2011-03-23 86 views
0

我讀過一些關於在表格中設置deleted_at字段的醜陋方面的信息,表示行已被刪除。使用EAV表的「軟刪除」解決方案有問題嗎?


http://richarddingwall.name/2009/11/20/the-trouble-with-soft-delete/

是否有與您要刪除的表走行,並將其旋轉到一些EAV表的任何潛在的問題?

例如,

可以說我有兩個表deleteddeleted_row分別描述如下。

mysql> describe deleted; 
    +------------+--------------+------+-----+---------+----------------+ 
    | Field  | Type   | Null | Key | Default | Extra   | 
    +------------+--------------+------+-----+---------+----------------+ 
    | id   | int(11)  | NO | PRI | NULL | auto_increment | 
    | tablename | varchar(255) | YES |  | NULL |    | 
    | deleted_at | timestamp | YES |  | NULL |    | 
    +------------+--------------+------+-----+---------+----------------+ 

    mysql> describe deleted_rows; 
    +--------+--------------+------+-----+---------+----------------+ 
    | Field | Type   | Null | Key | Default | Extra   | 
    +--------+--------------+------+-----+---------+----------------+ 
    | id  | int(11)  | NO | PRI | NULL | auto_increment | 
    | entity | int(11)  | YES | MUL | NULL |    | 
    | name | varchar(255) | YES |  | NULL |    | 
    | value | blob   | YES |  | NULL |    | 
    +--------+--------------+------+-----+---------+----------------+ 

現在,當你想從任何表中刪除一行,你會從表中刪除,然後將其插入這些表本身。

deleted 
    +----+-----------+---------------------+ 
    | id | tablename | deleted_at   | 
    +----+-----------+---------------------+ 
    | 1 | products | 2011-03-23 00:00:00 | 
    +----+-----------+---------------------+ 

    deleted_row 
    +----+--------+-------------+-------------------------------+ 
    | id | entity | name  | value       | 
    +----+--------+-------------+-------------------------------+ 
    | 1 |  1 | Title  | A Great Product    | 
    | 2 |  1 | Price  | 55.00       | 
    | 3 |  1 | Description | You guessed it... it's great. | 
    +----+--------+-------------+-------------------------------+ 

我看到了一些東西。

  1. 你需要使用的應用程序邏輯 做樞軸(紅寶石,PHP,Python和 等)
  2. 表可能增長相當大的 因爲我使用blob處理 未知行值的大小

您是否發現這種類型的軟刪除有其他明顯的問題?

+0

我沒有太多的意見對是否是好事還是壞事(至少在沒有很多關於你的要求的更多細節),但根據你的數據庫服務器上你也許可以做到這一點與觸發器和保持邏輯超出數據庫。 – 2011-03-23 16:58:44

+0

湯姆,我還沒有偶然發現如何做觸發器,你知道任何好的例子嗎? – 2011-03-23 17:07:14

+0

對不起,我的頭不在。這也很大程度上取決於你正在使用的數據庫。 – 2011-03-23 17:13:40

回答

1

爲什麼不存檔表反映您的表?

create table mytable(
    col_1 int 
    ,col_2 varchar(100) 
    ,col_3 date 
    ,primary key(col_1) 
) 

create table mytable_deleted(
    delete_id int  not null auto_increment 
    ,delete_dtm datetime not null 
-- All of the original columns 
    ,col_1 int 
    ,col_2 varchar(100) 
    ,col_3 date 
    ,index(col_1) 
    ,primary key(delete_id) 
) 

然後,只需在您的表上添加on-delete-triggers,在刪除前在鏡像表中插入當前行?這將爲您提供簡單而非常高效的解決方案。

您實際上可以使用數據字典生成表並觸發代碼。

請注意,我可能不希望在歸檔表中的原始主鍵(col_1)上擁有唯一的索引,因爲如果您使用自然鍵,則實際上最終可能會隨着時間的推移刪除同一行兩次。除非您計劃在應用程序中連接歸檔表(爲了撤消目的),否則可以完全刪除索引。此外,我添加了刪除時間(deleted_dtm)和可用於刪除已刪除(hehe)行的代理鍵。

您也可以考慮範圍上deleted_dtm分區存檔表。這使得清除表格中的數據變得非常容易。

+0

我希望避免手動創建表格,但是我可以看到這種方法的優點,因爲它不需要任何應用程序邏輯。 – 2011-03-23 21:05:01

+0

@ nvoyageur,你在用什麼數據庫?你熟悉那個dbms的字典表嗎?您可以創建一組啓用/禁用歸檔功能的過程或腳本,因此您不必手動創建表格。是的,讓數據庫在後臺自動執行此操作的能力非常強大! – Ronnis 2011-03-23 21:09:39

+0

MySQL是我使用的主要數據庫(在Postgres中有幾個項目)。我還沒有任何字典表的經驗。一些東西讓我看看。 – 2011-03-23 21:31:01