3

我的同事提到我们的客户 DBA 提议删除我们项目 Oracle DB 模式中的所有外键约束。起初我不同意这个决定。我是开发人员而不是 DBA。所以后来意识到这个决定背后可能有一些原因。所以我正在尝试了解这个决定的利弊。

项目信息:

  1. 具有 Hibernate 持久性的 Spring 应用程序。
  2. 甲骨文 10g 数据库
  3. 有些批处理作业仅使用 SQL-loader 或普通 JDBC。

这是我的优缺点列表(如果我错了请纠正我)

优点:

  1. 由于应用程序持久性由 Hibernate 管理,因此不需要外键级联。它由 Hibernate 使用适当的级联选项进行管理。

  2. Hibernate DELETE 操作(包括删除级联选项)在删除其主键记录之前删除外键表记录(即避免引用完整性问题)。对于无外键情况、外键情况和外键级联情况,此行为是相同的。但是添加外键会不必要地减慢 Oracle 删除操作。

缺点

  1. Hibernate 提供了一种机制来管理对象之间的关联以及关联中的级联操作。但它从来没有提供数据库拥有的完整的参照完整性解决方案。

  2. 那些仅使用 SQL-loader 或普通 JDBC 的批处理作业需要参照完整性。

伙计们,我需要你的建议。如果你们中的任何人是 DBA,请提供 DBA 的附加理由。

谢谢你。

4

4 回答 4

9

我以前从未听过 DBA 提出这样的建议!来自应用程序开发人员,是的,但绝不来自数据库管理员。它乞求信仰。

Tom Kyte 曾多次说过(例如这里):应用程序来来去去,但数据是永恒的。

以我自己的经验,我曾在 20 多年前的 Oracle 数据库上工作过。他们从 Oracle 6 开始,多年来一直迁移到 10G 或 11g - 相同的数据。但是最重​​要的应用程序呢?首先它们是 Forms 3.0,然后在某些情况下迁移到 C++,在某些情况下在 Forms 6i 中重新构建,在某些情况下在 Application Express 中重新构建。ADF 当然是另一种可能性。或者也许是 SOA 架构......

当前的应用程序开发工具有什么特别之处,以至于它突然接管了 Oracle 作为 DBMS 的工作?

于 2010-07-09T09:47:36.903 回答
6

我曾在决定放弃参照完整性约束的项目中处理数据库。

我们必须编写“QC 脚本”来检测与每个表关系相关的孤立行(孤立行会被外键约束阻止)。

然后当(不是如果)它们发生时,我们必须制定如何解决孤儿的政策。选择包括以下内容:

  • 删除孤立的行。
  • 归档孤立的行。
  • 将任何孤立的外键值更新为 NULL。
  • 将任何孤立的外键值更新为父表中的某个现有值。
  • 与异常一起生活。编写更多代码以从报告中排除孤儿。也许是所有表的一组视图?

您可能希望与该数据库的利益相关者安排一次定期的每周会议,以查看 QC 脚本报告,并决定如何处理每个孤立的行。

没有任何框架可以像在数据库中运行的约束那样可靠地强制引用完整性。只有数据库才能提供真正的原子更改并确保一致性。

于 2010-07-09T07:53:06.950 回答
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 在父表中都有一行,并且由于没有实际选择订单表中的值,它可以通过不访问订单来节省工作桌子。如果没有约束,数据库就不能确定 order_lines 中的条目是否有父条目,因此它必须做额外的工作来访问 orders 表来检查它。

根据您的查询模式,您可能会发现删除约束实际上会增加数据库的工作量。

于 2010-07-09T22:45:16.607 回答
-2

通常,外键删除是数据库性能优化的开始。这是一种权衡:您在 DBMS 级别上销售有保证的完整性,并且必须自己管理它(这在 Hibernate 中相当容易,但在普通 SQL 中需要非常准确),并且由于查询中的外键检查,您可以获得更高的查询性能相当昂贵。

于 2010-07-09T07:21:17.510 回答