Sql 定义可延迟约束的利弊是什么

Sql 定义可延迟约束的利弊是什么,sql,oracle,database-design,constraints,Sql,Oracle,Database Design,Constraints,我们在项目中使用Oracle数据库。我们定义了尽可能多的可应用于数据库的约束(包括主约束、唯一约束、检查约束和外键约束) 似乎定义可延迟的约束允许我们在需要时延迟它们,那么为什么要将任何约束定义为不可延迟呢 为什么像Oracle这样的数据库没有将延迟作为默认情况 定义不可延迟的约束有什么好处吗?可延迟约束的主要用例是,您不需要担心为具有外键关系的多个表执行DML语句的顺序 考虑以下示例: create table parent ( id integer not null primary k

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

似乎定义可延迟的约束允许我们在需要时延迟它们,那么为什么要将任何约束定义为不可延迟呢

为什么像Oracle这样的数据库没有将延迟作为默认情况


定义不可延迟的约束有什么好处吗?

可延迟约束的主要用例是,您不需要担心为具有外键关系的多个表执行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,空); 插入两个值(1,1); 更新一 设置id_two=1 其中id=1

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

(然而,使用循环参考的设计通常是有问题的!)

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


延迟约束的一个缺点是错误检查。只有在提交数据后才能知道数据是否正确。这使得找出哪里出了问题变得更加复杂。如果在执行
insert
(或
delete
update
)时出现错误,您将立即知道是哪些值导致了错误。

有一些有趣的地方,当您定义一个约束
delerable
时,您可以将其设置为
初始立即
,这将检查DML命令上的约束,那么,定义“不可延迟”约束有什么好处吗?@AmirPashazadeh:如果你想确保它们永远不会被延迟(因为你想“在动词时间”得到错误)。另外,请阅读作为对您的问题的评论而发布的链接