执行逻辑/软删除记录(即设置一个表明记录被删除的标志)而不是实际或物理删除记录的优点是什么?
这是常见做法吗?
这样安全吗?
我参与的项目的首席开发人员表示依靠级联删除相关行是不好的做法.
我不知道这有多糟糕,但我想知道你对它是否/为什么的看法.
说我有两张桌子,user而且comment.它们的表定义如下所示:
CREATE TABLE `user` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`username` VARCHAR(255) NOT NULL,
`deleted` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY (`username`)
) ENGINE=InnoDB;Run Code Online (Sandbox Code Playgroud)
CREATE TABLE `comment` (
`id` INTEGER NOT NULL AUTO_INCREMENT,
`user_id` INTEGER NOT NULL,
`comment` TEXT,
`deleted` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
CONSTRAINT `fk_comment_user_id` FOREIGN KEY (`user_id`)
REFERENCES `user` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB;Run Code Online (Sandbox Code Playgroud)
这非常适合强制执行数据完整性以及所有这些,但我希望能够"删除"用户并保留其所有注释(供参考).
为此,我已添加,deleted以便我可以SET deleted = 1 …
背景
我有很多不同的"东西"(特定领域的项目/实体/主题),对于"东西"所有者(人类)是可见的.业主将用数字识别他们的"事物".而是显示一个大的"随机"数字,我想向他们展示一个对人类来说更容易的小数字(最好是从1开始的序列).业主们很自在地谈论"我的foo 37"和"她的酒吧128"."序列"可能有间隙,但附加的数字必须在"事物"的生命周期内保持不变.所以我需要一种方法来生成"thing"+所有者特定的id(当前称为"visible id").
"东西"+所有者组合的数量是10k +的规模.目前新的"东西"不能动态生成,但业主可以.
每个所有者的一个"事物"实例的数量相对较小,每个所有者约为几十个,但是没有可以从业务规则中获得的硬性上限.经常创建和删除新的"事物"实例.
考虑的选择
我在一个SO问题Oracle Partitioned Sequence中找到了一个很好的讨论,它解决了我所遇到的几乎相同的问题.
到目前为止,我已经考虑了以下选项:
max(visible_id) + 1但我们会遇到正常的并发问题,所以这是不行的.题
是否有其他方法可以解决此问题,还是应该开始动态创建序列?如果序列是答案,请详细说明可能存在的陷阱(如DDL中的隐式提交).
我对Oracle 11gR2和12c解决方案都感兴趣(如果它们不同的话).
伪代码来说明问题
create table foo (
id number primary key -- the key for computers
,owner_id number
,visible_id number -- the key for humans
,data_ varchar2(20)
);
create constraint foo_u1 unique foo(owner_id, visible_id);
-- primary key sequence
create sequence foo_id_seq;
insert into foo values(
foo_id_seq.nextval …Run Code Online (Sandbox Code Playgroud) 是否可以在MySQL中使一行无效?那么这一行不再用于查询结果了?我的客户希望保留已删除的成员存在于数据库中,但我不想编辑所有查询以检查成员是否被删除.
或者有一种简单的方法可以将整个行数据移动到另一个"非活动"表中吗?
建议阅读
我怎么在这里结束
我非常相信,在制作软件时,任何事情都要事先做好,以便以后最大限度地减少工作量.因此,我试图确保在接近我的数据库架构和维护时,它可以保持关系完整性,而不是过时或过于复杂.
在查看典型的删除方法CASCADE时,这会让人有些不寒而栗.哎呀,对我目前的情况来说有点过头了.我想保持关系图的完整性,但我不想删除每个图只是因为链的一部分是无关紧要的.因此,我选择采用软删除的方式,以确保数据完整性保留,同时记录可以从相关性中删除.我通过在数据库中的每个叹息表中添加"DateDeleted"字段来完成此操作.
转折点
然而,这显然开始增加太多的复杂性并且值得付出努力.我将逻辑放在不应该去的地方,并且不想在整个应用程序中使这些不良做法永久化.简而言之,我将回滚此实现.
在查找天气或不是人们喜欢软删除时,似乎有很多支持它.事实上,链接的"相似"帖子顶部是"我总是软删除"的最高投票回答.此外,那里和SO周围的大多数答案包括某种"isDeleted"或"isActive"类型的方法.
新的实施理念
链接的"好文章"涵盖了我实际遇到的一些问题.它还提出了一种替代软删除的方法,我从最佳实践的角度出发.建议使用"存档数据库",我在查看软删除时实际考虑过.我决定反对它的原因是因为我之前提到的有关CASCADE删除的观点.我很谨慎从数据库中删除整个图表,因为链的一部分被删除了.但是,这个图表至少可以从档案中保留,所以我不确定它真的那么糟糕.
十字路口
那么,我应该继续添加逻辑,逻辑,逻辑......逻辑吗?或者,我是否应该考虑创建归档数据库,其中大多数逻辑只是位于一个非常复杂的图形管理类中来存储/恢复关系对象图?后者似乎对我来说是最好的做法.
我的数据库中有一个包含100列的表.我想创建一个触发器来审核每个更新操作的修改.
我能想到的是为所有列创建update子句,但它们都是类似的脚本.那么有没有优雅的方法呢?
sql ×4
mysql ×3
soft-delete ×2
audit ×1
cascade ×1
constraints ×1
database ×1
foreign-keys ×1
oracle ×1
php ×1
sql-server ×1