2012-02-06 15 views
4

需要跟蹤對數據庫中的對象所做的更改。什麼是一個很好的解決方案來存儲對象的變化歷史?

微不足道的實現是獲取鏡像表,通過觸發器將數據插入到數據庫中或應用程序內部,但影響性能和隨着時間的推移鏡像數據庫變得巨大並且在原始表必須是改變(鏡像表需要反映這種改變)。

因爲我最大的要求是對數據庫和應用程序性能的影響最小,所以我當前的首選是將更改轉儲到udp上的syslog-ng中,並將它們存儲在純文本文件中。

畢竟changelog不會被頻繁訪問,所以甚至可以隨着時間的推移將其歸檔。但顯然這樣的設置實際訪問數據是相當棘手的。

所以我想我的問題是 - 是否有一個系統,至少部分適應我的需求?完美的配合將是UDP訪問的無模式附加數據庫系統,可自動存檔數據(或至少需要最少量的配置)或插入性能降低速度很慢。 MongoDB的? CouchDB的? YourDB?

+0

保存爲序列化對象或json的更改(增量更新)數組可能也可以在數組合並以查看當前合併的更改。 – 2012-02-06 17:42:10

+0

是的,這就是我打算做的,問題是要使用什麼存儲,因此很容易維護它並對其進行時間片分割。 – keymone 2012-02-28 13:20:10

+0

如果問題是存儲,您可以將其存儲在任何地方,包括文件,數據庫中的字段或持久性緩存。這是你的電話。 – 2012-02-29 11:06:41

回答

2

那麼,有很多方法可以解決這個問題。我對MongoDB最爲熟悉,因此會朝這個方向傾斜。總的來說,我認爲它會滿足你對性能的需求,並且使用副本集和從奴隸讀取的內容可能是需要採取的方法。然而,該版本是不是建立在你可以看到一個辦法與Mongoid ::版本這裏版本:

Mongoid::Versioning - how to check previous versions?

你提到的可能有更好的原生支持的其他解決方案,但我不能說那。希望這至少會給你一些關於MongoDB方面的指示。

+0

我如何解決歸檔問題?不會將數據從一個集合移動到另一個集合,以便寫入(插入)?另外我正在尋找更多的類似日誌的解決方案,並且mongodb似乎提供了太多的功能,我不需要這種情況。 – keymone 2012-02-21 11:12:23

0

SQLite呢?每個數據庫都是一個自包含的文件,您可以在歸檔時輕鬆進行重命名和移動。如果文件被重命名或自動移動,則在下一次插入時創建其他文件。

關於SQLite的唯一問題是併發寫入,它需要阻止寫入文件。它每秒可以處理大約60個事務,但您可以在一個事務中執行數千次插入(請參閱doc)。

+0

這是個好主意,但不幸的是,sqlite不是無模式的。模型發生變化,我不想花太多時間維護版本/更新日誌系統。 – keymone 2012-02-22 16:39:48

1

看一看mongoid history

它跟蹤像的歷史變遷什麼,何時,由何人用版本一起。它也提供了配置選項

1

RavenDB有這個功能原生的(但可能是太年輕的的NoSQL數據庫的生產需求 - 由你當然)

http://ravendb.net/docs/server/bundles/versioning

http://www.slideshare.net/jwoglamott/battle-of-nosql-stars-amazons-sdb-vs-mongodb-vs-couchdb-vs-ravendb

如果您想要去MongoDB,有兩種實施策略建議在這thread

Strategy 1: embed history不會影響你的寫性能如果您調整代碼以避免在不必要時返回歷史記錄,則可以閱讀並閱讀,但是您對一個文檔有16Mb的限制(可能會阻止您或不會)。 Strategy 2: write history to separate collection需要(顯然)兩個操作。我同意在那裏說這些(或組合)是MongoDB中可用的策略。

CouchDB在內部使用了MVCC方法(並且您可以像建議的here一樣利用它),但在SO中這種方法是debated。有一個關於this topic的問題,並且所提出的解決方案與上面介紹的MongoDB的嵌入式策略類似(因此您應該選擇一個您所提供的)。

1

對於簡單的目的(MySQL的!),只是做了後,你想保持的記錄表UPDATE觸發器。

例如,對於表汽車行駛字段

carId(主鍵) 顏色 製造商 模型

創建表 'cars_history'(或等於名)與字段: carId 字段 OLD_VALUE new_value

並添加一個像這樣的AFTER UPDATE觸發器:

delimiter // 

CREATE TRIGGER trigger_changes 
AFTER UPDATE ON cars 
FOR EACH ROW 
BEGIN 
IF OLD.manufacturer <> NEW.manufacturer THEN 
    INSERT INTO cars_history 
    (carId, field, old_value, new_value) 
    VALUES 
    (OLD.carId, 'manufacturer', OLD.manufacturer, NEW.manufacturer); 
ELSE IF OLD.color <> NEW.color THEN 
    ... 
END IF; 
END;// 
delimiter ; 

未經測試,因此可能含有語法錯誤:)希望幫助呢!

相關問題