DB設計中維護修訂歷史的一般策略是什麼?如果它只是我正在處理的一張桌子,我認爲它不會那麼難。只需將每個更新保存爲表格中的新記錄即可。最後的記錄將始終是最新的修訂版本。數據庫設計:如何跟蹤歷史?
但是,當數據存儲在多個表中時,設計該數據以便跟蹤修訂的好方法是什麼?
DB設計中維護修訂歷史的一般策略是什麼?如果它只是我正在處理的一張桌子,我認爲它不會那麼難。只需將每個更新保存爲表格中的新記錄即可。最後的記錄將始終是最新的修訂版本。數據庫設計:如何跟蹤歷史?
但是,當數據存儲在多個表中時,設計該數據以便跟蹤修訂的好方法是什麼?
我更喜歡爲每個版本化表格增加歷史表格。與主表time_from
和time_to
附加字段相同的結構。 透明充滿觸發器。最近修訂的time_to
設置在遙遠的未來。
指定時刻狀態可以查詢檢索這樣的:
SELECT * FROM user_history
WHERE time_from >= '2012-02-01' AND time_to <= '2012-02-01'
至於我,主表中存儲的歷史是不是一般的好主意,因爲它檢索或加入現有數據時需要複雜的條件。
我正在使用的方法,其中我正在處理的每個對象至少有一個所謂的實例表,其中我保留隨時間而變化的數據。通常這樣的表格遵循以下概念:
_HISTORY
後綴名;start_dt
和end_dt
,指示對象實例的生命週期;start_dt
是NOT NULL
,end_dt
可以是NULL
,它表示該實例是當前的並且不受其時間的限制;1/Jan-2013
激活一個新的公司名稱,然後你需要設置當前實例的end_dt
到31/Dec-2012 23:59:59
並插入的1/Jan-2013 00:00:00
start_dt
的新紀錄;revision
字段,如果有必要跟蹤修訂版。爲了有這樣的設計有一個適當的RI約束,我總是有2個版本化obejcts表。比方說,對於Customer
obejct我有以下一組表:
customer (customer_id INTEGER, PRIMARY KEY (customer_id));
customer_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP,
name VARCHAR(50), sex CHAR(1), ...,
PRIMARY KEY (customer_id, start_dt));
customer_bank_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP,
bank_id INTEGER, iban VARCHAR(34));
在所有其他地方我用customer(customer_id)
建立外鍵。查詢實際的客戶信息很簡單:
SELECT c.customer_id, ch.name, ch.sex
FROM customer c
JOIN customer_history ch ON c.customer_id = ch.customer_id
AND now() BETWEEN ch.start_dt AND coalesce(end_dt, now());
爲什麼我更喜歡這樣的設計:
希望這會對你有幫助。
最難的部分不是「基本」表的版本控制 - 您只需單獨對它們進行版本化,就像單獨使用一張表一樣。
困難的部分是跟蹤他們之間的連接。
你打算怎麼做取決於具體項目的要求。下面是sales orders could be "historized"的一個例子,但也有許多其他變體可能。
Datadiff。 API支持的DB版本跟蹤。
披露:
我建Datadiff。我需要一個解決方案,提供MongoDB中數據模型的可視歷史記錄,以幫助支持SASS產品。它也將與SQL數據庫一起工作。
您可以使用key:val
表示法進行基本查詢。即id:123
所以主表具有最新的數據。那麼「歷史」表格有每個版本的副本?這是否打破標準化? – StackOverflowNewbie
是的,非規範化發生,它是簡單的價格(歷史狀態是從主表上簡單的'INSERT','DELETE','UPDATE'自動生成的)和最新版本的性能(例如主表具有基於數據的索引歷史有日期索引)。 如果最新修訂版本不是主要修訂版本,則此方法可能會因標準化失效而受損。 – vearutop