<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"><id>tag:blogger.com,1999:blog-375697951860081841</id><updated>2008-07-03T20:17:25.901+08:00</updated><title type="text">When pet projects bite back!</title><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default?start-index=26&amp;max-results=25" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>39</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/WhenPetProjectsBiteBack" type="application/atom+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">1347700</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://www.feedburner.com</feedburner:feedburnerHostname><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-23838469487108622</id><published>2008-06-30T22:00:00.002+08:00</published><updated>2008-06-30T22:21:14.025+08:00</updated><title type="text">Decisions in Your Tables</title><content type="html">So how do I start explaining about decision tables? Well, its an interesting subject..&lt;br /&gt;&lt;br /&gt;&lt;b id="wz5m"&gt;Introduction&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;What does &lt;a href="http://en.wikipedia.org/wiki/Decision_table" id="t5hg" target="_blank" title="wikipedia say"&gt;wikipedia say&lt;/a&gt; ?&lt;br /&gt;"&lt;b id="nbiy"&gt;Decision tables&lt;/b&gt; are a precise yet compact way to model complicated logic. Decision tables, like &lt;a href="http://en.wikipedia.org/wiki/Conditional_%28programming%29" id="nbiy0" title="Conditional (programming)"&gt;if-then-else&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Switch_statement" id="nbiy1" title="Switch statement"&gt;switch-case&lt;/a&gt; statements, associate conditions with actions to perform. But, unlike the control structures found in traditional programming languages, decision tables can associate many independent conditions with several actions in an elegant way."&lt;br /&gt;&lt;br /&gt;Decision tables, for me, seem to make sense in that they model logic into an understandable table-diagram that can be checked easily.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b id="wz5m3"&gt;Advantages to Using Decision Tables&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The first advantage of decision tables, in my opinion, would be to replace if-then-else statements with something more manageable.&lt;br /&gt;&lt;br /&gt;&lt;table id="g5ps0" align="center" border="1" cellpadding="5" cellspacing="0"&gt;   &lt;caption id="g5ps1"&gt;&lt;b id="g5ps2"&gt;Printer troubleshooter&lt;/b&gt;&lt;/caption&gt; &lt;tbody id="g5ps3"&gt;   &lt;tr id="g5ps4"&gt;     &lt;td id="g5ps5"&gt;  &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps7"&gt;  &lt;br /&gt;&lt;/td&gt;     &lt;th colspan="8" id="g5ps9"&gt;       Rules     &lt;/th&gt;   &lt;/tr&gt;   &lt;tr id="g5ps10"&gt;     &lt;td id="g5ps11" rowspan="3"&gt;       Conditions     &lt;/td&gt;     &lt;td id="g5ps12"&gt;       Printer does not print     &lt;/td&gt;     &lt;td id="g5ps13"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps14"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps15"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps16"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps17"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps18"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps19"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps20"&gt;       N     &lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps21"&gt;     &lt;td id="g5ps22"&gt;       A red light is flashing     &lt;/td&gt;     &lt;td id="g5ps23"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps24"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps25"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps26"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps27"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps28"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps29"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps30"&gt;       N     &lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps31"&gt;     &lt;td id="g5ps32"&gt;       Printer is unrecognized     &lt;/td&gt;     &lt;td id="g5ps33"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps34"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps35"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps36"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps37"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps38"&gt;       N     &lt;/td&gt;     &lt;td id="g5ps39"&gt;       Y     &lt;/td&gt;     &lt;td id="g5ps40"&gt;       N     &lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps41"&gt;     &lt;td id="g5ps42" rowspan="5"&gt;       Actions     &lt;/td&gt;     &lt;td id="g5ps43"&gt;       Check the power cable     &lt;/td&gt;     &lt;td id="g5ps44"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps45"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps46"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps47"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps48"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps49"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps50"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps51"&gt;        &lt;br /&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps52"&gt;     &lt;td id="g5ps53"&gt;       Check the printer-computer cable     &lt;/td&gt;     &lt;td id="g5ps54"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps55"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps56"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps57"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps58"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps59"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps60"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps61"&gt;        &lt;br /&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps62"&gt;     &lt;td id="g5ps63"&gt;       Ensure printer software is installed     &lt;/td&gt;     &lt;td id="g5ps64"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps65"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps66"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps67"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps68"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps69"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps70"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps71"&gt;        &lt;br /&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps72"&gt;     &lt;td id="g5ps73"&gt;       Check/replace ink     &lt;/td&gt;     &lt;td id="g5ps74"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps75"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps76"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps77"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps78"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps79"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps80"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps81"&gt;        &lt;br /&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr id="g5ps82"&gt;     &lt;td id="g5ps83"&gt;       Check for paper jam     &lt;/td&gt;     &lt;td id="g5ps84"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps85"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps86"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps87"&gt;       X     &lt;/td&gt;     &lt;td id="g5ps88"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps89"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps90"&gt;        &lt;br /&gt;&lt;/td&gt;     &lt;td id="g5ps91"&gt;        &lt;br /&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;/tbody&gt; &lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Here you can see an example of a decision table for a printer trouble shooter. Above are the conditions (the if-then-else) and below are the actions to take according to the conditions.&lt;br /&gt;While this table contains quite a few options, you can see that its easy to handle them because it is more visual then if-then-else.&lt;br /&gt;&lt;br /&gt;Now, since this is a blog about MySQL, lets pretend for a minute that it would be a good idea to put your decision table in your database. Why? well, because databases hold tables. Think of it as a regular configuration file (like an XML file or an INI file), but you just decided to keep it in your database.&lt;br /&gt;So what have you done exactly? Well, you have seperated your if-then-else statements (your logic) and then convert it into a diagram (which happens to fit nicely into a database table). So basically, you have abstracted your logic from your application code into a &lt;u id="wvjr"&gt;manageable&lt;/u&gt; place. This is very important.&lt;br /&gt;By abstracting your logic, you can now manage changes in your application.What this means is, in the future, if you need to make a change to your logic, you can simply change your decision table and the logic will be updated in your application. In theory, you can also let non-technical people make changes in these tables also.&lt;br /&gt;So the second advantage for using decision tables is for managing change and the third advantage, again in my opinion is debugging. Just the fact that its more visual and you can see the paths for conditions and actions, helps to debug errors.&lt;br /&gt;&lt;br /&gt;&lt;b id="bfyi"&gt;Example&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;An insurance company wants to setup a system that will determine if their already existing customers deserve a discont on their next policy and/or get money back.&lt;br /&gt;&lt;br /&gt;For a customer to get a discount on his next policy he/she needs to: &lt;ul id="uqro"&gt;&lt;li id="uqro1"&gt;     Already have an existing policy with the insurance company   &lt;/li&gt;&lt;li id="uqro2"&gt;     Want to renew his/her policy with the insurance company   &lt;/li&gt;&lt;li id="uqro3"&gt;     Must have paid most of the monthly insurance payements on time. Atleast 75% of the time.   &lt;/li&gt;&lt;li id="uqro4"&gt; Customers who have big insurance policies (that are over 10,000 USD) can also get discount, but only if those customers paid on time not less then 50% of the time. &lt;/li&gt;&lt;li id="uqro5"&gt; Customers who are very good can also get some money back. Meaning, they must have paid more then 90% of the payments on time and not made any claims on their insurance policy. &lt;/li&gt;&lt;li id="uqro6"&gt; If a customer has made claims on their policy over 50% of the value of the policy, they will not get a discount or money back. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Here is the code for these conditions:&lt;br /&gt;&lt;blockquote&gt;&lt;blockquote id="fzb8"&gt;    -If HasPolicy(Person) = True {&lt;br /&gt;    --If Wants2Renew(Person) = True {&lt;br /&gt;     ---If Not(PaidOnTime(Person) = ‘Less50%’) and Not(UsedPolicy(Person) = ‘More50%’) {&lt;br /&gt;      ----If (PaidOnTime(Person) = ‘More75%’ and BigPolicy = True) {&lt;br /&gt;       -----Discount = True;&lt;br /&gt;       -----MoneyBack = False;&lt;br /&gt;      ----} Elseif PaidOnTime(Person) = ‘More90%’ {&lt;br /&gt;         -----Discount = True;&lt;br /&gt;   -----If UsedPolice(Person) = ‘NotUsed’ {&lt;br /&gt;    ------MoneyBack = True;&lt;br /&gt;   -----} Else {&lt;br /&gt;       ------MoneyBack = False;&lt;br /&gt;   -----}&lt;br /&gt;      ----} Else {&lt;br /&gt;         -----Discount = False;&lt;br /&gt;         -----MoneyBack = False;&lt;br /&gt;      ----}&lt;br /&gt;     ---} Else {&lt;br /&gt;        ----Discount = False;&lt;br /&gt;        ----MoneyBack = False;&lt;br /&gt;---}&lt;br /&gt;    --} Else {&lt;br /&gt;       ---Discount = False;&lt;br /&gt;       ---MoneyBack = False;&lt;br /&gt;   --}&lt;br /&gt;-} Else {&lt;br /&gt;      --Discount = False;&lt;br /&gt;      --MoneyBack = False;&lt;br /&gt;   -}&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p class="western" id="w8_n157" style="margin-bottom: 0in;"&gt; &lt;/p&gt; &lt;div id="x-lb" style="padding: 1em 0pt; text-align: left;"&gt;   &lt;div id="urds" style="padding: 1em 0pt; text-align: center;"&gt;     &lt;div id="rf:2" style="text-align: left;"&gt;       Here is a condition table for the same example. Minus (-) equals all the options.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;     &lt;img id="bfkw" src="http://docs.google.com/File?id=dhpd74xh_777dftpwqhr_b" style="width: 587px; height: 172px;" /&gt;   &lt;/div&gt;&lt;br /&gt;&lt;b id="qo0j"&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As you can see decision tables are much much better then writing code, because its half the size...&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;HEY! wait a minute! that code is waaay too long, I can do much better than you!&lt;br /&gt;&lt;/div&gt; &lt;p class="western" id="w8_n157" style="margin-bottom: 0in;"&gt;   Ok Ok, lets refactor the code:&lt;br /&gt;&lt;/p&gt; &lt;blockquote id="rt_3"&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;-If HasPolicy(Person) and Wants2Renew(Person) and ((PaidOnTime(Person) = ‘More75%’ and BigPolicy(Person)) or (PaidOnTime(Person) = ‘More90%’)) and Not(UsedPolicy(Person) = ‘More50%) {&lt;br /&gt;    --Discount = True;&lt;br /&gt;     --If PaidOnTime(Person) = ‘More90%’ and UsedPolicy(Person) = ‘NotUsed’{&lt;br /&gt;     ---MoneyBack = True;&lt;br /&gt;     --} Else {&lt;br /&gt;     ---MoneyBack = False;&lt;br /&gt;     --}&lt;br /&gt;   -}&lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt; &lt;p class="western" id="w8_n168" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; So here the code if a lot smaller. I do admit that it did take me some time to check the code (and I might have mistakes) and I didn't get the chance to make tests for it. Normally, after writing code, you would test it many many times over to see that it does what its supposed to do.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="western" id="w8_n40" style="margin-bottom: 0in;"&gt;   &lt;b id="alz-"&gt;Conclusion&lt;/b&gt; &lt;/p&gt; &lt;p class="western" id="w8_n40" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" id="w8_n40" style="margin-bottom: 0in;"&gt; Decision tables can help you make things clearer when it comes to implementing logic in your application. It also helps debug and manage changes.&lt;br /&gt;&lt;/p&gt; &lt;p class="western" id="w8_n40" style="margin-bottom: 0in;"&gt;   For the example above, &lt;/p&gt; &lt;blockquote id="mgbz"&gt;   &lt;p class="western" id="w8_n40" style="margin-bottom: 0in;"&gt;The insurance company decided that giving money back will now also be given to people who already have an insurance policy, but may or may not want to renew their policy with the insurance company.&lt;/p&gt;&lt;/blockquote&gt;&lt;p class="western" id="w8_n40" style="margin-bottom: 0in;"&gt;Please change the program for this new requirement.&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/06/decisions-in-your-tables.html" title="Decisions in Your Tables" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=23838469487108622" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/23838469487108622/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/23838469487108622" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/23838469487108622" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-7110839893807739719</id><published>2008-06-07T01:27:00.002+08:00</published><updated>2008-06-07T01:32:15.674+08:00</updated><title type="text">I got Married</title><content type="html">Well, I haven't blogged for a while, but I have a good excuse.&lt;br /&gt;I got married!&lt;br /&gt;&lt;br /&gt;We flew out to get married in a nice Mediterranean country.&lt;br /&gt;It was quite romantic and we are very happy.&lt;br /&gt;I married the most beautiful and amazing girl in the world.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(P.S. If you intended to get married in another country, plan ahead 3-4 months to get the right documents)</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/06/i-got-married.html" title="I got Married" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=7110839893807739719" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/7110839893807739719/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/7110839893807739719" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/7110839893807739719" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-2973119532165177661</id><published>2008-05-16T13:55:00.005+08:00</published><updated>2008-05-16T18:41:25.159+08:00</updated><title type="text">Useful ways of using Views</title><content type="html">Here are a few ways I found Views to be useful for me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Data Cleansing&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;If I have a column that needs to be cleaned or tested in some way. For example:&lt;br /&gt;&lt;blockquote&gt;Select mycolumn, if(mycolumn is null, TRUE, FALSE) as mycolumnisnull from mytable&lt;/blockquote&gt;This example is not that amazing, but it lets you place conditions for the data. Then instead of re-writing these conditions in your application layer, you can re-use the View from the database.&lt;br /&gt;Another example:&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;Select email, regex ['some amazing email verification/cleaning regex line'] as cleaned_emails from emails&lt;/blockquote&gt;Here again, we have some condition that placed in the database. We can now call the emails table and tell it to give us only the cleaned emails according to the defined conditions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Decision Making&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can place  some business logic in your Views. I &lt;a href="http://mysqlbarbeque.blogspot.com/2008/02/using-business-rules-in-mysql-overview.html"&gt;wrote about it&lt;/a&gt; in my blog before.&lt;br /&gt;This time I will just use an example:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Select business_loan, if (business_loan &gt; 30000, 'Allow Discount', 'No Discount') as discount from loans&lt;/blockquote&gt;So here, you have an embedded rule that says if the loan is over 30,000, then give a discount. Otherwise, no discount.&lt;br /&gt;There are advantages and disadvantages to using business rules in your database. One advantage is the visual way of verifying that your code is working. You can see next to your data if your code works or if you need to make changes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Displaying parts of many-column tables&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;Very simply, if you know you only need a few columns from a table with many columns, you can just specify it in a View. It just keeps things tidier.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Create View contact_details&lt;br /&gt;Select col11 as firstname, col52 as lastname, col37 phonenumber from 100columntable&lt;/blockquote&gt;I have used this (a lot) for finding tables to extract data from when I did some ETL-data warehouse work. This is an example:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; Create View src_thetableiwaslookingfor&lt;br /&gt;Select * from database1.tablethatiwant&lt;/blockquote&gt;This helped me a lot in the past and also helped when I worked with other developers on the same project. We just all used the same interfaces (Views).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fashioning your data&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can use some basic text manipulation on your data to help you display it better.&lt;br /&gt;For example:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Select concat(title,'. ',firstname, ' ', lastname) as fullname from contact_details.&lt;/blockquote&gt;Here, we just added the title, first name and last name into one string (example, Mr. John Smith).&lt;br /&gt;If you really want to go crazy, you can do this&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Create View HTML_export&lt;br /&gt;Select concat('[tr] [td] ',firstname,'[/td] [td] ',lastname,'[/td] [/tr] ') as list from contact_details&lt;/blockquote&gt;&lt;br /&gt;So, if in the future you want to get a quick list of all the contact names in HTML format, you can just use the View.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;Views are very useful :)&lt;br /&gt;Especially if you dislike long-winded languages when you can do it in 1 line of SQL.&lt;br /&gt;&lt;br /&gt;I plan on writing a more detailed article soon about this topic</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/05/useful-ways-of-using-views.html" title="Useful ways of using Views" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=2973119532165177661" title="2 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/2973119532165177661/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/2973119532165177661" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/2973119532165177661" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-92770552892925887</id><published>2008-05-13T15:30:00.003+08:00</published><updated>2008-05-13T15:56:13.495+08:00</updated><title type="text">A Blog about Blogging</title><content type="html">Many of you may have already noticed that blogs are becoming more and more influential as mediums of information. I personally read tens of blogs everyday to keep up with events.&lt;br /&gt;&lt;br /&gt;But who decided that blogs are good sources of information?&lt;br /&gt;After all, a blog is someone's opinion. It might be a better educated opinion with more facts then other opinions, but its still someone's opinion.&lt;br /&gt;&lt;span style="font-size:100%;"&gt; A blog can be defined as:&lt;br /&gt;&lt;/span&gt; &lt;div id="wyp70" style="margin-left: 40px;"&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div id="wyp70" style="margin-left: 40px;"&gt;&lt;span style="font-size:100%;"&gt;Short for "Web log," a specialized site that allows an individual or group of individuals to share a running log of events and personal insights with online audiences.&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;/blockquote&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;span id="e4y80" style="font-weight: bold;"&gt;News&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; News is still someone's opinion. News companies try to be neutral and say that they report the news the way it is. But anyone probably knows that if they open the TV to a certain news channel, they will see the news in a different way then other channels.&lt;br /&gt;Whether it be if the news channel is usually more right, more left, if the news anchors are tougher then news anchors on other channels, etc..&lt;br /&gt;So there is no "actual" news, there is just how people see the world. Truth is relative to how you see the facts.&lt;br /&gt;In a sense, you can validate blogs as being reasonably "true" by saying that news channels are not 100% "true" anyway.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="e4y83" style="font-weight: bold;"&gt;&lt;br /&gt;Chatting with Friends&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; But not everyone is a news journalist. So what motivates people to write blogs?&lt;br /&gt;Obviously, some people have different reasons. But since its my blog, I will express my opinion to what I think it is.&lt;br /&gt;I think that people like to chat with their friends or other people and share ideas.&lt;br /&gt;It is always nice to talk to a friend who thinks a bit like you and discuss issues that you find interesting.&lt;br /&gt;This is where I think the motivation lies. People want to share ideas and instead of maybe sharing it with one person, they can share it with many people. People who think this issue is interesting. People who either want to learn the issue or people who already know enough about the issue to comment on it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="v.6.0" style="font-weight: bold;"&gt;Facts and Opinions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Opinions are ways of trying to understand the world around us. If there were facts to help us understand the world around us, then we don't need someone's opinion about the issue, we already know or can find out.&lt;br /&gt;If however, there is no formal way of finding out something, we use informal ways. We have opinions about things because we don't have any other formal way of understanding them. We like to give our opinions and discuss them to either affirm them with other people (if they agree) or change them, if we are found out to be wrong.&lt;br /&gt;In this spirit of co-operation, we discover new things when we discuss our opinions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My Opinion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think blogs are now at a very mature stage. Already, blogs are compared to news channels and news channels reference blogs some of the time.&lt;br /&gt;A good point to take from this, I think, is that even with news, its important to remember that its still someone's opinion. Its always good to take many different opinions from different sources as well as share your own opinions before coming to your own conclusions.&lt;br /&gt;And its even more important to note, that a lot of our current conclusions are based on opinions. With that, we should be open to new opinions that could possibly change our previous conclusions.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/05/blog-about-blogging.html" title="A Blog about Blogging" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=92770552892925887" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/92770552892925887/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/92770552892925887" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/92770552892925887" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-2047120759577810169</id><published>2008-04-28T12:25:00.003+08:00</published><updated>2008-04-28T13:16:05.708+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title type="text">Thank You Ubuntu</title><content type="html">Well, I decided to take the plunge and migrate from Windows XP to Ubuntu. Now, technically, I have been wanting to do this for a while, but I was dependant on my windows to dial up to my internet (some problem with my ISP here). I tried to do it in Ubuntu a few months ago, but it was too complicated for me. However, it left me with a yearning to try again.&lt;br /&gt;So, I waited for the new Ubuntu to come out and in parallel fixed my router.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why?&lt;/span&gt;&lt;br /&gt;The reason I thought it was a good idea to move to linux was mainly for self-improvement.&lt;br /&gt;&lt;br /&gt;I recently read some blogs (couldn't find them now) that mentioned that with all the new web apps, there will be less and less emphasis on the OS. In 2011 (gartner says), this will hit a crucial point.&lt;br /&gt;I was thinking, maybe more people will adopt free linux when everything important will be in "the cloud" and all you really need is a browser anyway.  So I know how to use linux, I will be ready for that time and help people start adopting it.&lt;br /&gt;&lt;br /&gt;Another 2 important reasons for me were:&lt;br /&gt;1) That all servers use linux for their web apps and to be more comfortable in that environment will be a big plus.&lt;br /&gt;2) To get myself more into the developing frame of mind. This maybe just me, but I noticed that the hardcore developers use linux or macs. Not that I am knocking windows, but I don't really feel that developers in windows are as serious as linux or mac for some reason (did you see some online presentation videos for a  new technology. ALL the presenters use macs. Especially ones from Google. Am I missing something?)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Installing&lt;/span&gt;&lt;br /&gt;I did some research, downloaded some pdfs and was all ready to go. I decided to make my current windows into a VMware image in case I needed something from it.&lt;br /&gt;I downloaded Ubuntu and tried to figure it out. Bascially, you get 700mbs which you download of the net and anything else you want, you need to download. Fedora, comes with 4gbs and you need to download very little.&lt;br /&gt;&lt;br /&gt;I had real problems understanding how to install things.. until I discovered DAM DAM DAM... repositories. Ok, so forgive me if you now are saying to yourself "Duh, I already knew that". I am new to it.&lt;br /&gt;&lt;br /&gt;What I learned was, if you type "sudo apt-get install the-whole-universe-for-free-woohoo-I-love-it",  you just magically get it. No need to download, configure (well, most dont) and all that trouble. You just use apt-get. You can even do it visually with the package manager.&lt;br /&gt;&lt;br /&gt;This for me, is a huge advantage over other platforms. Its just so welcoming and encourages you to improve.&lt;br /&gt;For example, I could download MySQL off the website, then install it manually. Or, I could just write 1 line and it will download, install itself, do some configuring and automatically upgrade (I think) when a new version goes into the repository. How cool is that?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Tipping Point &lt;/span&gt;&lt;br /&gt;So I was trying to install VMware and this was really difficult. Opening the bin/rpm file was difficult enough, but after succeeding in that, it gave me some error.&lt;br /&gt;I almost gave up, until I found this &lt;a href="http://czarism.com/easy-peasy-vmwareplayer-vmplayer-ubuntu-hardy-804"&gt;article&lt;/a&gt;.  It shows you that you can do everything with command lines and after playing around with linux, I am becoming more and more comfortable with them.&lt;br /&gt;However, the important part is in the comments.&lt;br /&gt;Someone posted the exact error I had.. and the guy told him how to solve the problem... by changing the ACTUAL CODE. Oh my god! change the actual code of the supplier? Unheard of in windows. If you have an error, you file a report somewhere and wait a week if your lucky.&lt;br /&gt;&lt;br /&gt;Just the fact that I was allowed to look into someone else's code (and VMware is a big company) and learn and/or change it (I wont go into licenses), really makes me feel part of something.&lt;br /&gt;I now really understand that open source doesn't mean free as in free beer, but free as in freedom of expression (sorry, that was a bit deep).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;In conclusion.&lt;/span&gt;&lt;br /&gt;I really like Ubuntu. Its not perfect and it needs some work, but this time, I feel that I can be part of it and help it improve.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.howtoforge.com/the-perfect-desktop-ubuntu-8.04-lts-hardy-heron"&gt;A useful article to install Ubuntu&lt;/a&gt; &lt;--</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/thank-you-ubuntu.html" title="Thank You Ubuntu" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=2047120759577810169" title="2 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/2047120759577810169/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/2047120759577810169" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/2047120759577810169" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-6463435667473864988</id><published>2008-04-21T12:24:00.006+08:00</published><updated>2008-04-28T13:21:09.679+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="China" /><title type="text">China and Blogs equals Page Cannot Be Found</title><content type="html">Hello Fellow Bloggers&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I am hereby officially requesting if you could kindly enable your blog to have subscription via email.&lt;br /&gt;The reason I am asking this is because I like to get information from your wonderful blogs, but unfortunately, &lt;a href="http://www.feedburner.com/"&gt;feedburner&lt;/a&gt; is blocked in china (and wordpress sometimes, blogspost sometimes, typepad...etc). This makes it difficult and highly annoying to get feeds from blogs.&lt;br /&gt;The usual method to overcome this difficulty is to find proxies and sometimes install browser plugins to connect to the various proxies (&lt;a href="http://www.vidalia-project.net/"&gt;vidalia&lt;/a&gt; is also good), but this slows down the process of trying to view the blog.&lt;br /&gt;Now, I realize that most of you have no problem at all viewing blogs and are used to reading them every day with no delay in speed or increase of blood pressure.&lt;br /&gt;But, please, consider the poor unfortunate people that live in "restrictive" parts of the world and would still like to be informed as to whats going on in outside their country of residence.&lt;br /&gt;&lt;br /&gt;To help you enable email subscription for your blog, please use either &lt;a href="http://www.feedburner.com/"&gt;feedburner&lt;/a&gt; or &lt;a href="http://www.feedblitz.com/"&gt;feedblitz&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thank you for your understanding.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/china-and-blogs-equals-page-cannot-be.html" title="China and Blogs equals Page Cannot Be Found" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=6463435667473864988" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/6463435667473864988/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/6463435667473864988" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/6463435667473864988" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-5544157748935566632</id><published>2008-04-17T18:02:00.005+08:00</published><updated>2008-04-28T13:16:53.454+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="data warehousing" /><title type="text">My First Data Warehouse</title><content type="html">I finally finished my first data warehouse! and it only took me 3 days!&lt;br /&gt;&lt;br /&gt;Well, to be fair, the data warehouse design was already planned and it wasn't really that big anyway, but I am still happy about it.&lt;br /&gt;&lt;br /&gt;I was asked on Monday to do a data warehouse for my company's head quarters in Germany. I work in Beijing, so its like.... very slow to connect to there. They gave me the database design, some SQL statements to generate a few dimensions and "rough" business rules for the data.&lt;br /&gt;&lt;br /&gt;Now, I haven't done anything like this before, but I really wanted to try. So I did it my way.&lt;br /&gt;&lt;br /&gt;My way is to use a lot of Views with &lt;a href="http://mysqlbarbeque.blogspot.com/2008/04/sql-is-in-fact-programming-language.html"&gt;long SQL statements&lt;/a&gt; instead of cursors or stored procedures.  I like it this way, because I feel like I can see the data and catch problems instead of programming blindly to find out later that there is a big problem. So basically, for me, its more comfortable.&lt;br /&gt;&lt;br /&gt;I took the SQL statements that loaded the dimensions, cleaned them a bit and put them in Views. The Views in Oracle (we used Oracle for this data warehouse. I told them MySQL is better, but they preferred Oracle)... the views are very restrictive. I thought it was good, because it made me confident that they will work properly. However, Views don't allow for UNION, so for that I used Materialized Views.&lt;br /&gt;&lt;br /&gt;Materialized Views was something I learned while doing this data warehouse and I think they are very cool, to be honest. It allowed me to create a sort of temp table that more or less needed no code from me to maintain. I can refresh it with 1 line in a stored procedure. I could also schedule it to refresh, but I didn't learn how to do that. I also used Materialized Views to replace views that needed too much calculations and I got REALLY annoyed waiting for it finish from the server in Germany.&lt;br /&gt;&lt;br /&gt;I checked my SQL statements with looking at the Views and using a lot of count()'s on many different columns. Count()'s don't count NULL values and NULL is something that cant go into a fact table of a data warehouse.  I also brushed up on my AND/OR conditions when I had missing data from one table and I had to find it in maybe another table. After that, I took this value and  INNER JOIN'd it with another table. So an example that worked well for me is:&lt;br /&gt;&lt;blockquote&gt;left join src_dim_team_all dt on ((u2dt.TEAM = dt.TEAM)) or&lt;br /&gt;((u2dt.TEAM is null) and (dt.TEAM = f.TEAM))&lt;/blockquote&gt;In this example, the join takes the data from the first table.. or.. if the first table's value is null, it takes it from the second table. A simple OR didn't work for me and I only found that out when I tested it with some count()'s.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the end, 99.99% of the work was done using Views and 1 stored procedure to do the: &lt;blockquote&gt;insert into mydimension from select * from myview&lt;/blockquote&gt;which made it very very easy for me to abstract the complexity into several Views.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At the end, the final extracting, transforming and loading was ridiculous. EVERY tiny thing took 5-10 mins to run on the German server and after that I had to test it if its correct.&lt;br /&gt;&lt;br /&gt;However, I enjoyed this experience and it would be one more thing I can add on my CV.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thanks for reading my blog.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/my-first-data-warehouse.html" title="My First Data Warehouse" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=5544157748935566632" title="2 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/5544157748935566632/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/5544157748935566632" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/5544157748935566632" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-191848380351548832</id><published>2008-04-14T12:56:00.004+08:00</published><updated>2008-04-28T13:49:54.106+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><title type="text">My Adventures With Erlang Have Come to an End</title><content type="html">After&lt;a href="http://mysqlbarbeque.blogspot.com/2008/04/sql-is-in-fact-programming-language.html"&gt; trying very hard&lt;/a&gt; to install the &lt;a href="http://yaws.hyber.org/"&gt;Yaws webserver&lt;/a&gt; for Erlang on windows, asking 2 friends of mine to try to install it and pleading with the original creator to make an installer, I have given up.&lt;br /&gt;&lt;br /&gt;So my very short lived relationship with Erlang has come to an end also. I am just too busy to sit down and learn how to install a program that seems too complicated to me before I even start programming in it.&lt;br /&gt;&lt;br /&gt;I hope one day, Yaws will use an installer like &lt;a href="http://www.bitrock.com/"&gt;Bitrock&lt;/a&gt;. Until then, I will spend my time either improving the languages I know or learning new ones that seem cool and not that complicated to get into.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/my-adventures-with-erlang-have-come-to.html" title="My Adventures With Erlang Have Come to an End" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=191848380351548832" title="2 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/191848380351548832/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/191848380351548832" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/191848380351548832" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-726390380735124630</id><published>2008-04-04T11:19:00.003+08:00</published><updated>2008-04-28T13:17:49.170+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="bitrock" /><title type="text">BitRock Lamp Installer</title><content type="html">I was complaining in an &lt;a href="http://mysqlbarbeque.blogspot.com/2008/04/sql-is-in-fact-programming-language.html"&gt;earlier post&lt;/a&gt; that I have problems with linux style installation.&lt;br /&gt;I found a company that can help me solve that!&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://www.bitrock.com/"&gt;BitRock&lt;/a&gt; makes open source software easier to use by providing a complete automated solution for Open Source Application Deployment.&lt;/blockquote&gt;&lt;br /&gt;Its quite cool and they have a &lt;a href="http://bitrock.com/download_webstacks_download.html"&gt;LAMP stack installer&lt;/a&gt; here.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now I am suggesting that someone at Erlang does it too. They have a &lt;a href="http://21ccw.blogspot.com/2008/02/lyme-vs-lamp-i.html"&gt;Lyme&lt;/a&gt; stack which is Linux + &lt;a href="http://yaws.hyber.org/"&gt;Yaws &lt;/a&gt;+ &lt;a href="http://www.erlang.org/doc/apps/mnesia/index.html"&gt;Mnesia &lt;/a&gt;+ Erlang. (a comparison can be found &lt;a href="http://21ccw.blogspot.com/2008/02/lyme-vs-lamp-iv.html"&gt;here&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Anyway, I am still stuck on installing yaws :(&lt;br /&gt;I asked a friend to help until someone makes a cool installer.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/bitrock-lamp-installer.html" title="BitRock Lamp Installer" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=726390380735124630" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/726390380735124630/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/726390380735124630" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/726390380735124630" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-7415969123290414735</id><published>2008-04-03T20:57:00.003+08:00</published><updated>2008-04-03T21:00:56.712+08:00</updated><title type="text">The Code Monkey Song</title><content type="html">For those who haven't heard this song, please go to &lt;a href="http://www.jonathancoulton.com/2006/04/14/thing-a-week-29-code-monkey/"&gt;here&lt;/a&gt;.&lt;br /&gt;Its a very cool song about programmers, done in an "open-source" way, in that the guy who wrote the song isn't signed by any record label and hes trying to promote himself through his site.&lt;br /&gt;&lt;br /&gt;Truly an anthem song.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/code-monkey-song.html" title="The Code Monkey Song" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=7415969123290414735" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/7415969123290414735/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/7415969123290414735" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/7415969123290414735" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-3033087006686683007</id><published>2008-04-03T16:39:00.007+08:00</published><updated>2008-04-18T13:23:16.333+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming Lanugage" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title type="text">SQL is in Fact a Programming Language</title><content type="html">While I was updating my blog recently, I read the top part of it which said "&lt;span&gt;My adventures in database developing". I realized that I have really neglected database developing with all my research into other programming languages.&lt;br /&gt;So I was trying to play around with SQL statements to brush up on my skills.&lt;br /&gt;&lt;br /&gt;Luckily (or unluckily), someone at my work, a java developer, needed to do a data export and thought that I can do it in 1 SQL line. He said.... and I quote "You only need 1 SQL line. Whats the problem?".&lt;br /&gt;Whenever I hear the "whats the problem" line, there usually is one.&lt;br /&gt;So, with him having great confidence in my SQL-ing ability or a complete misunderstanding of database developing, I was forced to do the data export.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;I realized early on that it would take a long time. Just to start off, I needed like 20+ columns, but each column was a row somewhere in 4 different tables.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/__8lgzcJRF8U/R_Sqs-zXguI/AAAAAAAADwk/qfR81X9_wLA/s1600-h/patonback.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 229px; height: 236px;" src="http://bp0.blogger.com/__8lgzcJRF8U/R_Sqs-zXguI/AAAAAAAADwk/qfR81X9_wLA/s400/patonback.gif" alt="" id="BLOGGER_PHOTO_ID_5184956760759698146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span&gt;To make a long story short, I did complete the task and to simply pat myself on the back, I will paste it here. &lt;/span&gt;&lt;span&gt;Just to show that, yes, you can program in SQL. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;br /&gt;(but next time, please give me rights on the server to do it with several views).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;The SQL statement is about 2-3 pages long, by the way and&lt;/span&gt; &lt;span&gt;you don't really need to read all of the statement&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;SELECT&lt;br /&gt;CONTACT.CON_ID as contact_id,&lt;br /&gt;contact.CON_EMAIL_LOWER as email,&lt;br /&gt;contact.CON_CREATION_DATE as creation_date,&lt;br /&gt;lastname.CONATTR_VALUE as givenname,&lt;br /&gt;firstname.CONATTR_VALUE as familyname,&lt;br /&gt;languages.CONATTR_VALUE as "LANGUAGE",&lt;br /&gt;gender2.SELVAL_VALUE as gender,&lt;br /&gt;mobile.CONATTR_VALUE as mobilephone,&lt;br /&gt;office.CONATTR_VALUE as officephone,&lt;br /&gt;home.CONATTR_VALUE as home,&lt;br /&gt;address.CONATTR_VALUE as address,&lt;br /&gt;zipcode.CONATTR_VALUE as zipcode,&lt;br /&gt;province2.SELVAL_VALUE as province,&lt;br /&gt;city2.SELVAL_VALUE as city,&lt;br /&gt;intendedpurchase2.SELVAL_VALUE as intendedpurchase,&lt;br /&gt;ownedcarbrand2.SELVAL_VALUE as ownedcarbrand,&lt;br /&gt;minimodel3.SELVAL_VALUE as  minimodel,&lt;br /&gt;dealer3.SELVAL_VALUE as dealer,&lt;br /&gt;subject3.SELVAL_VALUE as subject,&lt;br /&gt;SUBSCRIPTION.sub_id as subscription_id,&lt;br /&gt;brochure13.SELVAL_VALUE as brochure1,&lt;br /&gt;brochure23.SELVAL_VALUE as brochure2,&lt;br /&gt;brochure33.SELVAL_VALUE as brochure3,&lt;br /&gt;message2.CAMATTR_VALUE as message&lt;br /&gt;from CONTACT contact&lt;br /&gt;left join CONTACT_ATTRIBUTE lastname on lastname.CONATTR_CON_ID = CONTACT.CON_ID and lastname.CONATTR_ATTR_ID = 1010&lt;br /&gt;left join CONTACT_ATTRIBUTE firstname on firstname.CONATTR_CON_ID = CONTACT.CON_ID and firstname.CONATTR_ATTR_ID = 1020&lt;br /&gt;left join CONTACT_ATTRIBUTE languages on languages.CONATTR_CON_ID = CONTACT.CON_ID and  languages.CONATTR_ATTR_ID = 1000&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE gender2 INNER JOIN CONTACT_ATTRIBUTE gender on gender.CONATTR_SEL_ID=gender2.SELVAL_SEL_ID and gender2.SELVAL_LANGUAGE = 'zh' )&lt;br /&gt;   on gender.CONATTR_CON_ID = CONTACT.CON_ID and gender.CONATTR_ATTR_ID = 1030&lt;br /&gt;left join CONTACT_ATTRIBUTE mobile on mobile.CONATTR_CON_ID = CONTACT.CON_ID and  mobile.CONATTR_ATTR_ID = 1100&lt;br /&gt;left join CONTACT_ATTRIBUTE office on office.CONATTR_CON_ID = CONTACT.CON_ID and  office.CONATTR_ATTR_ID = 1110&lt;br /&gt;left join CONTACT_ATTRIBUTE home on home.CONATTR_CON_ID = CONTACT.CON_ID and  home.CONATTR_ATTR_ID = 1120&lt;br /&gt;left join CONTACT_ATTRIBUTE address on address.CONATTR_CON_ID = CONTACT.CON_ID and address.CONATTR_ATTR_ID = 1200&lt;br /&gt;left join CONTACT_ATTRIBUTE zipcode on zipcode.CONATTR_CON_ID = CONTACT.CON_ID and zipcode.CONATTR_ATTR_ID = 1210&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE province2 INNER JOIN CONTACT_ATTRIBUTE province on province.CONATTR_SEL_ID=province2.SELVAL_SEL_ID and province2.SELVAL_LANGUAGE = 'zh' )&lt;br /&gt;   on province.CONATTR_CON_ID = CONTACT.CON_ID and province.CONATTR_ATTR_ID = 510&lt;br /&gt;left join (SELECTION_VALUE city2 INNER JOIN CONTACT_ATTRIBUTE city on city.CONATTR_SEL_ID=city2.SELVAL_SEL_ID and city2.SELVAL_LANGUAGE = 'zh' )&lt;br /&gt;   on city.CONATTR_CON_ID = CONTACT.CON_ID and city.CONATTR_ATTR_ID = 520&lt;br /&gt;left join (SELECTION_VALUE intendedpurchase2 INNER JOIN CONTACT_ATTRIBUTE intendedpurchase on intendedpurchase.CONATTR_SEL_ID=intendedpurchase2.SELVAL_SEL_ID and intendedpurchase2.SELVAL_LANGUAGE = 'zh' )&lt;br /&gt;   on intendedpurchase.CONATTR_CON_ID = CONTACT.CON_ID and intendedpurchase.CONATTR_ATTR_ID = 1300&lt;br /&gt;left join (SELECTION_VALUE ownedcarbrand2 INNER JOIN CONTACT_ATTRIBUTE ownedcarbrand on ownedcarbrand.CONATTR_SEL_ID=ownedcarbrand2.SELVAL_SEL_ID and ownedcarbrand2.SELVAL_LANGUAGE = 'zh' )&lt;br /&gt;   on ownedcarbrand.CONATTR_CON_ID = CONTACT.CON_ID and ownedcarbrand.CONATTR_ATTR_ID = 1400&lt;br /&gt;&lt;br /&gt; left join SUBSCRIPTION  on CONTACT.CON_ID=SUBSCRIPTION.SUB_CON_ID&lt;br /&gt; left join&lt;br /&gt;  (SELECTION_VALUE minimodel3 INNER JOIN&lt;br /&gt;      (CAMPAIGN_ATTRIBUTE minimodel2 INNER JOIN SUBSCRIPTION minimodel on minimodel2.CAMATTR_SUB_ID=minimodel.SUB_ID)&lt;br /&gt;       on minimodel2.CAMATTR_ATTR_ID=52001)&lt;br /&gt;   on minimodel2.CAMATTR_SEL_ID = minimodel3.SELVAL_SEL_ID and minimodel3.SELVAL_LANGUAGE = 'zh' and minimodel.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE dealer3 INNER JOIN&lt;br /&gt;      (CAMPAIGN_ATTRIBUTE dealer2 INNER JOIN SUBSCRIPTION dealer on dealer2.CAMATTR_SUB_ID=dealer.SUB_ID)&lt;br /&gt;       on dealer2.CAMATTR_ATTR_ID=52002)&lt;br /&gt;   on dealer2.CAMATTR_SEL_ID = dealer3.SELVAL_SEL_ID and dealer3.SELVAL_LANGUAGE = 'zh' and dealer.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE subject3 INNER JOIN&lt;br /&gt;      (CAMPAIGN_ATTRIBUTE subject2 INNER JOIN SUBSCRIPTION subject on subject2.CAMATTR_SUB_ID=subject.SUB_ID)&lt;br /&gt;       on subject2.CAMATTR_ATTR_ID=50001)&lt;br /&gt;   on subject2.CAMATTR_SEL_ID = subject3.SELVAL_SEL_ID and subject3.SELVAL_LANGUAGE = 'zh' and subject.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE brochure13 INNER JOIN&lt;br /&gt;      (CAMPAIGN_ATTRIBUTE brochure12 INNER JOIN SUBSCRIPTION brochure1 on brochure12.CAMATTR_SUB_ID=brochure1.SUB_ID)&lt;br /&gt;       on brochure12.CAMATTR_ATTR_ID=51001 and brochure12.CAMATTR_SEL_ID=5100101)&lt;br /&gt;   on brochure12.CAMATTR_SEL_ID = brochure13.SELVAL_SEL_ID and brochure13.SELVAL_LANGUAGE = 'zh' and brochure1.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE brochure23 INNER JOIN&lt;br /&gt;      (CAMPAIGN_ATTRIBUTE brochure22 INNER JOIN SUBSCRIPTION brochure2 on brochure22.CAMATTR_SUB_ID=brochure2.SUB_ID)&lt;br /&gt;       on brochure22.CAMATTR_ATTR_ID=51001 and brochure22.CAMATTR_SEL_ID=5100102)&lt;br /&gt;   on brochure22.CAMATTR_SEL_ID = brochure23.SELVAL_SEL_ID and brochure23.SELVAL_LANGUAGE = 'zh' and brochure2.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;br /&gt;left join&lt;br /&gt;  (SELECTION_VALUE brochure33 INNER JOIN&lt;br /&gt;      (CAMPAIGN_ATTRIBUTE brochure32 INNER JOIN SUBSCRIPTION brochure3 on brochure32.CAMATTR_SUB_ID=brochure3.SUB_ID)&lt;br /&gt;       on brochure32.CAMATTR_ATTR_ID=51001 and brochure32.CAMATTR_SEL_ID=5100103)&lt;br /&gt;   on brochure32.CAMATTR_SEL_ID = brochure33.SELVAL_SEL_ID and brochure33.SELVAL_LANGUAGE = 'zh' and brochure3.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;br /&gt;&lt;br /&gt;left join&lt;br /&gt;  (CAMPAIGN_ATTRIBUTE message2 INNER JOIN SUBSCRIPTION message on message2.CAMATTR_SUB_ID=message.SUB_ID and message2.CAMATTR_ATTR_ID=50002)&lt;br /&gt;   on message.SUB_CON_ID=CONTACT.CON_ID&lt;br /&gt;           and SUBSCRIPTION.SUB_ID in (select distinct(CAMATTR_SUB_ID) from CAMPAIGN_ATTRIBUTE group by CAMATTR_SUB_ID)&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I apologize in advance if I get anyone's feed-reader stuck.&lt;br /&gt;&lt;br /&gt;Thank you for reading my blog.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/sql-is-in-fact-programming-language.html" title="SQL is in Fact a Programming Language" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=3033087006686683007" title="6 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/3033087006686683007/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/3033087006686683007" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/3033087006686683007" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-8936265342332920355</id><published>2008-04-02T20:32:00.003+08:00</published><updated>2008-04-28T13:18:56.353+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="dates" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title type="text">Searching Problems with Dates and Midnight</title><content type="html">Today, we run into an issue when a client of ours. They wanted to see some of the data on our website and when doing a search, they didnt see all the days they asked for in the search&lt;br /&gt;&lt;br /&gt;Why didn't they see all the data? Because they did a search by date and some of the dates were stored via the website in the form of '2008-01-01 00:00:00' and some were stored via the database in the form of '2008-01-01 12:35:49'.&lt;br /&gt;Now, for some magical reason, if you hide the time in the date in your searches, like so:&lt;br /&gt;&lt;blockquote&gt;where signupdate between '2008-01-01' and '2008-01-02'&lt;br /&gt;or&lt;br /&gt;where signupdate between date('2008-01-01 00:00:00') and date('2008-01-02 00:00:00')&lt;br /&gt;&lt;/blockquote&gt;then you might not see all the data between the days 01 to 02.&lt;br /&gt;Depending on which way your date was stored, you might only see the dates &lt;span style="font-style: italic;"&gt;between&lt;/span&gt; those 2 dates and not equal to those dates as well.&lt;br /&gt;&lt;br /&gt;So for example, if you had:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;2008-01-01 00:00:00&lt;br /&gt;2008-01-01 00:00:00&lt;br /&gt;2008-01-02 00:00:00&lt;br /&gt;2008-01-02 00:00:00&lt;br /&gt;2008-01-03 00:00:00&lt;br /&gt;2008-01-03 00:00:00&lt;/blockquote&gt;&lt;br /&gt;and you ran the search above, then you would see:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;2008-01-01 00:00:00&lt;br /&gt;2008-01-01 00:00:00&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;(I once worked for another company that booked hotel rooms online. For them when you booked the room, the nights were counted. So if you would do a search, on the website, all the date allocations would be set to midnight - 00:00:00.)&lt;br /&gt;&lt;br /&gt;In our situation we had a mix of dates which caused use problems with 1 table and was ok with another.&lt;br /&gt;&lt;br /&gt;We decided to solve the problem like this&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;where signupdate between '2008-01-01 00:00:00' and ' 2008-01-02 23:59:59'&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;That is, from what I understand, the time a day starts (00:00:00) and the time a day ends (23:59:59). So we figured we covered all the issues with this statement and we are happy with it.&lt;br /&gt;I hope it helps you to if you also run into these kind of problems.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/04/searching-problems-with-dates-and.html" title="Searching Problems with Dates and Midnight" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=8936265342332920355" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/8936265342332920355/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/8936265342332920355" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/8936265342332920355" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-2060300272171857963</id><published>2008-03-26T13:54:00.004+08:00</published><updated>2008-04-28T13:55:09.849+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="idea" /><title type="text">Yet Another Idea for GSoC - New Datatypes</title><content type="html">Well, as most of you may know, Google Summer of Code is nearing and I have seen many&lt;br /&gt;MySQL blogs urging people to contribute ideas or mentor projects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My Idea&lt;/span&gt;&lt;br /&gt;So I'm going to suggest an idea and as the title already mentions, I think it would be a good idea to add some new Datatypes. Specifically, a new Email datatype.&lt;br /&gt;&lt;br /&gt;Now I already hear you saying "Email is a string, why would you need a datatype for it?", but hear me out.&lt;br /&gt;&lt;br /&gt;So basically, I personally, have been dealing a lot with trying to clean email addresses and customer data so that my company can help their biggest client use this data in their new CRM system.&lt;br /&gt;&lt;br /&gt;I thought it would have been a good idea to implement an email datatype inside MySQL that already has the &lt;a href="http://www.regular-expressions.info/email.html"&gt;standard regex for emails&lt;/a&gt; and has a defined varchar for the standard of emails.&lt;br /&gt;Later, I became aware that there can be different types of emails addresses.&lt;br /&gt;For example, you can have the standard latin a-z 0-9 with . and _ in them.&lt;br /&gt;You can have an email with the european a u o with the 2 dots above them.&lt;br /&gt;You can also have emails with characters like / in them for example 24/7@domain.com (someone that posted on &lt;a href="http://mysqlbarbeque.blogspot.com/2008/01/email-validators-my-contribution.html"&gt;my blog&lt;/a&gt; mentioned that one).&lt;br /&gt;&lt;br /&gt;To solve this, you could have an Email datatype like this:&lt;br /&gt;Email(latin)&lt;br /&gt;Email(german)&lt;br /&gt;Email(utf-8)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Benefits&lt;/span&gt;&lt;br /&gt;So what would be the benefits of using this kind of datatype?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Its out of the box solution for a common problem.  &lt;/li&gt;&lt;ul&gt;&lt;li&gt;MySQL is used by many many websites and most of them record email addresses,  so its relevant to them. &lt;/li&gt;&lt;li&gt;You wouldn't need to develop something yourself, go look at MySQL forge for     snippets, download and use any libarys, even bother to read about it. Its just there provided for you in the database.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;It helps improve data quality. After you have many tens of thousands of emails, it would have been nice to have more data quality. Thats not to say that you can develop some solution on the front end with Javascript for example, but it would still be nice to just have it in the database.&lt;/li&gt;&lt;li&gt; You wouldn't need to write &lt;a href="http://www.jpipes.com/index.php?/archives/211-Performance-Coding-Webinar-Today-Come-Join-Me-for-Some-Fun.html"&gt;webinars&lt;/a&gt; telling people how to optimize or shrink their email field in the database. Maybe even you can store it better on the harddisk for queries if you know it will be used for email address, who knows.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Downside&lt;/span&gt;&lt;br /&gt;The downside would be, that you will get a database error if you didn't implement any checks when the user is entering their email address on their website. For this you might want to make your email field a string and worry about it later. But I assure you, later will be for more annoying.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;More Options&lt;/span&gt;&lt;br /&gt;Now, you can also say "Well, you can also have a datatype for phone". Well, you can.&lt;br /&gt;Maybe you can have a phone datatype like this:&lt;br /&gt;phone(US)&lt;br /&gt;phone(world)&lt;br /&gt;&lt;br /&gt;Depends what you want, but I'd like to start with email addresses. Maybe you can throw in there ip(raw), ip(full)...&lt;br /&gt;I saw a webiner from &lt;a href="http://www.jpipes.com/index.php?/archives/211-Performance-Coding-Webinar-Today-Come-Join-Me-for-Some-Fun.html"&gt;Jay Pipes&lt;/a&gt; writing about that to improve query lookup speed specifically for ip addresses.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;I think it will be useful for many MySQL users to have an out-of-the-box solution for a very generic problem in the form of new datatypes that come with their own validation rules.&lt;br /&gt;&lt;br /&gt;Please write your thoughts in the comments. Your opinion is valued.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thank you for reading my blog.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/03/yet-another-idea-for-gsoc-new-datatypes.html" title="Yet Another Idea for GSoC - New Datatypes" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=2060300272171857963" title="3 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/2060300272171857963/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/2060300272171857963" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/2060300272171857963" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-1466363090009551572</id><published>2008-03-24T11:32:00.005+08:00</published><updated>2008-04-28T13:19:32.976+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="business" /><title type="text">A list of Open-Source Alternatives to Business Applications</title><content type="html">If you are part of a big company and would like to recommend to them a list of open-source and cheap commercial alternatives, I have compiled a list that I use for my company.&lt;br /&gt;&lt;br /&gt;These options might make your company more competitive in certain markets and might let you react faster to changes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Here is the list:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Database - DataWarehouse&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.infobright.com/"&gt;InfoBright&lt;/a&gt; - Commercial DataWarehouse Engine (highly recommended) that runs inside MySQL. &lt;a href="http://www.dbms2.com/2007/10/22/infobright-brighthouse-mysql/"&gt;review about it&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.enterprisedb.com/"&gt;EnterpriseDB &lt;/a&gt;- Commercial Enterprise Scale Database that runs inside PostgreSQL&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.vertica.com/product/relational-database-management-system-overview"&gt;Vertica &lt;/a&gt;- A very high-scale, commercial, analytical and column-based Database. (Was made by the man who invented relational databases in 1970s)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;BI Suite&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.pentaho.com/"&gt;Pentaho&lt;/a&gt; - Commercial Open-Source BI suite. Has ETL tools and Reporting (like informatica and cognos)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;CRM&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.sugarcrm.com/crm/"&gt;SugarCRM&lt;/a&gt; - Open Source CRM and on-demand CRM&lt;br /&gt;&lt;br /&gt;&lt;a href="http://xrms.sourceforge.net/pagebuilder.php?s1=18"&gt;XRMS&lt;/a&gt; - Web-based Open Source CRM&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.opencrx.org/"&gt;OpenCRX&lt;/a&gt; - Enterprise Open Source CRM&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;ESB&lt;/span&gt;&lt;br /&gt;&lt;a href="http://mule.mulesource.org/display/MULE/Home"&gt;Mule&lt;/a&gt; - Commercial Open Source Enterprise Service Bus. Connects between many different webservices. (highly recommended)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;ERP&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.openbravo.com/"&gt;OpenBravo&lt;/a&gt; - Web-based Open Source ERP&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;ERP + CRM&lt;/span&gt;&lt;br /&gt;&lt;a href="http://ofbiz.apache.org/"&gt;OFBiz&lt;/a&gt; - Apache "Open-For-Business" Open Source ERP and CRM&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.compiere.com/"&gt;Compiere&lt;/a&gt; - Open Source ERP and CRM&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I hope it helps.&lt;br /&gt;&lt;br /&gt;Thank you for reading my blog.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/03/list-of-open-source-alternatives-to.html" title="A list of Open-Source Alternatives to Business Applications" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=1466363090009551572" title="7 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/1466363090009551572/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/1466363090009551572" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/1466363090009551572" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-5756840026456793455</id><published>2008-03-21T12:05:00.006+08:00</published><updated>2008-04-28T13:45:49.427+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="talend" /><category scheme="http://www.blogger.com/atom/ns#" term="pentaho" /><category scheme="http://www.blogger.com/atom/ns#" term="informatica" /><title type="text">Pentaho Kettle vs Informatica PowerCenter</title><content type="html">After having a successful presentation to a  major car manufacturer in China, I have decided to upload my presentation so that other people may benefit and recommend it to their bosses.&lt;br /&gt;&lt;br /&gt;In the presentation I research Talend, Pentaho, Informatica and Inaport(CRM data importer).&lt;br /&gt;&lt;br /&gt;So the presentation is biased to Pentaho (and the Use Cases inside the presentation are from the Pentaho website).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://laurenstephens.net/uploads/4d7b656f9e.pdf"&gt;My Presentation &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Please enjoy and distribute.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/03/pentaho-kettle-vs-informatica.html" title="Pentaho Kettle vs Informatica PowerCenter" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=5756840026456793455" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/5756840026456793455/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/5756840026456793455" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/5756840026456793455" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-1741936251514559017</id><published>2008-03-17T22:55:00.006+08:00</published><updated>2008-04-28T13:20:32.177+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="open source" /><category scheme="http://www.blogger.com/atom/ns#" term="ETL" /><title type="text">Open Source ETL tools vs Commerical ETL tools</title><content type="html">Recently I have been asked by my company to make a case for open-source ETL-data integration tools as an alternative for the commercial data integration tool, &lt;a title="Informatica PowerCenter" href="http://www.informatica.com/" id="b:le"&gt;Informatica PowerCenter&lt;/a&gt;.&lt;br /&gt;So I did a lot of research and I'm going to try my best, considering I have never used the open-source tools nor the commercial one.&lt;br /&gt;&lt;br /&gt;I found plenty of information about comparisons between &lt;a title="Pentaho Kettle" href="http://www.pentaho.com/" id="c3b3"&gt;Pentaho Kettle&lt;/a&gt; and &lt;a title="Talend" href="http://www.talend.com/" id="plku"&gt;Talend&lt;/a&gt;, which were 2 of the open-source tools I was supposed to research.&lt;br /&gt;Now, without getting in a big arguement (or matt casters posting on my blog), I'd like to attempt to compare the two, very briefly.&lt;br /&gt;And again, this is ONLY from the research I did online and not based on my experience using the tools (since I dont really have any).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Pentaho Kettle vs Talend&lt;/h2&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Pentaho&lt;/span&gt;&lt;br /&gt;Pentaho is a commerical open-source BI suite that has a product called Kettle for data integration.&lt;br /&gt;It uses an innovative meta-driven approach and has a strong and very easy-to-use GUI.&lt;br /&gt;The company started around 2001 (2002 was when kettle was integrated into it).&lt;br /&gt;It has a strong community of 13,500 registered users.&lt;br /&gt;It has a stand-alone java engine that process the jobs and tasks for moving data between many different databases and files.&lt;br /&gt;It can schedule tasks (but you need a schedular for that - cron).&lt;br /&gt;It can run remote jobs on "slave servers" on other machines.&lt;br /&gt;It has data quality features: from its own GUI, writing more customised SQL queries, Javascript and regular expressions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Talend&lt;/span&gt;&lt;br /&gt;Talend is an open-source data integration tool (not a full BI suite).&lt;br /&gt;It uses a code-generating approach. Uses a GUI, but within Eclipse RC.&lt;br /&gt;It started around October 2006&lt;br /&gt;It has a much smaller community then Pentaho but has 2 finance companies supporting it.&lt;br /&gt;It generates java or perl code which you later run on your server.&lt;br /&gt;It can schedule tasks (also with using schedulars like cron).&lt;br /&gt;It has data quality features: from its own GUI, writing more customised SQL queries and Java.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Comparison &lt;/span&gt;- (from my understanding)&lt;br /&gt;Pentaho is faster (twice as fast maybe) then Talend.&lt;br /&gt;Pentaho's GUI is easier to use then Talend's GUI and takes less time to learn.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My impression&lt;/span&gt;&lt;br /&gt;Pentaho is easier to use because of its GUI.&lt;br /&gt;Talend is more a tool for people who are making already a Java program and want to save lots and lots of time with a tool that generates code for them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Assuming Pentaho made it to the next round....&lt;/span&gt;&lt;br /&gt;&lt;h2&gt;Pentaho Kettle vs Informatica&lt;/h2&gt; &lt;span style="font-weight: bold;"&gt;Informatica&lt;/span&gt;&lt;br /&gt;Informatica is a very good commercial data integration suite.&lt;br /&gt;It was founded in 1993&lt;br /&gt;It is the market share leader in data integration (Gartner Dataquest)&lt;br /&gt;It has 2600 customers.  Of those, there are fortune 100 companies, companies on the Dow Jones and government organization.&lt;br /&gt;The company's sole focus is data integration.&lt;br /&gt;It has quite a big package for enterprises to integrate their systems, cleanse their data and can connect to a vast number of current and legacy systems.&lt;br /&gt;Its very expensive, will require training some of your staff to use it and probably require hiring consultants as well. (I hear Informatica consultants are well paid).&lt;br /&gt;Its very fast and can scale for large systems. It has "&lt;a href="http://www.informatica.com/products/powercenter/options/pushdown/default.htm"&gt;Pushdown Optimization&lt;/a&gt;" which uses an ELT approach that uses the source database to do the transforming - like Oracle Warehouse Builder.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Comparison&lt;/span&gt;&lt;br /&gt;Pentaho's Javascipt is very powerful when writing transformation tasks.&lt;br /&gt;Informatica has many more enterprise features, for example, load balancing between database servers.&lt;br /&gt;Pentaho's GUI requires less training then Informatica.&lt;br /&gt;Penatho doesn't require huge upfront costs as Informatica does. (that part you saw coming, I'm sure)&lt;br /&gt;(edited)Informatica is faster then Pentaho. Infromatica has Pushdown Optimization, but with some tweaking to Pentaho and some knowledge of the source database, you can improve the speed of Pentaho. (also see line below)&lt;br /&gt;(new)You can place Pentaho Kettle on many different servers (as many as you like, its free) and use it as a cluster.&lt;br /&gt;Informatica has much better monitoring tools then Pentaho.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My Impression&lt;/span&gt;&lt;br /&gt;Informatica is a really good enterprise ETL suite, but is very big and expensive.&lt;br /&gt;If the system is small enough, I would rather give Pentaho a try and there are many many use cases where big companies used Pentaho (an airport, a hospital..).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt; I think &lt;a title="matt casters" href="http://www.ibridge.be/" id="o0aj"&gt;matt casters&lt;/a&gt; said it best when he said:&lt;br /&gt;&lt;blockquote&gt;The flood of open source software is going to wash away the proprietary ones..&lt;/blockquote&gt;&lt;br /&gt;If you want to add (or correct) to the information I wrote here, then please consider doing so, as I am still trying to understand these products myself.&lt;br /&gt;Your opinion is valued.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thank you for reading my blog.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/03/open-source-etl-tools-vs-commerical-etl.html" title="Open Source ETL tools vs Commerical ETL tools" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=1741936251514559017" title="9 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/1741936251514559017/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/1741936251514559017" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/1741936251514559017" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-177728420644386314</id><published>2008-03-07T19:09:00.005+08:00</published><updated>2008-04-28T13:23:26.744+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MS SQL" /><category scheme="http://www.blogger.com/atom/ns#" term="business rules" /><title type="text">Computed/Virtual Columns</title><content type="html">&lt;p class="MsoNormal"&gt;Some days a go I discovered a wonderful thing called computer columns when I stumbling on MS SQL server. There is a free MS SQL server 2005 express that you can download off a Microsoft site. Yes, I know, &lt;span style="font-weight: bold;"&gt;FREE &lt;/span&gt;and from microsoft.&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;(P.S. for those who didn’t read, Bill Gates &lt;a href="http://www.news.com.au/business/money/story/0,25479,23328130-31037,00.html"&gt;is now the 3&lt;sup&gt;rd&lt;/sup&gt; richest man in the world&lt;/a&gt; after 13 years of being number one.)&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I also read a &lt;a href="http://www.devx.com/dbzone/Article/30786/1954"&gt;really good article&lt;/a&gt; that explains indexes on computed columns. The benefits of speeding up searches with them and adding business rules. &lt;span style=""&gt; &lt;/span&gt;Obviously, the business rules were particularly interesting to me. &lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Jay Pipes had a similar&lt;a href="http://www.jpipes.com/index.php?/archives/211-Performance-Coding-Webinar-Today-Come-Join-Me-for-Some-Fun.html"&gt; webinar&lt;/a&gt; about the benefits of speeding up searches, but he suggested you do that by creating a new column and placing in it there. His example was, you can speed up a search for “SELECT * FROM Contacts WHERE family_name LIKE ‘%stone’” by making a column that reverses the family name and then you search by “SELECT * FROM Contacts WHERE reverse_family_name LIKE ‘enots%’”. This will save the query to go through all the records to find the results.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;So I looked a bit more into it how to developing business rules in computed columns and I found out that I can’t use “If”s but I can use “Case”. I also found out that the values you are looking at must be in the same table and the same row. Otherwise its non-deterministic and cannot work.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I am pretty happy with these computed columns and I consider it to cover most of what I have been looking for. I am also aware that there is some work being done on this to be implemented into MySQL, since I saw some information about it on the &lt;a href="http://forge.mysql.com/"&gt;MySQL forge&lt;/a&gt;.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I would also like to add some business rules in the form of validations for data to keep data quality high. I was thinking something along the lines of creating new data types with some constraints and limits inside them, but that didn’t work out at all in MySQL.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;For example, creating an “email” data-type that will have some regular expressions check on it and default size.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I found something else in the &lt;st1:place st="on"&gt;&lt;st1:placetype st="on"&gt;land&lt;/st1:placetype&gt; of &lt;st1:placename st="on"&gt;XML&lt;/st1:placename&gt;&lt;/st1:place&gt; which is kind of what I was looking for, called&lt;a href="http://en.wikipedia.org/wiki/Schematron"&gt; schematron&lt;/a&gt;, but I need to look into it more.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;I’m going to learn some more about this when I have time. In the near future I know I have to learn about installing a CRM system that uses MS SQL and I want to see if I can use any computed columns to help with this system. So if I find anything interesting, I'll blog about it.&lt;br /&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Thank you for reading my blog &lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/03/computedvirtual-columns.html" title="Computed/Virtual Columns" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=177728420644386314" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/177728420644386314/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/177728420644386314" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/177728420644386314" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-8415621865762108641</id><published>2008-02-28T10:47:00.003+08:00</published><updated>2008-04-28T13:24:12.041+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Excel" /><title type="text">BI users can't wean themselves off Excel</title><content type="html">I read &lt;a href="http://searchdatamanagement.techtarget.com/news/article/0,289142,sid91_gci1288694,00.html?track=sy240&amp;amp;asrc=RSS_RSS-24_240#"&gt;this article&lt;/a&gt; recently  about how BI users just really love and are used to their Excel sheets for almost anything they do. My first reaction was "duh".  My second reaction was that even I used Excel recently to help me data cleanse some contact information.&lt;br /&gt;Its easy to use, the functions are clear, I can develop my own functions in VBA, I can use colors to see problems with values, etc...&lt;br /&gt;I mean I can bet you that "even" if you use MySQL and you want to play around with the data to see if you can find anything, you would use Excel.&lt;br /&gt;&lt;br /&gt;But as the article says, there are some drawbacks in terms of time spent fixing errors and if you use Excel sheets that connect to other Excel sheet and then you go and insert a column or something.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway, the article is worth the read and maybe if we could take some of the advantages of Excel and add it to MySQL, maybe we can get some of the marketshare of Excel to move over a bit to MySQL</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/02/bi-users-cant-wean-themselves-off-excel.html" title="BI users can't wean themselves off Excel" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=8415621865762108641" title="1 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/8415621865762108641/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/8415621865762108641" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/8415621865762108641" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-8274453955739202357</id><published>2008-02-27T11:29:00.004+08:00</published><updated>2008-04-28T13:53:06.240+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="business rules" /><title type="text">Execution – The Art of “Cut the Crap and Just Do It”</title><content type="html">&lt;p&gt;I recently reread the book called &lt;a href="http://www.leadershipnow.com/leadershop/1057-0.html"&gt;“Execution – The Art of Getting Things Done”&lt;/a&gt; and although its somewhat old, it has surprisingly good and practical advise about putting your focus more on getting things done and less on thinking about strategies.&lt;/p&gt;    &lt;p&gt;Or where I read from somewhere recently “The goal is to work, not think about working” which was in reference to keeping a planning meeting fixed to a certain number of hours.&lt;/p&gt;    &lt;p&gt;Of course, you do need strategy, but if you don’t actually make sure that what you planned get done, or alternately, notice that your strategy may not be working then it just won’t work.&lt;/p&gt;  &lt;p&gt;&lt;b style=""&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;b style=""&gt;Hey! Wait a minute! Don’t you do Theory all the Time&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;    &lt;p&gt;Yes, I am very guilty of it myself about just thinking of things and not doing them. I even wrote about it at the top of one of &lt;a href="http://mysqlbarbeque.blogspot.com/2007/12/my-database-is-monster-run-away-firstly.html"&gt;my posts&lt;/a&gt;. &lt;/p&gt;    &lt;p&gt;So recently, I was looking at all my talk about &lt;a href="http://mysqlbarbeque.blogspot.com/2008/02/using-business-rules-in-mysql-overview.html"&gt;business rules&lt;/a&gt; on my blog and I was thinking “if I take a regular database and I wanted to add some business logic/rules to it, how many rules would I need to add?”.&lt;/p&gt;  &lt;p&gt;I took a database that was connected to some web site forms that basically collect information about users for campaigns and news letters. I could really only found one rule to add and that’s because I knew how the data will be used later.&lt;/p&gt;    &lt;p&gt;Now I do agree that this is not really a web application that requires a lot of logic. This system is pretty much taking data from point A to point B.&lt;/p&gt;    &lt;p&gt;However, I was thinking about past projects and even when it was relatively complicated web application and even then, I could only think, at the top of my head, 3 main rules that might have been used in the database instead of across 10s of PHP files. Everything else in those PHP file was again, taking data from point A and fashioning it in a nice viewable way to point B, which is on your screen.&lt;/p&gt;&lt;b style=""&gt;&lt;br /&gt;My Question&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;    &lt;p&gt;So my question is, why is adding business rules to your database such a controversial issue?&lt;/p&gt;  &lt;p&gt;Maybe it’s something to do with adopted practices that tell you to not put any logic in the database. Maybe people are afraid to commit to one database and might change it in the future. So keeping the logic separate is more convenient.&lt;/p&gt;    &lt;p&gt;I myself have come to realize that a large part of the reasons I thought this was a good idea was when I was working on a MySQL/PHP system and wanted to save time coding PHP (or just couldn’t even found where the lines of code were located in the mess that was there) by making long and complicated SQL statements or by creating Views. This seemed easier to me and I found it more comfortable to control my work, monitor the data and (which was the best part for me) show me the speed in which the queries were generated - so that I can speed up the website.&lt;br /&gt;&lt;/p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;b style=""&gt;&lt;br /&gt;Conclusion &lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;    &lt;p&gt;So I think that if you really take a look at it, (and you are not making an &lt;a href="http://www.blogger.com/en.wikipedia.org/wiki/Expert_system"&gt;Expert System&lt;/a&gt; or &lt;a href="http://www.blogger.com/en.wikipedia.org/wiki/Decision_support_system"&gt;Decision Support System&lt;/a&gt;) you only really need a few (that’s just my crazy assumption) business rules which can relatively easily be implemented in the database. Why not just try it and see if it works for you.&lt;/p&gt;  &lt;p&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/02/execution-art-of-cut-crap-and-just-do.html" title="Execution – The Art of “Cut the Crap and Just Do It”" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=8274453955739202357" title="0 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/8274453955739202357/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/8274453955739202357" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/8274453955739202357" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-1751493885002926583</id><published>2008-02-20T14:21:00.002+08:00</published><updated>2008-04-28T13:53:32.646+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Views" /><category scheme="http://www.blogger.com/atom/ns#" term="business rules" /><title type="text">Using Business Rules in MySQL</title><content type="html">&lt;span style="font-weight: bold;font-size:180%;" &gt;Overview&lt;/span&gt;&lt;br /&gt;While everyone tries to improve speed and performance in MySQL, other databases have realized that adding features that cut down on development time and improving time-to-market is what some people are looking for. MySQL is well known for great performance and it might be time to discover other parts of it that will speed up your over-all development process.&lt;p&gt;&lt;/p&gt;  &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;This article tries to explain how you can save time and effort on the development process by moving some of that development to the database. It does this by recommending you apply business rules to the database. &lt;/span&gt; &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in; font-weight: bold;" lang="en-GB"&gt;Additional Notes:&lt;/p&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;This example was taken from an actual database. Some of the table designs from that database were not ideally optimized and normalized. Please refer to the theory of the example and not the exact technical detail.&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt; What is a Business Rule?&lt;/span&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;"Business rules represent policies, procedures and constraints regarding how an enterprise conducts its business." &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://www.google.com/url?sa=X&amp;amp;start=1&amp;amp;oi=define&amp;amp;ei=_BN7R-n3AoaM6gOo9eFY&amp;amp;sig2=gob_L_j7lj0B59fay97hAw&amp;amp;q=http://www.isr.uci.edu/%7Ealspaugh/glossary.html&amp;amp;usg=AFQjCNELN_qrcQh-AdXx9DP34OcDOdxQig"&gt;www.isr.uci.edu/~alspaugh/glossary.html&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;“Business rules describe the operations, definitions and constraints that apply to an organization in achieving its goals” &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://en.wikipedia.org/wiki/Business_rules"&gt;http://en.wikipedia.org/wiki/Business_rules&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;As you can see, business rules help you “achieve your goals”. So what are your goals?&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;Many people do not take a few minutes to ask some simple but penetrating questions.  &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;For example, your goal is to create an amazing online hotel reservation system.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;You will do this by registering hotels and hotel rooms on your system and then letting the customer book them through a web portal.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;What kind of information do I need to collect?&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;The hotel details&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;The hotel room  details&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;The customer  details&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;The allocation  details&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;Why do I need to collect information about allocation details?&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;To know which  rooms the customer allocated and on which dates.&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;To know which  rooms the hotel needs to reserve for the customer.&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;To know which  rooms have already been booked and to not book them to someone else.&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;What kind of information do I need to collect for the allocations?&lt;/span&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;The  date – which day has the room been booked&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;The  hotel info – which hotel was used so that you can pay them  later&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;The  room info&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;And  is the room available to be booked?&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" align="center" lang="en-GB"&gt; &lt;img src="http://docs.google.com/File?id=dhpd74xh_623gqbxt5cr" name="graphics1" align="bottom" border="0" height="288" width="417" /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;So how do you know if the room is available to be booked?&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;You might need other types of information that will tell you if the room is available. &lt;/span&gt; &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;For example:&lt;/span&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;Has  the room already been booked on the same days that you want it? Is  it &lt;b&gt;sold out&lt;/b&gt;? (sold out on your system or the hotel notified  you that its sold out)&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;Is  it currently available to be booked or is it being redecorated,  fumigated for cockroaches or under repair? – What’s the  &lt;b&gt;status&lt;/b&gt; of the room?&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;How  many &lt;b&gt;rooms&lt;/b&gt; are &lt;b&gt;available&lt;/b&gt; for this room type? I  mentioned the room type (like suite or with balcony) because we  don’t allocate specific rooms directly in the hotel; we just  get a certain number of rooms reserved from the hotel (at least  that’s what I understood from someone who does have an online  reservation system).  &lt;/span&gt;  &lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; &lt;p class="western" style="margin-left: 0.25in; margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;The requirements for a room to be available are a sort of business rule. Once you have the requirements, all that interests you is the result of the business rule (the result for the question, is it available?). Meaning, after you know what you need to determine if the room is available, you don’t really “care” about the extra bits of information. All you care about is the result that the room is available.&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;This is what you normally do in your head and if you explain it to the database, it can also do that for you. You can ask the database to give you all the available rooms between 2 dates and it will give you the results because it already knows what other requirements to look for to determine if a room is available. &lt;/span&gt; &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;  &lt;/p&gt;&lt;br /&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt; Decision Trees&lt;/span&gt;  &lt;p class="western" style="margin-bottom: 0in;"&gt;“A decision tree (or tree diagram) is a decision support tool that uses a graph or model of decisions and their possible consequences… A decision tree is used to identify the strategy most likely to reach a goal.” &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://en.wikipedia.org/wiki/Decision_tree"&gt;http://en.wikipedia.org/wiki/Decision_tree&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;In order for me to draw business rules, I like to use decision trees. They are simple and very helpful to see problems as well as explain them to other people. They are also a sort of visual method for brain storming problems (example &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://www.mindtools.com/dectree.html"&gt;http://www.mindtools.com/dectree.html&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;). There is also another reason to use decision trees and I will get to that later on.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" align="center"&gt;&lt;img src="http://docs.google.com/File?id=dhpd74xh_624f6rpbmdq" name="graphics2" align="bottom" border="0" height="523" width="390" /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;This is a decision tree for our business rule. The diagram shows all the conditions for when a room is available and when it is not.  &lt;/p&gt; &lt;h1 class="western" lang="en-GB"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/h1&gt; &lt;h1 class="western" lang="en-GB"&gt;Off to the Code&lt;/h1&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;Many people don’t know, but SQL is in fact a programming language. It is &lt;/span&gt;a “declarative query and data manipulation language… that has procedural constructs, control-of-flow statements, user-defined data types, and various other language extensions” (&lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://en.wikipedia.org/wiki/SQL"&gt;http://en.wikipedia.org/wiki/SQL&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;). We are interested in the “control-of-flow” part of SQL to help us place conditions so when a room is available.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;Here is our allocations table.&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;CREATE TABLE `allocations` (&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;`DayID` DATETIME NOT NULL,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;`HotelID` INTEGER UNSIGNED NOT NULL,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;`RoomID` INTEGER UNSIGNED NOT NULL,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;`SoldOut` BOOLEAN NOT NULL,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;`Status` BOOLEAN NOT NULL,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;`RoomsAvailable` TINYINT UNSIGNED NOT NULL,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;i&gt;PRIMARY KEY (`DayID`, `HotelID`, `RoomID`)&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;);&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;   &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" align="center" lang="en-GB"&gt; &lt;img src="http://docs.google.com/File?id=dhpd74xh_625gzt963dn" name="graphics3" align="bottom" border="0" height="106" width="445" /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;To enable the business rule I will use the following piece of code:&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;SELECT DayID, HotelID, RoomType, &lt;/i&gt; &lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;if((SoldOut=false)and(`Status`=true)and(RoomsAvailable&amp;gt;0),True,False) as Available FROM allocations&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" align="center" lang="en-GB"&gt; &lt;img src="http://docs.google.com/File?id=dhpd74xh_626cpk97kdt" name="graphics4" align="bottom" border="0" height="108" width="300" /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;We have simplified things a bit. We no longer need to look at the other 3 columns that we hid. The data in those columns is still being collected, but for the purpose of finding out which rooms are available, they can remain hidden.  &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;After creating a View with the above code, we can run a search like this:&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt;  &lt;i&gt;SELECT * FROM allocations_view WHERE Available = True&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt; And that’s really all we are concerned about.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;u&gt;What did we just do?&lt;/u&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;We placed a business rule in the database, next to the data. We took out the need for this to be programmed outside the database using another programming language (PHP, Java, Perl, ASP, etc… ).&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;u&gt;Is this a good idea?&lt;/u&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;I think it is for 2 reasons:&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;If  (and only if) developing this in the database saves you time and  simplifies things, then you’ve saved the time and money asking  a developer to do the same thing in the application layer.&lt;/span&gt;&lt;/p&gt;  &lt;/li&gt;&lt;li&gt;&lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;Instead  of the application layer retrieve all the bits of data to determine  what is the result of the business rule (meaning more data has to be  transferred from the database to the application layer), only the  data of the result is transferred to the application layer. This can  speed things up by reducing network traffic.&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;h1 class="western" lang="en-GB"&gt;Decision Tables&lt;/h1&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;“Decision tables are a precise yet compact way to model complicated logic. Decision tables, like if-then-else and switch-case statements, associate conditions with actions to perform. But, unlike the control structures found in traditional programming languages, decision tables can associate many independent conditions with several actions in an elegant way.” &lt;span style="color: rgb(0, 0, 255);"&gt;&lt;u&gt;&lt;a href="http://en.wikipedia.org/wiki/Decision_tables"&gt;http://en.wikipedia.org/wiki/Decision_tables&lt;/a&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;Once you have a decision tree, you can easily make a decision table. Since a decision table is a… table, you can place it in the database.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" align="center"&gt;&lt;img src="http://docs.google.com/File?id=dhpd74xh_627f5fnhmd2" name="graphics5" align="bottom" border="0" height="180" width="328" /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;This may seem more complicated then the previous approach, but bare with me.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;If you compare this decision table to the decision tree diagram from before, it covers all the possible outcomes (2 to the power of 3 equals 8 outcomes). In this case, there is only 1 outcome where the room will be available&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;You now need to join the original table and this decision table, using this code:&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;SELECT allocations.DayID, allocations.HotelID, allocations.RoomType,&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;allocations_decision.Available&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;FROM allocations Left Join allocations_decision on (allocations.SoldOut=allocations_decision.SoldOut)&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;and (allocations.`Status`=allocations_decision.`Status`)&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-left: 0.5in; margin-bottom: 0in;" lang="en-GB"&gt; &lt;i&gt;and (if((allocations.RoomsAvailable&amp;gt;0),True,False)=allocations_decision.AboveZeroRooms)&lt;/i&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" align="center" lang="en-GB"&gt; &lt;img src="http://docs.google.com/File?id=dhpd74xh_628hf9qmqg5" name="graphics6" align="bottom" border="0" height="103" width="259" /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;You have the same results as before, but the approach you used was somewhat more difficult to do.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;u&gt;What did we just do?&lt;/u&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;We used a decision table to display the possible outcomes of finding out if a room is available and then joined it to the original table.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;u&gt;Is this a good idea?&lt;/u&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;That is for you to decide. The main advantage is the ability to make changes in the future. You can actually configure the business rules of the system by making changes to the decision tables. Non-developers in particular, can make these changes.&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;If something happens during the life time of the system, for example changes in the market, then you can react to these changes by configuring your system’s business rules.&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;You can also use decision tables when using too many “if-then-else” statements that confuse you and you prefer to have a more simplified look at all the conditions.&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt; Conclusion&lt;/span&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;In this article I have tried to show that you can add business rules to the database. I try to show that using the SQL language helps and simplifies data management and data manipulation. I have also tried to show how to make your database to be configurable so that it can change its business rules when they need to be changed.&lt;/span&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;Above all, I tried to show that database developing is not so difficult and encourage people to put more emphasis on the database as part of the overall software development process.&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;"&gt;&lt;span lang="en-GB"&gt;Thank you for reading my article. &lt;/span&gt; &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;  &lt;/p&gt; &lt;p class="western" style="margin-bottom: 0in;" lang="en-GB"&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/02/using-business-rules-in-mysql-overview.html" title="Using Business Rules in MySQL" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=1751493885002926583" title="5 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/1751493885002926583/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/1751493885002926583" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/1751493885002926583" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-45525764249025165</id><published>2008-01-28T12:24:00.002+08:00</published><updated>2008-04-28T13:22:10.312+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Email" /><title type="text">Email Validators - My Contribution</title><content type="html">So after my&lt;a href="http://mysqlbarbeque.blogspot.com/2008/01/journals-of-self-confessed-data.html"&gt; recent battle&lt;/a&gt; with "dirty" email addresses, I decided to find some validating functions to help people and myself in the future. Most of them use &lt;a href="http://www.regular-expressions.info/javascriptexample.html"&gt;regular expressions&lt;/a&gt;.&lt;span style=";font-family:&amp;quot;;font-size:12;"  &gt;&lt;br /&gt;&lt;/span&gt;So here they are:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;MySQL stored function&lt;/span&gt;&lt;br /&gt;Taken from - http://forge.mysql.com/snippets/view.php?id=62&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;DELIMITER $$&lt;br /&gt;DROP FUNCTION IF EXISTS `test`.`is_valid_email` $$&lt;br /&gt;CREATE DEFINER=`root`@`localhost` FUNCTION `is_valid_email`(p_email varchar(64)) RETURNS tinyint(1)&lt;br /&gt;BEGIN&lt;br /&gt;CASE&lt;br /&gt;WHEN NOT (SELECT p_email REGEXP '^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$')&lt;br /&gt;THEN&lt;br /&gt;-- bad data&lt;br /&gt;RETURN FALSE;&lt;br /&gt;ELSE&lt;br /&gt;-- good email&lt;br /&gt;RETURN TRUE;&lt;br /&gt;END CASE;&lt;br /&gt;END $$&lt;br /&gt;DELIMITER ;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;In VBA&lt;/span&gt;&lt;/span&gt; (for excel, access and SQL server) – you need to enable “Microsoft VBScript Regular Expressions 5.5” in the preference&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Dim myRegExp As VBScript_RegExp_55.RegExp&lt;br /&gt;&lt;br /&gt;Function ValidEmail(ByVal email As String) As Boolean&lt;br /&gt;Set myRegExp = New RegExp&lt;br /&gt;myRegExp.IgnoreCase = True&lt;br /&gt;myRegExp.Global = True&lt;br /&gt;myRegExp.Pattern = "^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$"&lt;br /&gt;ValidEmail = myRegExp.Test(email)&lt;br /&gt;End Function&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;In JavaScript &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Taken from - http://neural.cs.nthu.edu.tw/jang/sandbox/javascript/examples/chkemail.asp&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;function CheckEmail(str) {&lt;br /&gt;&lt;br /&gt;   var testresults=true&lt;br /&gt;   var filter=/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/&lt;br /&gt;   if (filter.test(str)){&lt;br /&gt;       var tempstring = str.split("@")&lt;br /&gt;       tempstring = tempstring[1].split(".")&lt;br /&gt;   } else {&lt;br /&gt;       testresults=false&lt;br /&gt;   }&lt;br /&gt;   return (testresults)&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;In Flash ActionScript&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Taken from someone at my work. No regular expression.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;    private function checkEmail(value:String):Boolean{&lt;br /&gt;       var mail1= value.split("@")[0]&lt;br /&gt;       var mail2= value.split("@")[1]&lt;br /&gt;       var mail2_end = mail2.split(".")[mail2.split(".").length-1]&lt;br /&gt;       var lastCharASCII = value.charCodeAt(value.length-1)&lt;br /&gt;       if(value.split("@").length!=2) return false&lt;br /&gt;       if(mail1=="" ||  mail2== "" || mail2.split(".").length&lt;2)&gt;3) return false;&lt;br /&gt;       if((lastCharASCII&lt;65&gt;122)||(lastCharASCII&gt;90 &amp;amp;&amp;amp; lastCharASCII&lt;97))&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Hope it helps.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/01/email-validators-my-contribution.html" title="Email Validators - My Contribution" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=45525764249025165" title="5 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/45525764249025165/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/45525764249025165" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/45525764249025165" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-9196334235231815559</id><published>2008-01-23T14:55:00.001+08:00</published><updated>2008-04-28T13:53:51.028+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="data warehousing" /><title type="text">The Journals of a Self Confessed Data Warehousing Noob</title><content type="html">&lt;span style="font-weight: bold;"&gt;Data Warehousing Continued&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Part of the reason I was hired by my company was to help the company’s largest customer connect their data warehouse to the company’s website database. I have data basing experience but I have never been involved in such a large project (don’t tell my bosses). Luckily for me, I wont be doing everything, but for starters, I had to get some customer data, mainly email addresses and build a newsletter mailing list. Sounds simple enough..&lt;br /&gt;Unfortunately for me, I had no idea how difficult it is to take even simple data fields from 2-3 sources and merge it into one. Some of the systems were so old, that back when they recorded the email address, there were no validation rules to enforce the input from the users. I saw emails like this http://www.163.com@yingying837.cn (163.com is a Chinese email server). It seemed to me that the people who inputted this email address only recently purchased a computer.&lt;br /&gt;&lt;br /&gt;Anyway, after looking at the long list, running some filters and changing by hand some things, I figured I have 95% cleaned and the rest will be done with the email program to check if the email address still exists.&lt;br /&gt;&lt;br /&gt;I was amazed how complicated it is to &lt;a href="http://www.blogger.com/en.wikipedia.org/wiki/Data_cleansing"&gt;data cleanse&lt;/a&gt; old systems and afterwards make it comply with a data warehouse schema. Especially in the case of data that’s in more the one languages and even more so when it’s a language that uses characters like Chinese.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;From now on I plan to put a strong emphasis on&lt;a href="http://www.blogger.com/en.wikipedia.org/wiki/Data_quality"&gt; data quality&lt;/a&gt; from any data base I start working on.&lt;br /&gt;I think it would be good to use data quality methods in my &lt;a href="http://mysqlbarbeque.blogspot.com/2007/12/so-i-was-thinking-about-some-of-my.html"&gt;simplified business rules engine&lt;/a&gt; idea and this whole thing made me realize about possible directions my “new pet project” might go. I have already written a few things down about it on paper.&lt;br /&gt;&lt;br /&gt;Thank you for reading my blog.</content><link rel="alternate" type="text/html" href="http://mysqlbarbeque.blogspot.com/2008/01/journals-of-self-confessed-data.html" title="The Journals of a Self Confessed Data Warehousing Noob" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=375697951860081841&amp;postID=9196334235231815559" title="4 Comments" /><link rel="replies" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/9196334235231815559/comments/default" title="Post Comments" /><link rel="self" type="application/atom+xml" href="http://mysqlbarbeque.blogspot.com/feeds/posts/default/9196334235231815559" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/375697951860081841/posts/default/9196334235231815559" /><author><name>Jonathan</name><uri>http://www.blogger.com/profile/17336586681878234499</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-375697951860081841.post-2347069812922953475</id><published>2008-01-23T14:38:00.000+08:00</published><updated>2008-01-23T14:54:56.549+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MySQL" /><category scheme="http://www.blogger.com/atom/ns#" term="Oracle" /><title type="text">The OS DB vs Commercial DB War Continues - A View from the Sideline</title><content type="html">&lt;span style="font-weight: bold;"&gt;Yet Another Sun Bought MySQL Post&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So Sun bought MySQL…. dunno about you, but I was surprised. My first impression was “nooooooooooooooo, I liked it when it was small and my contributions made a difference”, but I realized that it has obvious big advantages.&lt;br /&gt;&lt;br /&gt;The main one, which has been mentioned over and over again, is the support of MySQL will grow to the level which I might see it in companies that opted not to get it and use commercial databases.&lt;br /&gt;&lt;br /&gt;When I was interviewed for my current job, I learnt that the company made a website for a large customer and that they were using MySQL along side open source frameworks for it. The customer would want in the future to integrate the data, the website gathers, to their CRM system. Because of that, they were thinking about moving to u