2011-03-23 87 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