我的同事提到我们的客户端DBA建议删除项目Oracle DB模式中的所有外键约束。最初我不同意这个决定。我是开发人员而不是DBA。后来才意识到这个决定背后可能有一些原因。所以我正在尝试获得这个决定的利弊。
项目信息:
这是我的利弊清单(如果我错了请纠正我)
优点:
由于应用程序持久性由Hibernate管理,因此不需要外键级联。它由Hibernate管理,具有适当的级联选项。
Hibernate DELETE操作(包括删除级联选项)在删除主键记录之前删除外键表记录(即避免引用完整性问题)。对于非外键的情况,外键情况和外键与级联情况,此行为相同。但是添加外键会不必要地减慢Oracle删除操作的速度。
缺点
Hibernate提供了一种机制,用于管理对象之间的关联以及关联中的级联操作。但它永远不会提供DB所具有的完整的参照完整性解决方案。
这些批处理作业只需使用SQL-loader或普通JDBC,就需要参照完整性。
伙计们,我需要你的建议。如果你们中的任何人都是DBA,请提供DBA方面的原因。
谢谢。
答案 0 :(得分:9)
我之前从未听过DBA的这样的提议!来自应用程序开发人员,是的,但绝不是来自数据库管理员。它乞求信仰。
Tom Kyte多次说过(例如here):应用程序来来往往,但数据是永远的。
根据我自己的经验,我参与了20多年前的Oracle数据库。他们从Oracle 6开始,多年来迁移到10G或11g - 相同的数据。但坐在上面的应用程序?首先它们是Forms 3.0,然后在某些情况下,它们被迁移到C ++,有些已经在Forms 6i中重新构建,在Application Express中重建了一些。 ADF当然是另一种可能性;或者可能是SOA架构......
当前的应用程序开发工具有什么特别之处,它突然接管了Oracle作为DBMS的工作?
答案 1 :(得分:6)
我曾参与决定放弃参照完整性约束的项目中的数据库。
我们必须编写“QC脚本”来检测与每个表关系相关的孤立行(孤立行会被外键约束阻止)。
然后,当他们(而不是)他们出现时,我们必须制定如何解决孤儿的政策。选择包括以下内容:
您可能希望与此数据库的利益相关者安排定期每周会议以查看QC脚本报告,并决定如何处理每个孤立行。
没有框架可以像在数据库中运行的约束一样可靠地强制引用完整性。只有数据库才能提供真正的原子变化并确保一致性。
答案 2 :(得分:4)
由于数据库约束得到保证,在某些情况下,它们可以允许其他优化。
例如,假设您有一个视图
CREATE VIEW orders_vw AS
SELECT ord.order_id, ord.customer_id, lin.product_id
FROM orders ord JOIN order_lines lin on ord.order_id = lin.order_id
然后你有一个SELECT product_id FROM orders_vw WHERE order_id = :val
的查询
在强制执行完整性的情况下,数据库知道order_lines中的任何order_id在父表中都有一行,并且由于实际上没有从orders表中选择任何值,因此可以通过不访问orders表来节省工作。
如果没有约束,数据库就无法确定order_lines中的条目是否具有父级,因此必须执行访问orders表的额外工作以进行检查。
根据您的查询模式,您可能会发现删除约束实际上会增加数据库的工作量。
答案 3 :(得分:-2)
通常,外键删除是数据库性能优化的开始。这是一种权衡:你在DBMS级别上销售有保证的完整性并且必须自己管理它(这对于Hibernate来说相当容易,但需要在纯SQL中非常准确),并且由于查询中的外键检查,您可以获得更高的查询性能很贵。