数据库表设置外键VS不设置外键,哪个更好()
必须设置外键VS不要设置外键的争论
数据库表到底要不要设置外键约束,一直具有非常大的争议。我认为完全没有必要非黑即白,存在即合理。
这两种争论的产生根源在于它们都有各自的使用场景和理由,并不是纯理论的空想。
所以最好的方式是根据项目类型、业务场景进行决策,甚至可以两种方式混合使用,才是最好的。
例如对于证券、股票、保险、银行等金融行业,应该设置外键保证数据的一致性更加重要,而对于互联网行行业的衣食住行则可以采用无外键设计,追求更高的性能和更快的迭代速度。
数据库表不设置外键会有哪些问题?
- 数据完整性问题
缺少外键最主要的问题是数据库不能强制进行完整性约束检查,如果在业务程序中没有正确处理,则可能会导致数据不一致。例如银行、证券、保险等金融行业,每一个账户的金额都不能出错,一旦出现数据不一致就是灾难性的问题。
- 表之间的关系不清晰
无法直接通过外键来梳理表之间的关联关系,对于新接触项目的人员会十分困难。对于一些大型的复杂项目,没有外键约束,梳理不清表之间的关系也是一种灾难。
- 对性能具有较大的提升
在表上拥有活动的外键可以提高数据质量,但会影响插入、更新和删除操作的性能。在这些任务之前,数据库需要检查它是否违反数据完整性。这就是为什么一些架构师和DBA完全放弃外键的原因。数据仓库和分析数据库尤其如此,这些数据仓库和分析数据库不以交易方式(一次一行)处理数据,而是批量处理数据。性能是数据仓库和商业智能的一切。
- 旧数据和脏数据更加利于存储
许多数据库在设计时需要存储来自旧数据库和遗留数据,这些数据可能对数据质量和完整性没有那么严格。为了能够容纳旧的脏数据,架构师可以选择(1)清理和转换遗留数据,这要耗费很大的人力成本。(2)放弃在数据库级别上强制执行参照完整性。一些打包的ERP和CRM应用程序也使用这种方法。
- 全表重新加载的时候会更加方便
一些数据库,如数据仓库,分段或接口数据库,需要经常从外部重新加载数据。这会导致重新加载时数据不一致(在父表为空的情况下,子表可能已满载)。这可以通过在重新加载时禁用外键来绕过。然而,这引入了额外的逻辑和复杂性以及另一个失败点。如上所述,对性能有负面影响。通常,成本大于收益,开发人员不用担心外键。
- 采用更高层次的框架来解决约束问题
一些应用程序使用编程框架,在物理数据库之上创建另一个逻辑层。开发人员不使用插入或更新语句来修改数据,而使用API或者框架在后台执行所有操作。ORM(对象关系映射)框架或Ruby on Rails框架就是这种情况。这些工具负责参照完整性,并与RDBMS一起创建更高级别的数据库引擎。这些框架可以自己创建数据库表,而不总是创建外键。使用这些工具的开发人员很少会干扰自动生成的模式,并且不需要外键。
- 鼓励创新,对更改开放
这种观点认为,增加外键会降低设计者的优化欲望,因为修改过程较为麻烦,所以限制了设计人员的创新思维。
- 架构师或设计师的懒惰心理得到满足
创建表的时候只要自己心里知道他们的关联关系就好了,不需要做那么多额外的设置,并且一旦需要调整设计就会十分繁琐,所以有很多设计人员就不再设置外键了。
- 保持模型的复杂度,维护个人地位
每一个设计者都希望自己是不可替代的,设计出复杂的数据模型,而不设置外键约束,这样就只有自己清楚他们的关联关系,只有自己能够进一步维护,出了问题也只有自己最清楚,从而可以保持自己的竞争力。这种想法看似邪恶,但是这样做的确实大有人在。
推荐阅读
- 急于表达——往往欲速则不达
- 第6.2章(设置属性)
- Docker应用:容器间通信与Mariadb数据库主从复制
- PMSJ寻平面设计师之现代(Hyundai)
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- mybatisplus如何在xml的连表查询中使用queryWrapper
- 爱琐搭配(喜欢复古、冷淡,像这种双环设计的气质耳环)
- leetcode|leetcode 92. 反转链表 II
- 下雪了,飞去你的城市拥抱你|下雪了,飞去你的城市拥抱你 | 有个直男向我表白了