当我查看RDBMS的数据库模型时,通常会惊讶地发现几乎没有约束(除了PK / FK)。例如,百分比通常存储在类型的列中int
(虽然tinyint
会更合适),并且没有CHECK
约束将值限制为0..100范围。同样在SE.SE上,建议检查约束的答案通常会收到注释,表明数据库是约束的错误位置。
当我询问不实施约束的决定时,团队成员会回答:
他们甚至都不知道自己喜欢的数据库中是否存在这样的功能。对于仅使用ORM的程序员而言,这是可以理解的,但是对于声称拥有给定RDBMS 5年以上经验的DBA而言,这是可以理解的。
或者它们在应用程序级别强制执行此类约束,并且在数据库中复制这些规则不是一个好主意,这违反了SSOT。
最近,我看到越来越多的项目甚至不使用外键。同样,我在SE.SE上看到了一些评论,这些评论表明用户不太在意引用完整性,让应用程序来处理它。
当询问团队有关不使用FK的选择时,他们说:
例如,当必须删除其他表中引用的元素时,它就是PITA。
NoSQL坚如磐石,那里没有外键。因此,我们在RDBMS中不需要它们。
就性能而言,这并不是什么大问题(上下文通常是在小型数据集上运行的小型Intranet Web应用程序,因此,实际上,即使索引也没有太大关系;没有人会介意给定查询的性能是否超过1.5 s到20毫秒)。
当我查看应用程序本身时,我系统地注意到了两种模式:
该应用程序会正确清理数据并在将其发送到数据库之前对其进行检查。例如,无法
102
通过应用程序将值存储为百分比。该应用程序假定来自数据库的所有数据都是完全有效的。就是说,如果
102
以百分比来表示,某处某处将崩溃,或者仅将其按原样显示给用户,从而导致奇怪的情况。尽管超过99%的查询是由单个应用程序完成的,但随着时间的流逝,脚本开始出现-要么在需要时手动运行脚本,要么执行cron作业。还可以手动对数据库本身执行某些数据操作。脚本和手动SQL查询都具有引入无效值的高风险。
这是我的问题:
没有关系约束而最终甚至没有外键的关系数据库建模的原因是什么?
就其价值而言,这个问题和我收到的答案(尤其是与Thomas Kilian进行的有趣的讨论)使我写了一篇有关数据库约束的结论文章。