2010-11-26 77 views
2

在處理內容管理系統時,我遇到了一些問題。回到我的數據模型,我注意到一些可能隨着時間流逝而變得更普遍的問題。主鍵,UUID,RecordKey表,哦我的

也就是說,我想維護用戶對記錄修改的審計跟蹤(更改日誌)(甚至會記錄用戶記錄修改)。由於包含了任意數量的模塊,因此我不能在我的主鍵中使用按表自動增量字段,因爲在試圖將其鍵保存在單個表中時不可避免地會導致衝突。

審計線索將保持user_idrecord_idtimestampaction的記錄(INSERT/UPDATE/DELETE),以及archive(舊記錄的序列化副本)

我已經考慮了幾個可能的解決方案該問題,例如在應用程序邏輯中生成主鍵(以確保跨數據庫平臺兼容性)。

我考慮過的另一個選項(我相信即使考慮這種方法,共識也會是負面的)創建一個RecordKey表,以維護一個全局自動遞增的密鑰。不過,我相信有更好的方法來實現這一點。

最終,我很想知道在嘗試執行此操作時應考慮哪些選項。例如,我打算允許(至少啓動)MySQL和SQLite3存儲的選項,但我擔心每個數據庫如何處理UUID

編輯使我的問題不太模糊:將使用全局ID是我的問題的推薦解決方案?如果是這樣,使用128位UUID(應用程序或數據庫生成)我可以在我的表設計中做什麼,這將有助於最大限度地提高查詢效率?

回答

3

好吧,你碰到了一堵磚牆。而且你意識到實際上db設計有問題。而且你將來會多次打這個磚牆。而你的未來並不明朗。你想改變這一點。好。

但是你還沒有做的是,確定這是什麼的真正原因。在這樣做之前,你無法擺脫可預測的未來。如果你做得很好,那就不會有磚牆,至少不是這個特殊的磚牆。

首先,你去了所有表上的所有列的記錄卡,以強制唯一性,但沒有真正理解標識符和用於自然地查找數據的鍵。那是由牆壁製成的磚。對於需要考慮的問題,這是一種不被看好的膝蓋反應。這是你將不得不重新訪問。

  1. 不要再犯同樣的錯誤。重擊的GUID或UUID的,或32字節Id IOT列,以解決您NUMERIC(10,0) Id IOT列將不會做任何事情,除了使DB胖多了,和所有訪問,特別是加入慢得多。牆壁將由混凝土塊製成,每隔一小時都會打到你。

  2. 回去看看錶,以期設計出他們是表,在數據庫中。這意味着您的出發點是否Surrrogate Keys,否Id iot列。完成後,您將有非常少的Id列。不是零,不是全部表格,但很少。因此你的牆上只有很少的磚塊。我最近已經發布需要一套詳細的步驟,所以請參考:

    Link to Answer re Identifiers

  3. 什麼是具有含所有表的審計「記載」一個審計表的理由?你喜歡遇見磚牆嗎?你想要在一個文件中插入熱點的db的併發性和速度瓶頸?

    審計要求已經在dbs實施了40多年,所以您的用戶有其他一些要求不會更改的機率不是很高。也可以正確地做。審計表唯一正確的方法(對於Rdb)是每個可審計的實際表有一個審計表。 PK將是原始表格PK加上日期時間(複合鍵在現代數據庫中是正常的)。其他列將是UserId和Action。該行本身將是之前的圖像(新圖像是主表中的單個當前行)。使用完全相同的列名稱。不要把它裝進一根巨大的繩子裏。

    如果你不需要數據(圖像之前),那麼停止記錄它。無緣無故地錄製所有音量是非常愚蠢的。恢復可以從備份中獲得。

  4. 是,一個單一的RecordKey表是一個怪物。另一個保證數據庫單線程的方法。

還沒有反應過來我的帖子,我已經可以從你的意見,你有做錯事,並保持你的磚牆完整地保留所有的「正確」的原因看。我試圖幫助你消滅它們。在回答之前仔細考慮幾天。

2

如何保持所有record_id本地到每個表,並添加另一列table_name(審計表),以使組合鍵?

這樣,您也可以通過table_name(這對於任意UUID或序列號來說很棘手)輕鬆過濾您的審覈日誌。因此,即使您不使用此解決方案,也可以考慮爲了稍後查詢日誌而添加table_name列。

爲了將所有表中的record_id合併到同一列中,您仍然需要強制所有表的ID都使用相同的數據類型(但好像您打算這麼做)。

+0

謝謝** Thilo **;這是我所做的一個考慮,添加`table_name`並按照你所描述的使用它。當然,爲了完善審計線索,將它作爲附加數據添加可能會有所幫助。但請考慮這種情況;用戶將博客模塊卸載爲更加全面的博客模塊,但這兩個博客模塊都對錶使用相同的命名方案。可能會出現衝突,因爲我不打算級聯刪除審計記錄。這就是爲什麼我傾向於支持某種全球關鍵實施。 – Dan 2010-11-26 05:02:28

+1

您描述的衝突不會成爲問題,因爲您仍然有時間戳知道哪個模塊使用哪個表的時間。唯一的問題是有人同時安裝了兩個模塊,但這似乎是不可能的,因爲數據庫也喜歡不同的表名。事實上,使用上述方法的審計表與數據庫自己的元數據表的工作方式非常相似。 – Thilo 2010-11-26 05:21:08

+0

謝謝** Thilo **;你對安裝是正確的。模塊安裝檢查現有表格,路徑等,並根據嚴重程度通知用戶,或者完全失敗。 – Dan 2010-11-26 08:18:13

2

更強大的方案是創建一個審計表,它反映每個表的結構,而不是將所有審計線索放到一個位置。 「影子」表模型使查詢審計線索變得更加容易。