<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Making the Complex Simple &#187; Database</title>
	<atom:link href="http://simpleprogrammer.com/category/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://simpleprogrammer.com</link>
	<description>Software Development from John Sonmez&#039;s Perspective</description>
	<lastBuildDate>Tue, 07 Feb 2012 17:47:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='simpleprogrammer.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Making the Complex Simple &#187; Database</title>
		<link>http://simpleprogrammer.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://simpleprogrammer.com/osd.xml" title="Making the Complex Simple" />
	<atom:link rel='hub' href='http://simpleprogrammer.com/?pushpress=hub'/>
		<item>
		<title>Add APPLY to Your TSQL Tool Belt</title>
		<link>http://simpleprogrammer.com/2011/09/21/add-apply-to-your-tsql-tool-belt/</link>
		<comments>http://simpleprogrammer.com/2011/09/21/add-apply-to-your-tsql-tool-belt/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 23:56:59 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Language]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">https://complextosimple.wordpress.com/?p=1396</guid>
		<description><![CDATA[Every once in a while I stumble across some SQL keyword that I didn’t really know about, but is extremely useful. The other day I came across APPLY, or rather CROSS APPLY. After reading through documentation on how it works and articles about it, I had a bit of trouble understanding it because I couldn’t [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=1396&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Every once in a while I stumble across some SQL keyword that I didn’t really know about, but is extremely useful.</p>
<p>The other day I came across APPLY, or rather CROSS APPLY.</p>
<p>After reading through documentation on how it works and articles about it, I had a bit of trouble understanding it because I couldn’t really find a simple explanation.</p>
<p><a href="http://complextosimple.files.wordpress.com/2011/09/criss-cross_1256682.jpg"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="criss-cross_1256682" src="http://complextosimple.files.wordpress.com/2011/09/criss-cross_1256682_thumb.jpg?w=486&#038;h=678" alt="criss-cross_1256682" width="486" height="678" border="0" /></a></p>
<p>I am going to try to explain it as simply as possible so you can start using it right away.</p>
<h2>How CROSS APPLY works</h2>
<p>The basic idea behind CROSS APPLY is to allow you to join two sets of data together.</p>
<p>If you understand how INNER JOIN works, you already understand CROSS APPLY.</p>
<p>The only difference is CROSS APPLY also allows you to join in a set of data in which that set of data is created or dependent on each row in the first set.</p>
<p>So basically what that means is that for a normal join you would, for example, join two tables that shared a common key.</p>
<p>I could join my customer table to my orders table to see all the orders for a particular customer like so:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cd47e942-3bfe-43f5-9c38-4809215fcadd" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;"><pre class="brush: sql; pad-line-numbers: true;">
SELECT *
FROM
 orders o
 JOIN customers c
 	ON o.customerid = c.customerid
WHERE
 c.companyname = 'Around the Horn'
</pre></p>
</div>
<p>Notice how the join is operating on a key that exists independently in each table.</p>
<p>We could rewrite this to be exactly the same using the CROSS APPLY syntax instead like so:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:fb1fb442-1315-48d7-b276-cbba63836948" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;"><pre class="brush: sql;">
SELECT *
FROM
  orders o
  CROSS APPLY (
    SELECT *  FROM
	   customers c
    WHERE
	   o.customerid = c.customerid) AS c
WHERE
  c.companyname = 'Around the Horn'
</pre></p>
</div>
<p>We can prove these results sets are exactly the same by using EXCEPT to make sure there are no rows in one set that aren’t in the other and then flipping it, like so:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:28630bf4-dcf0-4411-8a68-7bf8ab42e464" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;"><pre class="brush: sql;">
SELECT *
FROM
    orders o
    CROSS APPLY (SELECT *
                 FROM
                     customers c
                 WHERE
                     o.customerid = c.customerid) AS c
WHERE
    c.companyname = 'Around the Horn'

EXCEPT
SELECT *
FROM
    orders o
    JOIN customers c
        ON o.customerid = c.customerid
WHERE
    c.companyname = 'Around the Horn'
</pre></p>
</div>
<p>Just run this exact query again swapping the SQL above the EXCEPT with the SQL below and make sure it has no results as well.  If both of those queries have no results, then you know the results from each query are the same since EXCEPT will show any results that are in the top query but not in the bottom one.</p>
<h2>So when is CROSS APPLY useful?</h2>
<p>Remember how I said it can do more than a simple join?  Joins are restricted to only joining two sets of data that could be queries independently of each other.</p>
<p>What if I said give me the three most recent orders for each customer?</p>
<p>Take a minute and think about how you would write that query.  Go ahead and try to do it.  I’ll wait.</p>
<p>There are a few ways to do it without using CROSS APPLY, but none of them are really very easy or perform very well.</p>
<p>Using CROSS APPLY it is simple though:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:16f748f4-45f4-497e-8c9b-d47d601d4635" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;"><pre class="brush: sql;">
SELECT *
FROM
    customers c
    CROSS APPLY (
                 SELECT TOP 3 o.orderdate
                            , o.shipcity
                 FROM
                     orders o
                 WHERE
                     o.customerid = c.customerId
order by o.orderdate desc
) as top3;
</pre></p>
</div>
<p>So CROSS APPLY is useful whenever you have some data that you would want to be able to join against, but are forced to do some kind of sub-query instead because the data you are trying to join is not going to map well against a single key.</p>
<p>The other instance in which CROSS APPLY will be useful is when you are  doing a sub-select that has more than one value you would like to use in your final query.</p>
<p>For example if you were sub-selecting from an Order Details table to match up order ids that had a Quantity greater than 5, that sub-select would need to return exactly one column in order for you to use it in your where clause.  If you wanted to use other columns from the sub-select, you would have to do another sub-select for each of these columns.</p>
<p>If you first try to rewrite the sub-select as a JOIN and find that you can’t, you may be able to write it as a CROSS APPLY.</p>
<h2>How to know when to use CROSS APPLY</h2>
<p>There isn’t a good solid rule you can use to identify when you should use a CROSS APPLY but having the knowledge of CROSS APPLY and how it works can help you when you are trying to tune queries and you are having a difficult time constructing one.  It is another option you can try.</p>
<p>Here are some general guidelines of times when you might want to use CROSS APPLY:</p>
<ul>
<li>A query where the result set you want to JOIN against is in some way related to the data in the first set.  (Example: one column in the first table tells you how many rows in the 2nd table to get)</li>
<li>A query where you are doing a sub-query, but need more than one value from the sub-query</li>
<li>Anywhere you are using a Common Table Expression (CTE) could possibly be rewritten as a CROSS APPLY</li>
<li>A query that has a large set of data it is joining against and then filtering out.  You can change it to a CROSS APPLY that does the filter in the CROSS APPLY statement.</li>
<li>Any time you are trying to join against a table function (this is actually what CROSS APPLY was created for.)</li>
</ul>
<p><strong>As always, you can subscribe to this </strong><a href="http://feeds.feedburner.com/MakingTheComplexSimple"><strong>RSS feed</strong></a><strong> to follow my posts on Making the Complex Simple.  Feel free to check out </strong><a href="http://elegantcode.com/"><strong>ElegantCode.com</strong></a><strong> where I post about the topic of writing elegant code about once a week.  Also, you can follow me on twitter </strong><a href="http://twitter.com/jsonmez"><strong>here</strong></a><strong>.</strong></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/1396/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/1396/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/1396/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/1396/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/1396/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/1396/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/1396/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/1396/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=1396&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2011/09/21/add-apply-to-your-tsql-tool-belt/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2011/09/criss-cross_1256682_thumb.jpg" medium="image">
			<media:title type="html">criss-cross_1256682</media:title>
		</media:content>
	</item>
		<item>
		<title>News Flash: SQL Server Paging Still Sucks!</title>
		<link>http://simpleprogrammer.com/2010/07/22/news-flash-sql-server-paging-still-sucks/</link>
		<comments>http://simpleprogrammer.com/2010/07/22/news-flash-sql-server-paging-still-sucks/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 14:12:13 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">https://complextosimple.wordpress.com/?p=1013</guid>
		<description><![CDATA[Last time I wrote some code to allow paging of stored procedure results in SQL Server it sucked. That was about 3-4 years ago. I just wrote some code to do it again, and well…  It still sucks. Perhaps I’m doing it wrong, but if you are looking for, “how to implement paging in sql [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=1013&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Last time I wrote some code to allow paging of stored procedure results in SQL Server it sucked.</p>
<p>That was about 3-4 years ago.</p>
<p>I just wrote some code to do it again, and well…  It still sucks.</p>
<p>Perhaps I’m doing it wrong, but if you are looking for, “how to implement paging in sql server”, or “how to page sql server stored procedure results”, or “paging sql server”, I’ll give you my best answer for it at this point.</p>
<p>(Google search term additions above for helping people find help)</p>
<p><a href="http://complextosimple.files.wordpress.com/2010/07/paging.jpg"><img style="display:inline;border-width:0;" title="paging" src="http://complextosimple.files.wordpress.com/2010/07/paging_thumb.jpg?w=443&#038;h=325" border="0" alt="paging" width="443" height="325" /></a></p>
<h2>How I roll with CTEs</h2>
<p>CTEs or Common Table Expressions, are a pretty nice feature of SQL Server.  They are a bit complex, but basically they let you create a query and treat it as a table to select from.  They also allow recursive calls to themselves, which let you do cool things like query hierarchies of data.</p>
<p><a href="http://www.4guysfromrolla.com/webtech/071906-1.shtml#postadlink">This link</a> offers a pretty good explanation of CTEs.</p>
<p>Anyway, CTEs come in handy combined with the ROW_NUMBER() function to add the ability to page data from an existing stored procedure.</p>
<p>The basic idea here is to modify the original query by wrapping it inside of a CTE that adds a RowNumber column.</p>
<p>Then we can select from that query the rows that are in the range we want.</p>
<h2>Vegetables are good for you</h2>
<p>Let’s look at an example:</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:c53ade08-f66e-4cfc-ac56-8d7fd09282ee" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;"><pre class="brush: sql; pad-line-numbers: true;">
SELECT name, goodnessfactor, color
FROM vegetables
WHERE color = 'purple' OR color = 'green'
</pre></p>
</div>
<p>Now let’s modify this query to be pageable given we have the first and last record we want.  (first record = page number * rows per page, last record = page number + 1 * rows per page)</p>
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e669a1d3-1171-4f62-8655-96d7f96ad6dd" class="wlWriterEditableSmartContent" style="display:inline;float:none;margin:0;padding:0;"><pre class="brush: sql;">
WITH pagedVegetables AS (
    SELECT name, goodnessfactor, color,
    ROW_NUMBER() OVER (ORDER BY name) AS rownumber
    FROM vegetables
    WHERE color = 'purple' OR color='green'
)
SELECT *
FROM pagedVegetables
WHERE rownumber &gt; @firstRecord AND
               rownumber &lt;= @lastRecord
</pre></p>
</div>
<p>Okay, so it is actually not that bad.</p>
<p>A couple of notes to help understand what happened here.</p>
<ul>
<li>ROW_NUMBER() requires an OVER clause which basically will determine how you calculate what the row number is.  In this case, we are going to sort by name.  So the first alphabetical name will be row number 1, and so on.</li>
<li>We’ve wrapped the query in a CTE, and added an additional column so that we have a row number in our new virtual table.  (Think of the CTE as creating a temporary view for us.)</li>
<li>We are selecting everything out of the original query that is in the range of rows we want.  (Depending on how you define your range you may use different equality operators.  If you range is inclusive, you would do &lt;= and &gt;= , and if it is exclusive it would be &lt; and &gt;.  In this case we are both.)</li>
</ul>
<h2>A word on total row count</h2>
<p>If you need the total number of rows, so that you can pass that back to the pager in your code, then you will probably have to select the results from the CTE into a temporary table and return two result sets from it.</p>
<p>I couldn’t really find a way to select the total rows and the data from a single CTE expression.  If you know a way, please let me know.</p>
<h6>As always, you can subscribe to this <a href="http://feeds.feedburner.com/MakingTheComplexSimple">RSS feed</a> to follow my posts on Making the Complex Simple.  Feel free to check out <a href="http://elegantcode.com/">ElegantCode.com</a> where I post about the topic of writing elegant code about once a week.  Also, you can follow me on twitter <a href="http://twitter.com/jsonmez">here</a>.</h6>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/1013/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/1013/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/1013/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=1013&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2010/07/22/news-flash-sql-server-paging-still-sucks/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2010/07/paging_thumb.jpg" medium="image">
			<media:title type="html">paging</media:title>
		</media:content>
	</item>
		<item>
		<title>Zero Configuration Development Environments</title>
		<link>http://simpleprogrammer.com/2010/05/28/zero-configuration-development-environments/</link>
		<comments>http://simpleprogrammer.com/2010/05/28/zero-configuration-development-environments/#comments</comments>
		<pubDate>Fri, 28 May 2010 15:29:32 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Process Improvement]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">https://complextosimple.wordpress.com/?p=883</guid>
		<description><![CDATA[I have bee working on getting set up this week to develop for my new, awesome employer, TrackAbout. In doing so, I have once again felt the pain of getting a development environment configured.  I forgot how painful it can be.  This is in no way a reflection of TrackAbout, the truth is most development [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=883&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have bee working on getting set up this week to develop for my new, awesome employer, TrackAbout.</p>
<p>In doing so, I have once again felt the pain of getting a development environment configured.  I forgot how painful it can be.  This is in no way a reflection of TrackAbout, the truth is most development environments are a pain to get setup.  Unless you&#8217;re actively trying to build a painless development environment, it is going to probably be the opposite.</p>
<p>I’ve seen a large number of development environments and I’ve built my share of them.  From all this, I have a pretty good idea of what I consider ideal, what we should strive for.</p>
<p><a href="http://complextosimple.files.wordpress.com/2010/05/lg_cocacola_zero_can.jpg"><img style="display:inline;border:0;" title="lg_cocacola_zero_can" src="http://complextosimple.files.wordpress.com/2010/05/lg_cocacola_zero_can_thumb.jpg?w=240&#038;h=453" border="0" alt="lg_cocacola_zero_can" width="240" height="453" /></a></p>
<h2>The basic outline</h2>
<ol>
<li>Install non-scriptable tools or start with a fresh image.  (Basically getting IDE and SQL Server installed locally)</li>
<li>Get branch from version control.</li>
<li>Build database</li>
<li>Build code</li>
<li>Local deploy</li>
</ol>
<p>The idea here is that I should be able to either get an image that has my base tools installed, or install them myself, then pull down one source control location and everything else that happens from there is the result of  build scripts or some other automated process.</p>
<p>I know, it is easier said than done.  Let’s break it down step by step and look at some of the possible solutions.</p>
<h2>Install tools</h2>
<p>If you are in an organization where everyone will have the same hardware, it is much easier to create an image of a developer machine with say Visual Studio and SQL Server installed.</p>
<p>Another possible solution is to create a dev VM that is maintained and updated regularly, so that it has all the required tools and you have a uniform structure.  I have tried this approach, and I find that the biggest problem is that many times you want to run native to get the performance improvements.  As hardware capabilities increase though, I am seeing this as a more viable route.</p>
<p>Finally, if you can’t get either of those situations, it is ideal to put all the tools that must be installed on a network share or some other easily accessible place.</p>
<p>Ideally, you want to keep the number of required tools down to an absolute minimum.  In most .NET environments this should be Visual Studio and SQL Server.  The other kinds of tools can be handled via dlls (usually).</p>
<h2>Get branch from version control</h2>
<p>Ideally, you should be able to point a person to one source control location, and that should get everything necessary for them to build and deploy the entire system locally.</p>
<p>If different applications your organization is developing have different branches, then you might need to check out one location per project, but even that can be automated to some degree with a “get latest” script or symbolic links.</p>
<h2>Build the database</h2>
<p>This one is kind of hard.  It requires quite a bit of forethought on how to get this working.  The idea here is that I should be able to build the entire database from a set of scripts.</p>
<p>The challenge is getting together a process which allows for the construction of the database from scratch and to populate tables that are required for the application, and be able to apply patches to existing database.  I won’t go into how to do that here.</p>
<h2>Build the code</h2>
<p>There is quite a bit lumped into here.  From a developer perspective I should just be able to run one build command that is the same build that will be run on the <a href="http://simpleprogrammer.com/2009/12/30/continuous-integration-best-practices/">continuous integration server</a> and everything that I need should get built for me.</p>
<p>From behind the scenes, this is a difficult step.</p>
<ul>
<li>You have to make sure everything works from relative paths or environment variables.</li>
<li>You have to have your scripts check to see if things are installed and install them if not (registry keys, etc).</li>
<li>You have to have all the libraries in a place that the build can find on the client machine.</li>
</ul>
<p>The key to success here is to eliminate as much as possible and locate in one place, as much as possible, all configuration differences.</p>
<h2>Local deploy</h2>
<p>It should be very easy to do a local deployment of the application.  For .NET developers this usually isn’t a challenge, but in the Java world it can take some thinking on how to do this properly.</p>
<p>At anytime someone should be able to deploy locally to their machine.  Ideally, anyone should be able to take a build from the build server and deploy it with a single command.</p>
<h2>It is all about the mindset</h2>
<p>Basically, you have to think about zero configuration development environment from the beginning if you really want to be successful at it.  It is much harder to add it on later.</p>
<p>You do have to weigh the effort involved carefully though.  Most developers only set up their configuration once or twice. If you are going to have a growing team where you are constantly adding new developers, you should probably put considerable effort into getting as close to zero configuration as possible.  On the other hand, if you have a small team and don’t have new developers very often, it might not be worth the extra effort.  You have to find the balance.</p>
<p>In all honesty, my experience at my new job has been pretty good in contrast to some of the development environment setups I have seen.  There is a huge amount of consistency in configuration locations, which is good.</p>
<p>I’m looking forward to figuring out how to make it easier for the next guy though, once I understand everything better myself.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/883/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/883/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/883/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/883/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/883/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/883/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/883/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/883/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=883&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2010/05/28/zero-configuration-development-environments/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2010/05/lg_cocacola_zero_can_thumb.jpg" medium="image">
			<media:title type="html">lg_cocacola_zero_can</media:title>
		</media:content>
	</item>
		<item>
		<title>Mr. Developer, Prod is Not For You</title>
		<link>http://simpleprogrammer.com/2010/05/03/mr-developer-prod-is-not-for-you/</link>
		<comments>http://simpleprogrammer.com/2010/05/03/mr-developer-prod-is-not-for-you/#comments</comments>
		<pubDate>Mon, 03 May 2010 15:18:21 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://simpleprogrammer.com/?p=803</guid>
		<description><![CDATA[In my Kanbanand guide, I have a rule for infrastructure that says, &#8220;Production data never goes to any other environment.&#8221; Someone recently asked what exactly this means. It means that the database data that is in production never goes into dev, integration, qual, or whatever other environments you may have set up at your workplace. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=803&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://simpleprogrammer.com/2010/04/28/the-kanbandand-guide/">Kanbanand guide</a>, I have a rule for infrastructure that says, &#8220;Production data never goes to any other environment.&#8221;</p>
<p>Someone recently asked what exactly this means.</p>
<p>It means that the database data that is in production never goes into dev, integration, qual, or whatever other environments you may have set up at your workplace.  I think more important than the &#8220;what&#8221; is the &#8220;why&#8221;, and while I&#8217;m at it, I&#8217;ll tell you why I won&#8217;t give you, as a developer, access to production data at all.</p>
<p><a href="http://complextosimple.files.wordpress.com/2010/05/puzzle_lock.jpg"><img class="size-full wp-image-804 alignnone" title="puzzle_lock" src="http://complextosimple.files.wordpress.com/2010/05/puzzle_lock.jpg?w=500&#038;h=424" alt="" width="500" height="424" /></a></p>
<h2>Why production data stay in production</h2>
<p>Let&#8217;s start with a simple reason: security.  Production data in most cases is going to contain at least some amount of sensitive information.  If your company leaks sensitive information about customers or clients, you can almost guarantee that you will have a lawsuit on your hands.</p>
<p>It is much better to keep production data as safe as possible.  The best way to do that is to limit access to it as much as possible.  If you move production data to different environments, you will be greatly increasing the amount of places that data lives and correspondingly the number of people who have access to it.</p>
<p>Aside from just the security concerns, is the problem of reliance on exact data to recreate a problem.  <strong>Debugging an issue which is seen in production should not require the actual production data. </strong>If it does, there is a problem with the tooling you have created to support your application.  You might consider <a href="http://simpleprogrammer.com/2009/12/03/dedicated-developer-tools-teams/">creating some development tools</a> that will allow you to simulate any production issue in a different environment without having to use real production data.</p>
<p>I know it is much easer to just use production data, but it is a bad habit that masks other problems with your tooling and support.  It also has a large cost to the infrastructure and support of an application if you require frequent data migration between environments.</p>
<h2>Why developers stay out of production</h2>
<p>The reasoning is very similar.  We could talk again about security.  We could talk again about the problems with relying on production data to debug a problem in your application.</p>
<p>This really comes down to a discipline and constraint issue.  By enforcing this constraint and practicing this discipline, you gain quite a few things out of necessity:</p>
<ul>
<li>Logging must be improved to understand what happened in production</li>
<li>You are forced to consider creating a user click tracking mechanism</li>
<li>Test data generation is forced to be considered</li>
<li>Testing becomes more complete, because your team is forced to recreate issues independently rather than using production data</li>
</ul>
<p>It might not be immediately apparent to you how these things are connected, but if you enforce this kind of a policy, you will quickly find that you will need better ways of understanding what the user did.</p>
<p>It may seem counter-productive to make a developer&#8217;s job harder by preventing them from accessing production, but in the long run, being forced to create tooling and better logging to understand how the user is using the system, and having more complete testing will save time.</p>
<h2>Some tips on making this reality</h2>
<p>Yes, I know, easier said than done.  Let me help you get it done with these tips:</p>
<ol>
<li>Build enough logging into the application to make it easy to understand what the system is doing and the flow through the system.</li>
<li>Build a detailed level of logging that can be turned on for different parts of a live running production system.</li>
<li>Build or use tools that take data from your web server logs and application logs and translate that into a digest of how the user clicked through the system.  (Doing this well will allow you to recreate most scenarios that may have happened in production.)</li>
<li>Create migration tools that allow you to migrate and cleanse a particular piece of data.  The goal here is not to take the whole database and dump it to another environment, but to take specific sets of data, cleanse them (get rid of all personally identifiable information), and put them somewhere else to examine and debug.</li>
<li>Have ways to generate volumes of clean test data to put into non-production environments.  This may look like a test script that runs though the application and clicks through many scenarios to generate test data, or a bunch of SQL scripts that populate test data tables.</li>
</ol>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/803/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=803&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2010/05/03/mr-developer-prod-is-not-for-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2010/05/puzzle_lock.jpg" medium="image">
			<media:title type="html">puzzle_lock</media:title>
		</media:content>
	</item>
		<item>
		<title>Naming Database Columns, When to Violate DRY</title>
		<link>http://simpleprogrammer.com/2010/03/24/naming-database-columns-when-to-violate-dry/</link>
		<comments>http://simpleprogrammer.com/2010/03/24/naming-database-columns-when-to-violate-dry/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 14:35:36 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Design]]></category>

		<guid isPermaLink="false">http://simpleprogrammer.com/?p=549</guid>
		<description><![CDATA[DRY = Don&#8217;t Repeat Yourself. For the most part this is a good principle to follow.  But, there is one particular instance where I feel repeating myself makes things more clear. It is very important for us to remember that principles are important, but ultimately they are very strong guidelines, not absolutes.  (It is hard [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=549&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>DRY = Don&#8217;t Repeat Yourself.</p>
<p>For the most part this is a good principle to follow.  But, there is one particular instance where I feel repeating myself makes things more clear.</p>
<p>It is very important for us to remember that principles are important, but ultimately they are very strong guidelines, not absolutes.  (It is hard to imagine that I just said that, since I am usually arguing on the merit of principles, but I digress.)</p>
<h2>Traditions</h2>
<p>In particular, when creating database tables, most people will create a table structure that looks like:</p>
<p><a href="http://complextosimple.files.wordpress.com/2010/03/databasewithid.jpg"><img class="alignnone size-full wp-image-550" title="databasewithid" src="http://complextosimple.files.wordpress.com/2010/03/databasewithid.jpg?w=500" alt=""   /></a></p>
<p>Looks perfectly normal and good.  But, I don&#8217;t like it.  Imagine you have to join these tables together to create a query.  (A pretty common occurence.)</p>
<p><pre class="brush: sql;">
SELECT * FROM Book
JOIN Author ON Book.author_id = Author.id
JOIN Publisher ON Book.id = Publisher.publisher_id
</pre></p>
<p>Did you catch my mistake above?  Probably not.  Most people would overlook it.  With the ER diagram above, and not very many columns on the tables, it is a little bit easier to see.</p>
<p>It is very easy to mix up which table is the parent and which is the child.  It is very easy to put the .id on the wrong side of the join clause.  The correct SQL should have been:</p>
<p><pre class="brush: sql;">
SELECT * FROM Book
JOIN Author ON Book.author_id = Author.id
JOIN Publisher ON Book.publisher_id = Publisher.id
</pre></p>
<h2>Bucking the trend</h2>
<p>Now take a look at this ER diagram:</p>
<p><a href="http://complextosimple.files.wordpress.com/2010/03/databasewithfullname.jpg"><img class="alignnone size-full wp-image-552" title="databasewithfullname" src="http://complextosimple.files.wordpress.com/2010/03/databasewithfullname.jpg?w=500" alt=""   /></a></p>
<p>The corresponding SQL for selecting from this database is:</p>
<p><pre class="brush: sql;">
SELECT * FROM Book
JOIN Author ON Book.author_id = Author.author_id
JOIN Publisher ON Book.publisher_id = Publisher.publisher_id
</pre></p>
<p>It is a small change, but it makes a huge difference.  Writing SQL to join the tables is much easier and much more difficult to get wrong.  Yes, I am repeating myself here, but I am doing it for a very good reason.  I am making the SQL much more clear and I am making it much easier to talk about these tables.</p>
<p>Think about the last time you had a conversation about database tables.  Did you say <em>id</em>?  Did you then have to qualify which <em>id</em> you were talking about?  If you never have <em>&#8220;id&#8221;</em>, you eliminate a large amount of ambiguity.</p>
<p>The major argument against what I am suggesting is that you don&#8217;t need to name the <em>id</em> for the <em>book</em>, <em>book_id</em> because it is a column on book, so you know that id refers to the <em>id </em>of the book.  I do not disagree with this.  For the most part that principle is sound.  The question though is &#8220;which one is easier to read, write and talk about?&#8221;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/549/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/549/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/549/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/549/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/549/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/549/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/549/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/549/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=549&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2010/03/24/naming-database-columns-when-to-violate-dry/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2010/03/databasewithid.jpg" medium="image">
			<media:title type="html">databasewithid</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2010/03/databasewithfullname.jpg" medium="image">
			<media:title type="html">databasewithfullname</media:title>
		</media:content>
	</item>
		<item>
		<title>Using SQL to Check Complicated SQL</title>
		<link>http://simpleprogrammer.com/2010/02/17/using-sql-to-check-complicated-sql/</link>
		<comments>http://simpleprogrammer.com/2010/02/17/using-sql-to-check-complicated-sql/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 19:33:17 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Process Improvement]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://simpleprogrammer.com/?p=393</guid>
		<description><![CDATA[Complicated Queries I frequently find myself in the position of having to write fairly complex SQL queries in order to get a list of data that matches a certain criteria.  One problem with complicated SQL queries is that it is very hard to know if the result you have is correct, especially when your query [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=393&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3>Complicated Queries</h3>
<p>I frequently find myself in the position of having to write fairly complex SQL queries in order to get a list of data that matches a certain criteria.  One problem with complicated SQL queries is that it is very hard to know if the result you have is correct, especially when your query involves multi-table joins and sub-selects.  Often, a small error in one part of a complex SQL query can go unnoticed because it doesn&#8217;t greatly change the count of the results.</p>
<p>Unfortunately, sometimes there is just no way to make a simple query to achieve a certain result.  Often, a large amount of the information applied to the data in order to create the query requires outside knowledge that is not found in the relationships directly specified in the database.  In situations like these a solid technique for verifying the results of the query is important.</p>
<h3><strong>SQL checking SQL</strong></h3>
<p>I have started using a technique of approaching a query from two different directions in order to check my results.  The idea is that if you can think of more than one way to get the same set of data you are looking for, and each way returns the same set or results, the likelihood of that data being correct is greatly increased.</p>
<p>There was a scene in Apollo 13 where Tom Hanks manually calculated some trajectory and 3 guys in Houston all checked his math to make sure it was correct.  When they all came up with the same answer, everyone could be pretty sure the calculation was correct.</p>
<p><a href="http://complextosimple.files.wordpress.com/2010/02/apollo13missioncontrol1.jpg"><img class="alignnone size-full wp-image-394" title="Apollo13MissionControl1" src="http://complextosimple.files.wordpress.com/2010/02/apollo13missioncontrol1.jpg?w=500&#038;h=375" alt="" width="500" height="375" /></a></p>
<p>That is the idea behind SQL checking SQL.  If you can write a second query to get the same data, but from a different angle, there is a pretty good chance that the query is correct.  The best way to do this would be to have another person write the second query, knowing nothing about how you are doing the first.</p>
<h3>A Practical Example</h3>
<p>Sounds good, but how can I actually use it?  Let&#8217;s say that you have a database which stores job applications and resumes from applicants.  Let&#8217;s say that you want to create a list of all the applicants last week.</p>
<p>We could approach this problem from two angles.</p>
<ul>
<li>Get a list of all the people who had an application where the application date was last week.</li>
<li>Get a list of all the people who had a resume created.</li>
</ul>
<p>We have to use some outside information here.  We have to know that in our particular program, each applicant for a job can only have one resume submitted and they must have one submitted.  Then we know that we should see the same list of people who applied for jobs and had resumes created in that time frame.</p>
<p>Of course this is a really simple example, and given all the conditions it would be easy to be pretty sure of either of these queries without running both.  The problem is when you have a much larger set of tables you are interacting with and shakier sets of relations between the tables and data.</p>
<h3>Tips and Tricks</h3>
<p>Once you have created both queries to get the same set of resulting data, how can you easily check to see if they contain the same data?  The easiest way is to do a difference in SQL.  Depending on what flavor of SQL you are using, the syntax is slightly different.  You can look up the set operations for your flavor of SQL.  Difference is the opposite of union.  Difference allows you to see what records exist in the first query and not the second. I like to use difference with the 1st query first and with the 2nd query first, so that I can see what records are in either query, but not in the other.  Any records I find, I closely examine to figure out why they are in one and not the other.  Each time I do this, I then makes changes to the query that was wrong until all the results match exactly.</p>
<p>This balancing of the two queries helps to highlight problems that could be missed from either viewpoint of the problem.  After balancing out both queries to be exactly the same results, there is a really good chance the results are correct.  Certainly the chances of your query being correct are increased vs &#8220;just winging it.&#8221;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/393/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=393&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2010/02/17/using-sql-to-check-complicated-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2010/02/apollo13missioncontrol1.jpg" medium="image">
			<media:title type="html">Apollo13MissionControl1</media:title>
		</media:content>
	</item>
		<item>
		<title>Tracking a Change on a Column</title>
		<link>http://simpleprogrammer.com/2009/12/09/tracking-a-change-on-a-column/</link>
		<comments>http://simpleprogrammer.com/2009/12/09/tracking-a-change-on-a-column/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 16:12:42 +0000</pubDate>
		<dc:creator>jsonmez</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Design]]></category>

		<guid isPermaLink="false">http://simpleprogrammer.com/?p=62</guid>
		<description><![CDATA[I recently ran across a very interesting problem involving database design. I have changed the table names to simplify the problem, so let me describe it as such: I have 2 tables, fruit and vegetable. Each stores whether or not a fruit or vegetable is tasty.  We can ignore the other columns, so it would [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=62&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently ran across a very interesting problem involving database design.</p>
<p>I have changed the table names to simplify the problem, so let me describe it as such:</p>
<p>I have 2 tables, <em>fruit</em> and <em>vegetable. </em>Each stores whether or not a fruit or vegetable is tasty.  We can ignore the other columns, so it would be like</p>
<p><a href="http://complextosimple.files.wordpress.com/2009/12/justthetables.jpg"><img class="alignnone size-medium wp-image-63" title="JustTheTables" src="http://complextosimple.files.wordpress.com/2009/12/justthetables.jpg?w=300&#038;h=93" alt="" width="300" height="93" /></a></p>
<p>Now lets say that someone keeps changing the IsTasty setting through the UI of my application and management is demanding the ability to see when someone changed it last and who.  The tricky part here is although we are ignoring the other data on the table, there is other data, and we don&#8217;t want to track when any data on the table was changed, just this one column.</p>
<p><strong>Solution 1: Track the data in the table by adding columns to track updated on and updated by.</strong></p>
<p><strong><a href="http://complextosimple.files.wordpress.com/2009/12/option1inthetable.jpg"><img class="alignnone size-medium wp-image-65" title="Option1InTheTable" src="http://complextosimple.files.wordpress.com/2009/12/option1inthetable.jpg?w=300&#038;h=141" alt="" width="300" height="141" /></a></strong></p>
<p>Drawback here is we are adding 2 extra columns per table, and anywhere else we wanted to do this would require the same.  Imagine if we had more columns in this same table we wanted to track changes on.  Arghh&#8230;</p>
<p><strong>Solution 2: Track the data in a separate table for the fruit and vegetable tables for just that column.</strong></p>
<p><strong><a href="http://complextosimple.files.wordpress.com/2009/12/option2columnbecomestable1.jpg"><img class="alignnone size-medium wp-image-66" title="Option2ColumnBecomesTable" src="http://complextosimple.files.wordpress.com/2009/12/option2columnbecomestable1.jpg?w=300&#038;h=206" alt="" width="300" height="206" /></a></strong></p>
<p>This seems to be a little more clean and extensible in the future.  Now we have created two extra tables, and we haven&#8217;t added a bunch of extra columns to our existing tables, but if we wanted to track more columns, we would have to add more tables that are copy and pastes of these tables.  These tables are also exactly the same as each other except for the foreign key.</p>
<p><strong>Solution 3: Create a new table that has 2 optional foreign keys</strong></p>
<p><strong><a href="http://complextosimple.files.wordpress.com/2009/12/option3megatable.jpg"><img class="alignnone size-medium wp-image-67" title="Option3MegaTable" src="http://complextosimple.files.wordpress.com/2009/12/option3megatable.jpg?w=300&#038;h=247" alt="" width="300" height="247" /></a></strong></p>
<p>Here we are removing the duplication of the tables that are almost exactly alike.  It will scale, but we have optional foreign keys and it is very hard to do joins.  We also lose knowing what data this table belongs to and automatic referential integrity provided by the database.  (Which is the ability for the database to know what tables are linked together and make sure the referential data is correct.)  We could create a custom constraint, but each time we need a new column we would have to add a new key, and for a different type of column, we would need another table.</p>
<p><strong>Solution 4: Create a meta table to store information about columns in other tables</strong></p>
<p><strong><a href="http://complextosimple.files.wordpress.com/2009/12/option4metatable1.jpg"><img class="alignnone size-medium wp-image-70" title="Option4MetaTable" src="http://complextosimple.files.wordpress.com/2009/12/option4metatable1.jpg?w=300&#038;h=283" alt="" width="300" height="283" /></a></strong></p>
<p>To me this seems like the best approach.  When a column was changed has nothing to do with a fruit or vegetable.  It is data about data or meta-data.  By creating a table to store meta-data about any table it is very scalable.  We don&#8217;t have a foreign key, but we can either create triggers, or use our DAO framework to automatically make inserts to the audit table.</p>
<p>Other options?  Pro&#8217;s con&#8217;s?  Thoughts?</p>
<p><strong> </strong></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/complextosimple.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/complextosimple.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/complextosimple.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/complextosimple.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/complextosimple.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/complextosimple.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/complextosimple.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/complextosimple.wordpress.com/62/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=simpleprogrammer.com&amp;blog=10597120&amp;post=62&amp;subd=complextosimple&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://simpleprogrammer.com/2009/12/09/tracking-a-change-on-a-column/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/695e2a956b2dcb5ac45a7095b6ee338a?s=96&#38;d=retro&#38;r=PG" medium="image">
			<media:title type="html">jsonmez</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2009/12/justthetables.jpg?w=300" medium="image">
			<media:title type="html">JustTheTables</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2009/12/option1inthetable.jpg?w=300" medium="image">
			<media:title type="html">Option1InTheTable</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2009/12/option2columnbecomestable1.jpg?w=300" medium="image">
			<media:title type="html">Option2ColumnBecomesTable</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2009/12/option3megatable.jpg?w=300" medium="image">
			<media:title type="html">Option3MegaTable</media:title>
		</media:content>

		<media:content url="http://complextosimple.files.wordpress.com/2009/12/option4metatable1.jpg?w=300" medium="image">
			<media:title type="html">Option4MetaTable</media:title>
		</media:content>
	</item>
	</channel>
</rss>
