这个“软删除”有问题吗?使用 EAV 表的解决方案?
我读过一些有关仅在表中设置 deleted_at
字段来表示行已被删除的丑陋一面的信息。
即
http://richarddingwall.name/2009/11/20/ the-trouble-with-soft-delete/
从要删除的表中取出一行并将其转换到某些 EAV 表中是否存在任何潜在问题?
例如。
假设我有两个表 deleted
和 deleted_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. |
+----+--------+-------------+-------------------------------+
我立即看到了一些事情。
- 您需要使用应用程序逻辑 进行数据透视(Ruby、PHP、Python、 等等)
- 桌子可能会变得很大 因为我使用
blob
来处理 行值的未知大小
您是否发现这种类型的软删除存在任何其他明显的问题?
I've read some information about the ugly side of just setting a deleted_at
field in your tables to signify a row has been deleted.
Namely
http://richarddingwall.name/2009/11/20/the-trouble-with-soft-delete/
Are there any potential problems with taking a row from a table you want to delete and pivoting it into some EAV tables?
For instance.
Lets Say I have two tables deleted
and deleted_row
respectively described as follows.
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 | |
+--------+--------------+------+-----+---------+----------------+
Now when you wanted to delete a row from any table you would delete it from the table then insert it into these tables as such.
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. |
+----+--------+-------------+-------------------------------+
A few things I see off the bat.
- You'll need to use application logic
to do the pivot (Ruby, PHP, Python,
etc) - The table could grow pretty big
because I'm usingblob
to handle
the unknown size of the row value
Do you see any other glaring problems with this type of soft delete?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么不使用存档表来镜像您的表呢?
然后只需在表上添加 on-delete-triggers 即可在删除之前将当前行插入镜像表中?这将为您提供非常简单且非常高性能的解决方案。
您实际上可以使用数据字典生成表和触发器代码。
请注意,我可能不想在存档表中的原始主键 (col_1) 上有唯一索引,因为如果您使用自然键,您实际上可能最终会随着时间的推移删除同一行两次。除非您计划在应用程序中连接存档表(用于撤消目的),否则您可以完全删除索引。另外,我添加了删除时间(deleted_dtm)和一个可用于删除已删除(呵呵)行的代理键。
您还可以考虑对deleted_dtm 上的存档表进行范围分区。这使得从表中清除数据变得非常容易。
Why not mirror your tables with archive tables?
And then simply add on-delete-triggers on your tables that inserts the current row in the mirrored table before the deletion? That would provide you with dead-simple and very performant solution.
You could actually generate the tables and trigger code using the data dictionary.
Note that I might not want to have a unique index on the original primary key (col_1) in the archive table, because you may actually end up deleting the same row twice over time if you are using natural keys. Unless you plan to hook up the archive tables in your application (for undo purposes) you can drop the index entirely. Also, I added the time of delete (deleted_dtm) and a surrogate key that can be used to delete the deleted (hehe) rows.
You may also consider range partitioning the archive table on deleted_dtm. This makes it pretty much effortless to purge data from the tables.