7

数据库表设置外键VS不设置外键,哪个更好?

 3 years ago
source link: https://segmentfault.com/a/1190000040048202
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

必须设置外键VS不要设置外键的争论

数据库表到底要不要设置外键约束,一直具有非常大的争议。我认为完全没有必要非黑即白,存在即合理。

这两种争论的产生根源在于它们都有各自的使用场景和理由,并不是纯理论的空想。

所以最好的方式是根据项目类型、业务场景进行决策,甚至可以两种方式混合使用,才是最好的。

例如对于证券、股票、保险、银行等金融行业,应该设置外键保证数据的一致性更加重要,而对于互联网行行业的衣食住行则可以采用无外键设计,追求更高的性能和更快的迭代速度。

数据库表不设置外键会有哪些问题?

  1. 数据完整性问题

    缺少外键最主要的问题是数据库不能强制进行完整性约束检查,如果在业务程序中没有正确处理,则可能会导致数据不一致。例如银行、证券、保险等金融行业,每一个账户的金额都不能出错,一旦出现数据不一致就是灾难性的问题。

  2. 表之间的关系不清晰

    无法直接通过外键来梳理表之间的关联关系,对于新接触项目的人员会十分困难。对于一些大型的复杂项目,没有外键约束,梳理不清表之间的关系也是一种灾难。

如果数据库表不设置外键会有哪些好处?

  1. 对性能具有较大的提升

    在表上拥有活动的外键可以提高数据质量,但会影响插入、更新和删除操作的性能。在这些任务之前,数据库需要检查它是否违反数据完整性。这就是为什么一些架构师和DBA完全放弃外键的原因。数据仓库和分析数据库尤其如此,这些数据仓库和分析数据库不以交易方式(一次一行)处理数据,而是批量处理数据。性能是数据仓库和商业智能的一切。

  2. 旧数据和脏数据更加利于存储

    许多数据库在设计时需要存储来自旧数据库和遗留数据,这些数据可能对数据质量和完整性没有那么严格。为了能够容纳旧的脏数据,架构师可以选择(1)清理和转换遗留数据,这要耗费很大的人力成本。(2)放弃在数据库级别上强制执行参照完整性。一些打包的ERP和CRM应用程序也使用这种方法。

  3. 全表重新加载的时候会更加方便

    一些数据库,如数据仓库,分段或接口数据库,需要经常从外部重新加载数据。这会导致重新加载时数据不一致(在父表为空的情况下,子表可能已满载)。这可以通过在重新加载时禁用外键来绕过。然而,这引入了额外的逻辑和复杂性以及另一个失败点。如上所述,对性能有负面影响。通常,成本大于收益,开发人员不用担心外键。

  4. 采用更高层次的框架来解决约束问题

    一些应用程序使用编程框架,在物理数据库之上创建另一个逻辑层。开发人员不使用插入或更新语句来修改数据,而使用API或者框架在后台执行所有操作。ORM(对象关系映射)框架或Ruby on Rails框架就是这种情况。这些工具负责参照完整性,并与RDBMS一起创建更高级别的数据库引擎。这些框架可以自己创建数据库表,而不总是创建外键。使用这些工具的开发人员很少会干扰自动生成的模式,并且不需要外键。

  5. 鼓励创新,对更改开放

    这种观点认为,增加外键会降低设计者的优化欲望,因为修改过程较为麻烦,所以限制了设计人员的创新思维。

  6. 架构师或设计师的懒惰心理得到满足

    创建表的时候只要自己心里知道他们的关联关系就好了,不需要做那么多额外的设置,并且一旦需要调整设计就会十分繁琐,所以有很多设计人员就不再设置外键了。

  7. 保持模型的复杂度,维护个人地位

    每一个设计者都希望自己是不可替代的,设计出复杂的数据模型,而不设置外键约束,这样就只有自己清楚他们的关联关系,只有自己能够进一步维护,出了问题也只有自己最清楚,从而可以保持自己的竞争力。这种想法看似邪恶,但是这样做的确实大有人在。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK