sql - 定义可延迟约束的优缺点是什么

标签 sql oracle database-design constraints

我们在项目中使用 Oracle 数据库。我们定义了尽可能多的可应用于数据库的约束(包括主约束、唯一约束、检查约束和外键约束)。

看起来定义约束DEFERRABLE允许我们在需要时DEFER它们,那么为什么任何约束都应该定义为NOT DEFERRABLE呢?

为什么 Oracle 等数据库将 NOT DEFERRABLE 作为默认情况?

定义约束 NOT DEFERRABLE 有什么优点吗?

最佳答案

可延迟约束的主要用例是您无需担心对具有外键关系的多个表执行 DML 语句的顺序。

考虑以下示例:

create table parent
(
   id integer not null primary key
);

create table child
(
  id integer not null primary key,
  parent_id integer not null references parent
);

create table grand_child
(
  id integer not null primary key,
  child_id integer not null references child
);

如果约束是直接的,您必须以正确的顺序插入(或删除)行(相互引用),这可以例如批量加载数据时会出现问题。如果约束被推迟,只要提交事务时一切正常,您就可以按任何顺序插入/删除行。

因此,使用可延迟约束(上面的示例没有创建!),您可以执行以下操作:

insert into grand_child values (1,1);
insert into child values (1,1);
insert into parent values (1);
commit;

如果立即受到限制,这是不可能的。

上述示例的一个特例是循环引用:

create table one
(
   id integer not null primary key,
   id_two integer not null
);

create table two
(
   id integer not null primary key
   id_one integer not null
);

alter table one add constraint fk_one_two (id_two) references two(id);
alter table two add constraint fk_two_one (id_one) references one(id);

如果不将约束声明为可延迟,您将根本无法将数据插入到这些表中。

对于不支持可延迟约束的 DBMS,解决方法是使 fk 列可为空。然后先插入空值:

插入一个值(1, null); 插入两个值 (1, 1); 更新一 设置 id_two = 1 其中 id = 1;

使用可延迟约束,您不需要额外的更新语句。

(然而,使用循环引用的设计经常受到质疑!)

我不经常使用可延迟约束,但我不想没有它们。

可延迟约束的一个缺点是错误检查。在提交之前您不知道数据是否正确。这使得找出问题所在变得更加复杂。如果您在执行插入(或删除更新)时遇到错误,您会立即知道哪些值导致了错误。

关于sql - 定义可延迟约束的优缺点是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20439889/

相关文章:

sql - Oracle——优化SQL查询

java - JDBC如何管理数据完整性

mysql - 在 MySQL 中使用浮点存储超过一百万的值的最大可能值

即使在检查库中的类是否正确之后,也会出现 Java ClassNotFoundException

sql - 使用 if else 创建 View

SQL Server 两个字段的唯一组合键,第二个字段自动递增

mysql - 体育/游戏结果应用程序中的硬删除与软删除

sql - 连接两个表时如何删除一个连接键

oracle - Oracle 的 ORA_HASH 是 "random"吗?

database - 如何设计数据库以存储 "default"项