2008-11-06 97 views
3

我們有一個體面的面向對象的應用程序。每當應用程序中的對象發生更改時,對象更改都會保存回數據庫。但是,這已經變得不太理想。什麼是存儲和搜索對象事務的最佳方式?

目前,交易存儲爲交易和一組交易LI。

事務表具有who,what,when,why,foreignKey和foreignTable的字段。前四個是不言自明的。 ForeignKey和foreignTable用於確定哪個對象已更改。

TransactionLI有時間戳,鍵,val,oldVal和一個事務ID。這基本上是一個key/value/oldValue存儲系統。

問題是,這兩個表用於應用程序中的每個對象,所以他們現在是非常大的表。將它們用於任何事情都很慢。索引只有很多幫助。

因此,我們正在考慮其他方式來做這樣的事情。我們到目前爲止考慮過的事情: - 按照時間戳之類的東西對這些表進行分片。 - 將兩個表格非規範化併合併爲一個。 - 以上兩者的組合。 - 做一些改變後的序列化每個對象的行,並將其存儲在subversion中。 - 可能是別的,但現在我想不起來。

整個問題是我們希望有一些機制來正確存儲和搜索事務數據。是的,你可以強迫關係數據庫的飼料,但實際上,它是交易數據,應該相應地存儲。

其他人在做什麼?

+0

你正在使用什麼數據庫?您可能需要在SQL 2008中調查SQL更改跟蹤。它不會跟蹤您的對象,但它會跟蹤您的數據更改並對它們進行版本控制。 – D3vtr0n 2008-12-04 02:14:23

回答

0

我從來沒有找到一個很好的結束這種類型的問題的所有解決方案。你可以嘗試的一些事情是,如果你的數據庫支持分區(或者即使它不能實現你自己的相同概念),但按對象類型分區這個日誌表,然後你可以按日期/時間或按對象ID(如果你的ID是一個數字,這很好地不知道如何guid會分區)。

這將有助於維護表的大小並將所有相關事務保持爲一個對象的單個實例。

您可以探索的一個想法是將每個字段存儲在名稱值對錶中,您可以將數據存儲爲blob(文本或二進制文件)。例如,將對象序列化到Xml並將其存儲在字段中。

這樣做的缺點是,當你的對象發生變化時,如果你使用Xml,那麼你必須考慮它是如何影響所有的歷史數據,然後有更新歷史XML結構的簡單方法,如果你使用二進制的方式,但你有更加努力的努力。

我已經成功地存儲了一個相當複雜的對象模型,它有大量的相互作用作爲blob(.net中的xml序列化程序沒有處理btw對象的關係)。我可以很容易地看到自己存儲二進制數據。將其存儲爲二進制數據的一個巨大缺點是要訪問它,如果使用像MSSQL這樣的現代數據庫,則必須使用Xml將其從數據庫中取出,才能訪問數據。

最後一個方法是分裂兩種模式,你可以定義一個差異架構(和我同時承擔更多的再一個屬性的變化),所以例如可以想象存儲這些XML:

<objectDiff> 
<field name="firstName" newValue="Josh" oldValue="joshua"/> 
<field name="lastName" newValue="Box" oldValue="boxer"/> 
</objectDiff> 

這將有助於減少行數,並且如果您使用MSSQL,則可以定義XML模式並獲得對象周圍豐富的查詢能力。您仍然可以對錶格進行分區。

喬希

0

根據您的具體應用的特性的另一種方法是保持修訂實體本身各自的表中的,加上誰,什麼,爲什麼,每次修訂時。誰,什麼時候仍然可以是外鍵。

儘管我會非常小心地使用這種方法,因爲這對於每個實體/實體類型的變化量相對較小的應用程序來說是唯一可行的。

0

如果查詢數據很重要,我會在SQL Server 2005及更高版本中使用真正的分區,如果您有企業版的SQL Server。根據當前的月份,我們有數百萬行按年份劃分爲一天 - 您可以像應用程序要求一樣細緻,最多可以有1000個分區。

或者,如果您使用SQL 2008,則可以查看過濾後的索引。

這些解決方案可讓您保留簡化結構,同時提供查詢該數據所需的性能。

明顯應該考慮拆分/存檔較舊的更改。

1

我們採取了以下做法: -

  1. 所有對象序列化(使用標準XMLSeriliser),但我們已經與序列化屬性,以便使生成的XML小得多(存儲元素作爲裝飾我們的類例如屬性和字段名稱上的元音)。如有必要,可以通過壓縮XML來進一步完成這一步。

  2. 對象庫通過SQL視圖進行訪問。該視圖前面有許多結構相同的表,但表名附有一個GUID。當上一個表達到臨界質量(預定行數)時,會生成一個新表格

  3. 我們運行一個夜間歸檔例程,它會生成新表格並相應地修改視圖,以便調用應用程序不會看到任何差異。

  4. 最後,作爲過夜例程的一部分,我們將任何不再需要的舊對象實例存檔到磁盤(然後磁帶)。

相關問題