首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现软删除?

如何实现软删除?
EN

Database Administration用户
提问于 2012-02-15 18:51:17
回答 2查看 6.8K关注 0票数 7

您在数据库中实现软删除的方法是什么?

理想情况下,解决方案将允许

  • 在大型桌子上的良好性能
  • 考虑到关系
  • 考虑到唯一的键
  • 用户应该能够找到并恢复已删除的项目。

谢谢!

EN

回答 2

Database Administration用户

回答已采纳

发布于 2012-02-15 19:04:14

我有几种方法可以做到这一点:

  • 您可以有一个“删除”指示符,在删除记录时将其设置为"Y“。非常简单,但它将删除数据和活动数据保留在相同的表中,如果存在大量活动,这可能会导致性能问题。还原记录就像更改指示符一样简单。
  • 您可以有一个表,该表反映要从其中删除的表的结构,当从主表中删除记录时,将该记录插入"deleted_data“表中。这允许您将已删除的数据移动到单独的表中,以使主表具有更好的潜在性能,但是搜索两个表中的数据可能会使事情变得更加复杂,并且保持数据结构保持同步(当它们发生变化时)也需要做更多的工作。在这种情况下,恢复数据将涉及从“已删除”表中删除记录并将其插入主表中。

在这两种情况下,您可能都希望找到任何子记录并将其标记为已删除。我想您可以使用触发器或代码来完成此操作。

票数 7
EN

Database Administration用户

发布于 2012-02-15 19:05:12

对于本例,让我们使用如下所示的表:

代码语言:javascript
复制
CREATE TABLE parent_data
(
    id int not null auto_increment,
    ...
    PRIMARY KEY (id)
);

如果要执行软删除,请创建表,该表保存要删除的行的id。也许是这样的:

代码语言:javascript
复制
CREATE TABLE deleted_parent_data SELECT id FROM parent_data WHERE 1=2;
ALTER TABLE deleted_parent_data ADD PRIMARY KEY (id);

假设要删除行10、20、30、40、50。只需运行这个:

代码语言:javascript
复制
INSERT IGNORE INTO deleted_parent_data VALUES (10),(20),(30),(40),(50);

要查看有效数据,始终必须执行内部连接。

代码语言:javascript
复制
SELECT A.* FROM parent_data A
INNER JOIN deleted_parent_data B
USING (id) WHERE B.id IS NULL;

查看已删除的行将非常快。

代码语言:javascript
复制
SELECT B.* FROM deleted_parent_data A
LEFT JOIN parent_data B
USING (id) WHERE B.id IS NOT NULL;

要在parent_data中恢复第20行,只需运行

代码语言:javascript
复制
DELETE FROM deleted_parent_data WHERE id = 20;

若要永久删除行20和50,请运行两个不能回滚的步骤:

代码语言:javascript
复制
DELETE B.* FROM
(SELECT id FROM deleted_parent_data
WHERE id IN (20,50)) A
LEFT JOIN parent_data B
USING (id) WHERE B.id IS NOT NULL;
DELETE FROM deleted_parent_data WHERE id IN (20,50);

如果表child_data中有子记录,则必须有一个单独的delete_child_data表,并以类似的方式管理itin。也许这张桌子看起来是这样的:

代码语言:javascript
复制
CREATE TABLE deleted_child_table SELECT parent_id,id WHERE 1=2;
ALTER TABLE deleted_child_table ADD PRIMARY KEY (id);
ALTER TABLE deleted_child_table ADD UNIQUE KEY (parent_id,id);

您可能可以在deleted_parent_table和deleted_child_table之间使用触发器或外键约束,并附带所有ON DELETE CASCADE的提示和提示。这样,deleted_parent_table中的行的永久删除应该级联到deleted_child_table。

票数 3
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/13134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档