CREATE TABLE parent_data
(
id int not null auto_increment,
...
PRIMARY KEY (id)
);
如果要进行软删除,请创建包含要删除的行的 id 的表。也许是这样的:
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 行。运行这个:
INSERT IGNORE INTO deleted_parent_data VALUES (10),(20),(30),(40),(50);
您总是必须执行 INNER JOIN 才能查看有效数据
SELECT A.* FROM parent_data A
INNER JOIN deleted_parent_data B
USING (id) WHERE B.id IS NULL;
查看已删除的行会非常快
SELECT B.* FROM deleted_parent_data A
LEFT JOIN parent_data B
USING (id) WHERE B.id IS NOT NULL;
要恢复 parent_data 中的第 20 行,只需运行
DELETE FROM deleted_parent_data WHERE id = 20;
要永久删除第 20 行和第 50 行,请运行两个无法回滚的步骤:
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);
我可以想到几种方法来做到这一点:
您可以有一个“已删除”指示器,在删除记录时将其设置为“Y”。非常简单,但它会将已删除和活动的数据留在同一个表中,如果有很多活动,这可能会导致性能问题。恢复记录就像更改指标一样简单。
您可以有一个表,该表反映了您要从中删除的表的结构,并且当您从主表中删除一条记录时,将该记录插入“deleted_data”表中。这允许您将已删除的数据移动到单独的表中,以为主表提供更好的潜在性能,但是搜索任一表中的数据可能会使事情变得更加复杂,并且保持数据结构同步(当它们发生变化时)也有点更多的工作要做。在这种情况下,恢复数据将涉及从“已删除”表中删除记录并将其插入回主表中。
在这两种情况下,您可能都希望找到任何子记录并将它们标记为已删除。我想你可以用触发器或代码来做到这一点。
对于这个例子,让我们使用一个看起来像这样的表“
如果要进行软删除,请创建包含要删除的行的 id 的表。也许是这样的:
假设您要删除第 10、20、30、40、50 行。运行这个:
您总是必须执行 INNER JOIN 才能查看有效数据
查看已删除的行会非常快
要恢复 parent_data 中的第 20 行,只需运行
要永久删除第 20 行和第 50 行,请运行两个无法回滚的步骤:
如果表 child_data 中有子记录,则必须有一个单独的 delete_child_data 表并以类似的方式管理它。也许表如下所示:
您可能可以在deleted_parent_table 和deleted_child_table 之间使用触发器或FOREIGN KEY 约束以及所有的
ON DELETE CASCADE
花里胡哨。这样,deleted_parent_table 中行的永久删除应该级联到 deleted_child_table。