小编典典

使用EAV表的“软删除”解决方案是否存在问题?

sql

我已经阅读了一些有关仅deleted_at在表中设置一个字段以表示某行已被删除的丑陋方面的信息。


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. 您将需要使用应用程序逻辑来进行数据透视(Ruby,PHP,Python等)
  2. 该表可能会变得很大,因为我正在使用它blob来处理行值的未知大小

您还看到这种类型的软删除还有其他明显的问题吗?


阅读 156

收藏
2021-04-15

共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上的存档表进行分区分区。这使得从表中清除数据几乎毫不费力。

2021-04-15