2009-11-10 40 views
1

我有一個要求,以易於索引的方式存儲實體的所有版本,並想知道是否有人對什麼系統使用有任何輸入。版本和索引數據存儲

沒有版本控制系統是簡單地用每一行,例如,人的關係型數據庫。如果該人的狀態發生改變,該行被改變以反映這一點。通過版本控制,條目應該以這種方式進行更新,以便我們可以隨時回到以前的版本。如果我可以使用時間數據庫,這將是免費的,我可以問'在都柏林和30歲的時候,下午2點,所有人的狀態如何。不幸的是,似乎沒有任何成熟的開源項目可以做到時間。

一個真正討厭的方式做,這就是插入每狀態變化的新行。這會導致重複,因爲一個人可以有很多字段,但每次更新只能更改一個字段。爲每個給定時間戳的人選擇正確的版本也很慢。

理論上應該可以使用關係數據庫和版本控制系統模擬一個時態數據庫,但這聽起來很可怕。

所以我想知道是否有人已經遇到以前類似的東西,他們是如何處理的呢?

更新 正如Aaron所建議的,這裏是我們目前使用的查詢(在mysql中)。在我們的桌子上,行數大於200k肯定很慢。 (ID =表密鑰,爲person_id =每人ID,複製如果這個人有很多版本)

從人員P

選擇名稱,其中p.id =(選擇最多的人(ID),其中爲person_id = p.person_id和時間戳< =:時間戳)

更新 它看起來像要做到這一點的最好辦法是用時間分貝,但考慮到目前還沒有任何開源的在那裏的下一個最好的方法是每更新一次存儲新行。唯一的問題是重複未更改的列和緩慢的查詢。

+0

只是一個想法 - 你可能想要考慮一些屬性作爲空間中的點 - 也就是說,(更新時間,年齡[也許這應該是DOB?],位置)空間中的點。然後,您可以使用空間索引技術來查找值。 – bdonlan

回答

2

有兩種方法可以解決這個問題。兩者都假定你總是插入新的行。在任何情況下,您都必須插入一個時間戳(created),告訴您何時行被「修改」。

第一種方法使用數字來計算您已有多少個實例。主鍵是對象鍵和版本號。這種方法的問題似乎是,您需要select max(version)進行修改。在實踐中,這很少是一個問題,因爲對於應用程序的所有更新,您必須先加載當前版本的人員,修改它(並增加版本),然後插入新行。所以真正的問題是,這種設計使得在數據庫中運行更新變得困難(例如,將屬性分配給許多用戶)。

下一個方法使用數據庫中的鏈接。您將爲每個對象指定一個新密鑰,而不是一個組合密鑰,並且您有一個replacedBy字段,其​​中包含下一個版本的密鑰。這種方法可以很容易地找到當前版本(... where replacedBy is NULL)。但是更新是一個問題,因爲您必須插入一個新行並更新現有行。

爲了解決這個問題,你可以添加返回指針(previousVersion)。這樣,您可以插入新行,然後使用返回指針更新以前的版本。

+0

這些都是進行版本控制的好方法,事實上我們目前在第一個答案中做了你的建議,但正如我在問題中提到的那樣,這很慢。例如,查詢得到每個人的姓名(截至昨天)(不是最新的版本)將涉及選擇昨天創建的<(最新版本),然後使用這些版本查找對象鍵以獲取名稱。從經驗來看,這很慢。 – Dave

+0

+1 - 對於大量嚴重版本化的數據,如果您想使用RDBMS,性能可能會成爲一項挑戰。你只需要調整它像瘋了一樣,使用水平分區,並指望忍者DBA技巧來達到你的性能目標。 –

+0

@Dave:我建議你發佈一個完整的查詢例子,涉及的表格,以及數據庫的名稱/版本,以便我們可以瞭解我們是否可以改進某些內容。 –