<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SSIS Junkie : data modelling</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/tags/data+modelling/default.aspx</link><description>Tags: data modelling</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Data Warehouse modelling deliberations – foreign keys and unknown members</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2013/04/16/data-warehouse-modelling-deliberations-foreign-keys-and-unknown-members.aspx</link><pubDate>Tue, 16 Apr 2013 21:36:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:48738</guid><dc:creator>jamiet</dc:creator><slash:comments>8</slash:comments><comments>http://sqlblog.com/blogs/jamie_thomson/comments/48738.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/jamie_thomson/commentrss.aspx?PostID=48738</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/jamie_thomson/rsscomments.aspx?PostID=48738</wfw:comment><description>&lt;p&gt;Earlier today I posted the following question on Twitter:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/jamiet/status/324215986729385986"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="536" height="288" src="http://sqlblog.com/blogs/jamie_thomson/image_7211381A.png"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Foreign keys in a data warehouse. Yes or no? This discussion is looming at work, i know my position but am interested in what others think.     &lt;br&gt;(&lt;a target="_blank" href="https://twitter.com/jamiet/status/324215986729385986"&gt;https://twitter.com/jamiet/status/324215986729385986&lt;/a&gt;)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Specifically, I wanted to know if people were in favour of creating foreign keys from their fact to to their dimension tables or not.&lt;/p&gt;  &lt;p&gt;To say it prompted a good response is a bit of an understatement, 38 responses so far and counting. Here are some of those responses:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/AdamMachanic/status/324216208721330176"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="410" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_69AD62C3.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/dykesa/status/324217098333216769"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="412" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_1ACC9D64.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/sqlslacker/status/324217752577536000"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="412" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_40C24DBA.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/MarkGStacey/status/324218026532671488"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="413" height="91" src="http://sqlblog.com/blogs/jamie_thomson/image_14A550C9.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/datachick/status/324218360768393216"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="410" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_77BC2BF3.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/CalvinFerns/status/324219759438749697"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="409" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_4B9F2F02.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/JakeSmillie/status/324224224019509248"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="410" height="90" src="http://sqlblog.com/blogs/jamie_thomson/image_2AABBC5B.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/snack00/status/324225626850607105"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="409" height="90" src="http://sqlblog.com/blogs/jamie_thomson/image_3BAFEA3E.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/knight_devin/status/324236580464230400"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="410" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_61A59A94.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/markiehill/status/324242405341659136"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="411" height="77" src="http://sqlblog.com/blogs/jamie_thomson/image_12C4D535.png"&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/EyeOfSoreRon/status/324268874054914050"&gt;&lt;img title="image" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="image" width="409" height="90" src="http://sqlblog.com/blogs/jamie_thomson/image_58D59248.png"&gt;&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It certainly seems to be an emotive subject and its clear (to me) that there’s no correct answer, just lots of opinions. That’s a good thing. The majority of responders appeared to be of the opinion that a data warehouse &lt;i&gt;should&lt;/i&gt; contain foreign keys and that is my position too. In this blog post I want to outline &lt;i&gt;why&lt;/i&gt; I believe that one should create foreign keys from a fact table to its dimension tables:&lt;/p&gt;  &lt;h3&gt;Maintain integrity&lt;/h3&gt;  &lt;p&gt;Of course, this is the main reason why foreign keys exist – to protect the integrity of your data. I see no reason not to use them for this purpose in a data warehouse. The main argument that I see going against is that with a sufficiently robust ETL solution it shouldn’t be necessary. That is true but I would counter with “how do you know that your ETL solution is suitably robust?” I don’t think its possible to anticipate every eventuality that may arise and for that reason I like the safety net that foreign keys provide. I liked &lt;a target="_blank" href="https://twitter.com/knight_devin/status/324236580464230400"&gt;Devin Knight’s response&lt;/a&gt; here, foreign keys breed confidence.&lt;/p&gt;  &lt;h3&gt;Communicate business logic&lt;/h3&gt;  &lt;p&gt;When I join a project that has a database in place the first thing I do is try and understand the data model – to do that I go and look at the foreign keys in that database. Understanding the dependencies between entities is crucial in any data model and the best means of communicating those is via foreign keys. If I encounter a database that is bereft of foreign keys then my heart sinks a little.&lt;/p&gt;  &lt;h3&gt;Performance&lt;/h3&gt;  &lt;p&gt;Foreign keys can, in some circumstances, be beneficial in improving query performance. Take a read of &lt;a target="_blank" href="http://www.sqlservercentral.com/articles/Performance+Tuning/71264/"&gt;A Check and Foreign Key Constraint Improves Query Performance&lt;/a&gt; by Sarvesh Singh or &lt;a title="http://www.scarydba.com/2010/11/22/do-foreign-key-constraints-help-performance/" target="_blank" href="http://www.scarydba.com/2010/11/22/do-foreign-key-constraints-help-performance/"&gt;Do Foreign Key Constraints Help Performance?&lt;/a&gt; by Grant Fritchey.&lt;/p&gt;  &lt;h3&gt;Code Generation&lt;/h3&gt;  &lt;p&gt;I am a big fan of generating ETL code where possible and foreign keys can be invaluable when doing so.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;As I said there is no correct answer here so if you have any opinions, either agreeing or disagreeing, I look forward to reading your thoughts in the comments below.&lt;/p&gt;  &lt;hr&gt;  &lt;p&gt;&lt;a target="_blank" href="https://twitter.com/MarkGStacey/status/324218026532671488"&gt;Mark Stacey’s comment&lt;/a&gt; prompted an interesting digression into talking about surrogate keys for denoting unknown members and this is something I have strong opinions on too:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/SNAGHTML1ce05180_2CB89557.png"&gt;&lt;img title="SNAGHTML1ce05180" style="border-top:0px;border-right:0px;background-image:none;border-bottom:0px;padding-top:0px;padding-left:0px;border-left:0px;display:inline;padding-right:0px;" border="0" alt="SNAGHTML1ce05180" width="365" height="720" src="http://sqlblog.com/blogs/jamie_thomson/SNAGHTML1ce05180_thumb_5C270423.png"&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;In short, I don’t like the practice of using “–1” as the surrogate key for an unknown member. My reasoning is simple, I don’t like giving meaning to something that is supposed to be meaningless. How then should we indicate which is the unknown member? I propose a single-row table that includes a column for each dimension table, each with a foreign key to the unknown member in the respective dimension table.&lt;/p&gt;  &lt;p&gt;Moreover I don’t like the practice of starting surrogate key counters from 1; &lt;a target="_blank" href="http://msdn.microsoft.com/en-gb/library/ms187745.aspx"&gt;the first value available for the integer datatype in SQL Server is –2147483648&lt;/a&gt;&amp;nbsp; so why not start from that?&lt;/p&gt;  &lt;p&gt;I discuss both of these issues in much more depth at &lt;a target="_blank" href="http://sqlblog.com/blogs/jamie_thomson/archive/2009/10/14/considering-surrogate-keys-for-unknown-members.aspx"&gt;Considering surrogate keys for Unknown members&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Again if you have any thoughts on these subjects please put them in the comments. If nothing else I find it both fun and educational to debate this stuff.&lt;/p&gt;  &lt;p&gt;&lt;a target="_blank" href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Update, Chris Adkin posted a comment below that contained a link to Microsoft's own guidance on building datawarehouses where it is stated:&lt;/p&gt;&lt;p&gt;"&lt;span style="font-family:Verdana, Arial, sans-serif;font-size:11px;"&gt;&lt;i&gt;Many physical designs for data warehouses follow the star schema but do not completely specify the relationships between the fact and dimension tables, as mentioned earlier for foreign key constraints, for instance. Without the foreign key constraints explicitly specified, SQL Server must depend on heuristics to detect star schema query patterns.&lt;/i&gt;&lt;/span&gt;&lt;span style="font-size:10pt;"&gt;"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;"&gt;Chris' take on this:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;"&gt;"&lt;/span&gt;&lt;span style="font-family:Verdana, Arial, sans-serif;font-size:11px;"&gt;So, assuming we are talking about a Kimball DW, there is most definitely value in using foreign key contstraints as this provides a fail safe for the heuristics getting it wrong.&lt;/span&gt;&lt;span style="font-size:10pt;"&gt;"&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:10pt;"&gt;Thanks Chris.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=48738" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/data+warehousing/default.aspx">data warehousing</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/surrogate+keys/default.aspx">surrogate keys</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/data+modelling/default.aspx">data modelling</category></item><item><title>Twitter status id conundrum</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2010/04/18/twitter-status-id-conundrum.aspx</link><pubDate>Sun, 18 Apr 2010 15:05:38 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:24385</guid><dc:creator>jamiet</dc:creator><slash:comments>5</slash:comments><comments>http://sqlblog.com/blogs/jamie_thomson/comments/24385.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/jamie_thomson/commentrss.aspx?PostID=24385</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/jamie_thomson/rsscomments.aspx?PostID=24385</wfw:comment><description>&lt;p&gt;I have an interest, a slightly perverse one some might say, in using online services and trying to figure out what the underlying (logical) data model is and in this day and age Twitter is one that lends itself very well to scrutiny. Consider this recent tweet of mine:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a title="odata rdf tweet" href="http://twitter.com/jamiet/status/12154647354" target="_blank"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="odata rdf tweet screenshot" border="0" alt="odata rdf tweet screenshot" src="http://sqlblog.com/blogs/jamie_thomson/image_0DAD61B4.png" width="389" height="246" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The URL that enables you to see that tweet is &lt;a href="http://twitter.com/jamiet/status/12154647354" target="_blank"&gt;http://twitter.com/jamiet/status/12154647354&lt;/a&gt;&lt;strong&gt;&lt;/strong&gt;. We can interpret that URL to mean &amp;quot;a tweet by jamiet with an id of 12154647354&amp;quot; and hence we might further assume that the unique identifier for the tweet is {jamiet,12154647354}.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;However, its well-known that Twitter gives each status a unique ID regardless of who tweeted it so we might expect we could reach that tweet just by using a URL of &lt;a href="http://twitter.com/status/12154647354" target="_blank"&gt;http://twitter.com/status/12154647354&lt;/a&gt; however (at the time of writing) that only redirects to Twitter's homepage. That seems strange to me especially given that we can use Twitter's API to access information about that tweet using only the id of the status. Witness &lt;a href="http://api.twitter.com/1/statuses/show/12154647354.xml" target="_blank"&gt;http://api.twitter.com/1/statuses/show/12154647354.xml&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a title="twitter api screenshot xml" href="http://api.twitter.com/1/statuses/show/12154647354.xml" target="_blank"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="screenshot of twitter api result" border="0" alt="screenshot of twitter api result" src="http://sqlblog.com/blogs/jamie_thomson/image_0C8852C8.png" width="477" height="400" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;[We can also access a &lt;/em&gt;&lt;a href="http://json.org/" target="_blank"&gt;JSON&lt;/a&gt;&lt;em&gt;&lt;/em&gt;&lt;em&gt; version of that information using &lt;/em&gt;&lt;a href="http://api.twitter.com/1/statuses/show/12154647354.json" target="_blank"&gt;http://api.twitter.com/1/statuses/show/12154647354.json&lt;/a&gt;&lt;em&gt;&lt;/em&gt;&lt;em&gt;]&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;I'm puzzled as to why a tweet can't be accessed using on the main twitter website using the id alone. Anyone have any suggestions?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://twitter.com/jamiet" target="_blank"&gt;@jamiet&lt;/a&gt;&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=24385" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/twitter/default.aspx">twitter</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/data+modelling/default.aspx">data modelling</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/random+waffle/default.aspx">random waffle</category></item><item><title>Debunking Kimball Effective Dates</title><link>http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/28/debunking-kimball-effective-dates.aspx</link><pubDate>Sat, 28 Nov 2009 15:59:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:19269</guid><dc:creator>jamiet</dc:creator><slash:comments>56</slash:comments><comments>http://sqlblog.com/blogs/jamie_thomson/comments/19269.aspx</comments><wfw:commentRss>http://sqlblog.com/blogs/jamie_thomson/commentrss.aspx?PostID=19269</wfw:commentRss><wfw:comment>http://sqlblog.com/blogs/jamie_thomson/rsscomments.aspx?PostID=19269</wfw:comment><description>&lt;p&gt;Those who are familiar with Ralph Kimball’s theories on data warehousing modelling may be familiar with his assertion that a type 2 dimension member record should have a StartDate and an EndDate that defines the effective period of that record. He outlines this approach in his paper &lt;a href="http://digital.dmreview.com/dmreview/200810/?pg=21"&gt;Slowly Changing Dimensions, Types 2 &amp;amp; 3&lt;/a&gt; from the &lt;a href="http://digital.dmreview.com/dmreview/200810/?pg=21"&gt;October 2008 edition of DMReview&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;i&gt;I recommend adding five additional fields to a dimension that is undergoing Type 2 processing… begin-effective-datetime &amp;amp; end-effective-datetime are full time stamps that that represent the span of time between when the change became effective and when the next change becomes effective. The end-effective-datetime of a Type 2 dimension record must be exactly equal to the begin-effective-datetime of the next change for that dimension member .The most current dimension record must have an end-effective-datetime equal to a fictitious datetime far in the future.&lt;/i&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;My opinion, which is based on experience of implementing this technique, is that it is a bad idea and in this blog post I’ll explain why. Let me clarify that I do not think the practise of managing dimension members as Type 2 slowly changing dimensions is a bad idea, only that maintaining an effective period using a start date and an end date is.&lt;/p&gt;  &lt;h3&gt;Framing the problem&lt;/h3&gt;  &lt;p&gt;Let’s look at an example where I am modelling customers as a type 2 dimension. Following Kimball’s advice we would implement a table something like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_61A8C458.png"&gt;&lt;img style="border-width:0px;margin-right:auto;margin-left:auto;float:none;display:block;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_6970B6FA.png" width="756" height="148"&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note how we have two records for “Henry” because at some point he got married and had a child (attributes that we treat as type 2 changes) and how the [SCDEndDate] of the first record equals the [SCDStartDate] of the second record.&lt;/p&gt;  &lt;p&gt;Can you spot the obvious problem here? &lt;em&gt;We’ve got the same piece of information in more than one place&lt;/em&gt;; namely the date ‘27/11/2009’. What’s the point? We know that the [SCDEndDate] of a record equals the [SCDStartDate] of the record that supersedes it so using our old friend SQL we can easily work out the [SCDEndDate] of any record. I’ve seen too many examples of Kimball’s approach being used and I’ve hardly ever seen it not be a problem; just recently I worked on a data migration project and we had untold problems created by the use of [SCDStartDate] and [SCDEndDate] because the database could not constrain this relationship and neither, seemingly, did the code that had been written to manage the data.&lt;/p&gt;  &lt;p&gt;At the root of this problem is the fact that Kimball’s method cannot be constrained in a relational database management system (RDBMS) without a complicated and debilitating set-based check constraint, it ignores the goodness of relational theory and normalisation that data professionals have had drummed into them for years.&lt;/p&gt;  &lt;h3&gt;A better way&lt;/h3&gt;  &lt;p&gt;Here follows how I would solve this problem; note that the syntax here is for SQL Server but this method would work perfectly well for any RDBMS.&lt;/p&gt;  &lt;p&gt;Firstly, let’s create a table and put some data in it:&lt;/p&gt;  &lt;blockquote&gt;   &lt;table cellSpacing="0" cellPadding="0" bgColor="#eeeeee"&gt;       &lt;tr&gt;         &lt;td&gt;           &lt;pre style="padding:10px 20px;font-family:consolas,lucida console,courier new,courier;font-size:12px;-moz-background-clip:border;-moz-background-origin:padding;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;CREATE TABLE &lt;/font&gt;&lt;font color="black"&gt;[Customer] &lt;/font&gt;&lt;font color="gray"&gt;(
&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[Id]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;INT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PRIMARY KEY
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[NId]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;NVARCHAR&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;50&lt;/font&gt;&lt;font color="gray"&gt;)
&lt;br&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[Name]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;NVARCHAR&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;50&lt;/font&gt;&lt;font color="gray"&gt;)
&lt;br&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[HomeTown]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;NVARCHAR&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;50&lt;/font&gt;&lt;font color="gray"&gt;)
&lt;br&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[MaritalStatus]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;CHAR&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;1&lt;/font&gt;&lt;font color="gray"&gt;)
&lt;br&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[NumberOfChildren]&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;INT
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[SCDStartDate]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DATETIME&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="green"&gt;--Note only [SCDStartDate], no [SCDEndDate]
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;CONSTRAINT&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;Customer_UK &lt;/font&gt;&lt;font color="blue"&gt;UNIQUE
&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="gray"&gt;(
&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[NId]
&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[SCDStartDate]
&lt;br&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="gray"&gt;)
&lt;br&gt;);
&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;INSERT &lt;/font&gt;&lt;font color="black"&gt;[Customer] &lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;[Id]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;[NId]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;[Name]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;[HomeTown]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;[MaritalStatus]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;[NumberOfChildren]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;[SCDStartDate]&lt;/font&gt;&lt;font color="gray"&gt;)
&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;VALUES &lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;1&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Cust001'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Henry'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'London'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'S'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;0&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;DATETIME&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'20050324'&lt;/font&gt;&lt;font color="gray"&gt;))
&lt;br&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/font&gt;&lt;font color="black"&gt;2&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Cust001'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Henry'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'London'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'M'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;0&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;DATETIME&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'20070726'&lt;/font&gt;&lt;font color="gray"&gt;))
&lt;br&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/font&gt;&lt;font color="black"&gt;3&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Cust002'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Sarah'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Birmingham'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'M'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;2&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;DATETIME&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'20060213'&lt;/font&gt;&lt;font color="gray"&gt;))
&lt;br&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&lt;/font&gt;&lt;font color="black"&gt;4&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Cust001'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'Henry'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'London'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'M'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;1&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;DATETIME&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'20091127'&lt;/font&gt;&lt;font color="gray"&gt;));,&lt;/font&gt;&lt;font color="red"&gt;'M'&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;2&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;DATETIME&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'20060213'&lt;/font&gt;&lt;font color="gray"&gt;));&lt;/font&gt;&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve created three rows here for Henry for demo purposes. Over time we notice that Henry got married and then later had a child; note that there is no [SCDEndDate]:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_14D4D7F5.png"&gt;&lt;img style="border-width:0px;display:inline;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_535A259B.png" width="571" height="162"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let’s write a view that gets us the [SCDEndDate] for each record:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;table cellSpacing="0" cellPadding="0" bgColor="#eeeeee"&gt;
      &lt;tr&gt;
        &lt;td&gt;
          &lt;pre style="padding:10px 20px;font-family:consolas,lucida console,courier new,courier;font-size:12px;-moz-background-clip:border;-moz-background-origin:padding;-moz-background-inline-policy:continuous;"&gt;&lt;font color="blue"&gt;CREATE VIEW &lt;/font&gt;&lt;font color="black"&gt;vCustomer&amp;nbsp; &lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;AS
&lt;br&gt;SELECT &lt;/font&gt;&lt;font color="black"&gt;c.[Id]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[NId]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[Name]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[HomeTown]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[MaritalStatus]
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;c.[NumberOfChildren]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[SCDStartDate]
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="magenta"&gt;COALESCE&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="blue"&gt;MIN&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;c2.[ScdStartDate]&lt;/font&gt;&lt;font color="gray"&gt;),&lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;DATETIME&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="red"&gt;'99991231'&lt;/font&gt;&lt;font color="gray"&gt;)) &lt;/font&gt;&lt;font color="blue"&gt;AS &lt;/font&gt;&lt;font color="black"&gt;[SCDEndDate]
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="magenta"&gt;CONVERT&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;BIT&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="magenta"&gt;CASE&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="blue"&gt;WHEN MIN&lt;/font&gt;&lt;font color="gray"&gt;(&lt;/font&gt;&lt;font color="black"&gt;c2.[ScdStartDate]&lt;/font&gt;&lt;font color="gray"&gt;) &lt;/font&gt;&lt;font color="blue"&gt;IS &lt;/font&gt;&lt;font color="gray"&gt;NULL &lt;/font&gt;&lt;font color="blue"&gt;THEN &lt;/font&gt;&lt;font color="black"&gt;1 &lt;/font&gt;&lt;font color="blue"&gt;ELSE &lt;/font&gt;&lt;font color="black"&gt;0 &lt;/font&gt;&lt;font color="blue"&gt;END&lt;/font&gt;&lt;font color="gray"&gt;) &lt;/font&gt;&lt;font color="blue"&gt;AS &lt;/font&gt;&lt;font color="black"&gt;[IsLatest]
&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;FROM&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;[Customer] c
&lt;br&gt;&lt;/font&gt;&lt;font color="magenta"&gt;LEFT&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="gray"&gt;OUTER &lt;/font&gt;&lt;font color="blue"&gt;JOIN &lt;/font&gt;&lt;font color="black"&gt;[Customer] c2
&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;ON&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;c.[Nid] &lt;/font&gt;&lt;font color="blue"&gt;= &lt;/font&gt;&lt;font color="black"&gt;c2.[Nid]
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;AND&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;c.[SCDStartDate] &lt;/font&gt;&lt;font color="gray"&gt;&amp;lt; &lt;/font&gt;&lt;font color="black"&gt;c2.[SCDStartDate]
&lt;br&gt;&lt;/font&gt;&lt;font color="blue"&gt;GROUP&amp;nbsp; BY &lt;/font&gt;&lt;font color="black"&gt;c.[Id]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[NId]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[Name]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[HomeTown]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[MaritalStatus]
&lt;br&gt;&lt;/font&gt;&lt;font color="gray"&gt;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color="black"&gt;c.[NumberOfChildren]&lt;/font&gt;&lt;font color="gray"&gt;,&lt;/font&gt;&lt;font color="black"&gt;c.[SCDStartDate]&lt;/font&gt;&lt;font color="gray"&gt;;&lt;/font&gt;&lt;/pre&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/table&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is what we get if we select from that view:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href="http://sqlblog.com/blogs/jamie_thomson/image_3FCCC5FA.png"&gt;&lt;img style="border-width:0px;display:inline;" title="image" border="0" alt="image" src="http://sqlblog.com/blogs/jamie_thomson/image_thumb_765A713E.png" width="748" height="144"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note that each row for Henry has an [SCDEndDate] that is &lt;em&gt;guaranteed&lt;/em&gt; to be the same as the [SCDStartDate] of the record that supersedes it. Note also that we are &lt;em&gt;guaranteed&lt;/em&gt; there will be no time period gaps since when Henry first became known to us. (Edit: Another advantage of this approach was pointed out to me by Phil Nolan in the comments below: we do not have to update a record when it gets superseded which we would have to do were we explicitly storing [SCDEndDate])&lt;/p&gt;

&lt;p&gt;We have achieved this by joining the [Customer] table to itself and, for each row, finding the row that supersedes it and use the superseding row’s [SCDStartDate] as the current row’s [SCDEndDate]; if there is no superseding row we simply use a fictitious future date exactly as Kimball suggests. Moreover we can also derive an [IsLatest] field which is another field that Kimball recommend we use and also another field whose value cannot be constrained by the relational model. We have achieved the same as Kimball’s bunkum [SCDStartDate] &amp;amp; [SCDEndDate] table columns and still maintained the integrity of our data.&lt;/p&gt;

&lt;p&gt;The counter argument to doing this is that Kimball’s method will be quicker because we don’t need to write an INNER JOIN to achieve the data that we want. Well that is true but ask yourself what is more important, querying speed or the integrity of your data? If your answer is '’querying speed’ then you should probably ask yourself why you’re bothering to use an RDBMS at all; data integrity is the reason that we build a relational data model. [That’s a pretty controversial opinion so I’ll look forward to debating it in the &lt;a href="http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/28/debunking-kimball-effective-dates.aspx"&gt;comments of this blog post&lt;/a&gt; :)]&lt;/p&gt;

&lt;p&gt;If you absolutely need the [SCDEndDate] persisted somewhere then I’ll concede that the view resultset can be materialised into a table but really I don’t think there is that much need to do so; the main use of an [SCDEndDate] is to make your ETL easier and I’m sure its extremely rare that an ETL process cannot cope with the slightly increased querying time created by using the method I outline herein.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;In this blog post I have outlined the problems that I believe are inherent in Kimball’s method of defining a time period for a slowly-changing-dimension record and also an alternative method that exhibits a purer method of achieving the same information. I welcome your thoughts in the comments below.&lt;/p&gt;

&lt;p&gt;I have uploaded the script that I used herein so that you can try this technique for yourself. Download it from my Skydrive: &lt;a title="http://cid-550f681dad532637.skydrive.live.com/self.aspx/Public/BlogShare/20091128/DebunkingKimballMethodEffectiveDates.sql" href="http://cid-550f681dad532637.skydrive.live.com/self.aspx/Public/BlogShare/20091128/DebunkingKimballMethodEffectiveDates.sql"&gt;http://cid-550f681dad532637.skydrive.live.com/self.aspx/Public/BlogShare/20091128/DebunkingKimballMethodEffectiveDates.sql&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://twitter.com/jamiet"&gt;@Jamiet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P.S. There are some great debates going on in the comments section of this blog post so if you’re reading this using a blog aggregator/feedreader click through to &lt;a title="http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/28/debunking-kimball-effective-dates.aspx" href="http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/28/debunking-kimball-effective-dates.aspx"&gt;http://sqlblog.com/blogs/jamie_thomson/archive/2009/11/28/debunking-kimball-effective-dates.aspx&lt;/a&gt; to read more opinions on this.&lt;/p&gt;&lt;p&gt;&lt;span style="text-transform:none;text-indent:0px;letter-spacing:normal;word-spacing:0px;float:none;white-space:normal;orphans:2;widows:2;font-size-adjust:none;font-stretch:normal;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;"&gt;UPDATE: The debate continued over on &lt;a href="http://forum.kimballgroup.com/t1771-did-anybody-read-this-article" target="_blank"&gt;KimballGroup.com&lt;/a&gt; (where all&amp;nbsp;respondents&lt;/span&gt;&lt;span style="text-transform:none;text-indent:0px;letter-spacing:normal;word-spacing:0px;float:none;white-space:normal;orphans:2;widows:2;font-size-adjust:none;font-stretch:normal;-webkit-text-size-adjust:auto;-webkit-text-stroke-width:0px;"&gt;&amp;nbsp;disagreed with me, unsurprisingly).&lt;/span&gt;&lt;/p&gt;&lt;img src="http://sqlblog.com/aggbug.aspx?PostID=19269" width="1" height="1"&gt;</description><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/data+warehousing/default.aspx">data warehousing</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/sql/default.aspx">sql</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/data+modelling/default.aspx">data modelling</category><category domain="http://sqlblog.com/blogs/jamie_thomson/archive/tags/Kimball/default.aspx">Kimball</category></item></channel></rss>