2011-03-26 15 views
10

我想弄清楚如何設計我的數據庫表以允許撤銷重做。如何使用undo-redo設計SQL數據庫?

假設你有一個任務表具有以下結構:

id <int> 
title <varchar> 
memo <string> 
date_added <datetime> 
date_due <datetime> 

現在假設過了幾天,多用戶登錄功能,一些編輯已經發生;但用戶想要回到其中一個版本。

  1. 你將有一個單獨的表跟蹤的變化 - 或 - 你會盡量保持任務表中的變化(「鬼」行,因爲沒有更好的術語)?
  2. 你會跟蹤所有的列還是隻是每次更改的列?

如果有問題,我使用MySQL。此外,如果它很重要,我希望能夠顯示歷史(ala Photoshop)並允許用戶切換到任何版本。

獎金的問題:你是否保存整個memo細胞上的改變,或者你會嘗試只保存增量?我想問的原因是因爲memo單元格可能很大,每個修訂版只能更改一個單詞或字符。當然,保存三角洲將需要解析,但如果不經常期望撤銷,那麼節省空間而不是處理時間會更好嗎?

謝謝你的幫助。

+1

在這裏也有類似的問題。看看[我的答案](http://stackoverflow.com/questions/5408828/are-there-problems-with-this-soft-delete-solution-using-eav-tables/5410359#5410359) – Ronnis 2011-03-26 23:21:04

回答

6

我會爲您的任務表創建一個歷史表。與任務相同的結構+名爲previousId的新字段。這將保存以前的更改ID,因此您可以回顧不同的更改(撤消/重做)。

爲什麼一個新的歷史表?出於一個簡單的原因:不要將任務表中的任務重載到它沒有設計的東西上。

至於空間,在歷史中,而不是一個備忘錄,使用二進制格式,並壓縮你想存儲的文本的內容。不要嘗試檢測更改。你會遇到一個bug的代碼,這將導致挫折和浪費時間......

優化: 更妙的是,你可以只保留三列歷史表: 1.任務id(外鍵任務) 2 。data - 一個二進制字段。在保存到歷史表之前,創建一個只保存已更改字段的XML字符串。 3. previousId(將有助於維護變化的隊列,並允許導航來回)

至於數據字段,創建一個XML字符串是這樣的:

<task> 
    <title>Title was changed</title> 
    <date_added>2011-03-26 01:29:22<date_added> 
</task> 

這基本上會告訴你,這時候您只更改了標題和date_added字段。

構建XML字符串後,只需將其壓縮並存儲到歷史記錄表的數據字段中即可。

XML也將提供靈活性。如果您在任務表中添加/刪除字段,則不需要更新歷史記錄表。所以這樣,任務表和歷史表的結構是分離的,所以你不需要每次更新兩個表。

PS:不要忘記添加一些索引來快速瀏覽歷史表。要編入索引的字段:taskId和previousId,因爲您需要對此表進行快速查詢。

希望這會有所幫助。

+0

由壓縮方式會將您的文本大小減少至原始文本的5%。一個常見的值是10%左右,但如果你有共同的重複單詞,你會得到更好的壓縮。 – Adi 2011-03-30 20:33:54

+0

這很聰明,但我不確定我瞭解「3領域」的想法。當然,歷史表中的每條記錄都必須有自己的ID字段(autoincrement),任務記錄ID的外部鏈接以及對以前歷史記錄ID的引用(如果適用)(即具有相同的任務記錄ID)...或者有沒有理解我? – 2014-08-18 17:49:37

+0

@mikerodent我認爲你有這個想法,我們需要2個鍵:一個用於任務表(taskId),一個用於歷史表(previousId)以及已更改的有效負載(數據),以便您能夠瀏覽歷史記錄在taskId和previousId字段上,並且還能夠訪問已更改的數據並在需要時進行恢復。 – Adi 2014-09-04 11:08:19

4

當我用SQL做類似類型的東西,我總是用第二個表修訂歷史記錄。這可以防止您的主表隨版本變得過大。理由是,檢索當前記錄幾乎是100%,查看歷史記錄和回滾(撤消)是非常罕見的。

如果你只有一個單一的撤消或歷史,然後在表跟蹤可能是罰款。

無論你是想保存增量或整個單元取決於預期的增長/使用。如果您很容易創建管理增量的邏輯,那將爲您節省空間。如果事情真的不創造新的版本的時候,我不會與啓動,(申請YAGNI)

2

您可能要壓縮在三角形形式修改,但你仍然應該有當前版本完全進行快速檢索。

但是,較舊的到較新的增量需要大量的處理,除非您有一些非delta的基礎。較老的增量需要每次改變時重新處理。因此,德爾塔通常不會爲您帶來諸多好處,但會帶來更大的複雜性。

上次我檢查,這是幾年前,MediaWiki,維基百科背後的軟件,存儲全文並提供了一些手段用gzip壓縮舊的版本,以節省空間和刪除修改/頁專用表archive

他們的網站上有一個ER diagram of their database layout,你可能會發現有用。