我有兩個表X
和Y
。這是基於Web的CRUD應用程序的後端。快照SQL數據庫行的最佳做法
假設Y
中的行的字段爲a
,b
和c
。當創建一行X
時,它必須鏈接到特定行Y
中值的快照。 Y
中的行可能會稍後更改,但X
中的行在創建時仍應具有值a
,b
和c
。
做這種事情的「正確」方式是什麼?重複字段a
,b
和c
在X
似乎很簡單,但我想知道是否有更好的方法來做到這一點。
我有兩個表X
和Y
。這是基於Web的CRUD應用程序的後端。快照SQL數據庫行的最佳做法
假設Y
中的行的字段爲a
,b
和c
。當創建一行X
時,它必須鏈接到特定行Y
中值的快照。 Y
中的行可能會稍後更改,但X
中的行在創建時仍應具有值a
,b
和c
。
做這種事情的「正確」方式是什麼?重複字段a
,b
和c
在X
似乎很簡單,但我想知道是否有更好的方法來做到這一點。
您需要實施「慢慢變化的維度」。
基本上除了「自然」鍵外,還有一個valid_from和valid_to時間戳。
當前行總是具有「9999-12-31 23:59:59」的「valid_to」或系統可處理的最長日期/時間。
第一行必須: -
id valid_to valid_from description.
1 2009-12-25 9999-12-31 My best new toy.
當您更改說明你沒有覆蓋當前行 但舊行因此添加一個完整的新行的一個變化的失效日期日期: -
id valid_to valid_from description.
1 2009-12-25 2009-06-22 My best new toy
1 2010-06-23 9999-12-31 A broken toy.
然後,您可以將行Y的創建日期用於該日期的相應行X flr。
Select * from x
join Y on x.id = y.id
and x.create-date >= valid_from
and x.create-date <= valid_to
我建議您使用時間戳而不是日期,但原理更容易說明使用日期。
「複製」列似乎是正確的移動給我。有些人可能錯誤地認爲你通過複製數據來違反正確的數據庫設計,但是真正的每個表(及其列)都保存着不同的數據。一個是「當前」值,另一個表在特定時間點具有這些值。
類比將是發票上的地址。如果您需要在發票時捕獲客戶的地址,那麼您不會通過將地址列與發票一起復制數據,也不會在客戶擁有地址的情況下複製數據,因爲他們擁有可能不同的地址版本。
複製列的額外好處是將'JOIN'的開銷消除到'Y'上。 – 2010-07-15 06:14:38
這是有道理的。我只是想知道我在看問題的根本方式是否有問題。我對設計模式不太舒服。我讚賞「不同的數據」一點。我認爲它也不違反任何重複規則。 – 2010-07-15 07:05:50
爲了記錄,我認爲向表中添加列只是爲了避免加入是最糟糕的原因之一。把他們所屬的列。如果您在路上遇到性能問題,那麼可能會將其作爲最後手段進行非規範化。根據我的經驗,將列放置在某個地方過早地提高性能而不是將它們放在自然所屬的地方總是會導致意想不到的後果(閱讀,問題) – 2010-07-15 14:26:30
這是有道理的。你基本上建議我將表格'Y'稍微改變一點,以便按照期間存檔數據,然後使用'X'表中的創建時間來選取'Y'的'右'行。我對麼? – 2010-07-15 07:07:59
是的,這就是它!在數據倉庫中,這個tequnique被稱爲「緩慢地改變維度類型1」,在DW世界之外它有時被稱爲「雙時態表」。 – 2010-07-16 02:08:01