Ami*_*deh 4 sql oracle database-design constraints
我们在项目中使用Oracle数据库.我们定义了可以应用于数据库的约束(包括主要,唯一,检查和外键约束).
似乎定义约束DEFERRABLE允许我们在需要时对它们进行DEFER,那么为什么要将任何约束定义为NOT DEFERRABLE?
为什么像Oracle这样的数据库没有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
);
Run Code Online (Sandbox Code Playgroud)
如果约束是立即的,则必须以正确的顺序插入(或删除)行(彼此引用),这在批量加载数据时可能是一个问题.如果延迟约束,只要在提交事务时一切正常,就可以按任何顺序插入/删除行.
因此,与一个延迟的约束(这上面的例子中也没有!创建),你可以在以下几点:
insert into grand_child values (1,1);
insert into child values (1,1);
insert into parent values (1);
commit;
Run Code Online (Sandbox Code Playgroud)
如果限制是立竿见影的,这是不可能的.
以上示例的一个特例是循环引用:
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);
Run Code Online (Sandbox Code Playgroud)
如果不将约束声明为可延迟,则根本无法将数据插入到这些表中.
不支持可延迟约束的DBMS的解决方法是使fk列可以为空.然后首先插入空值:
插入一个值(1,null); 插入两个值(1,1); 更新一组id_two = 1,其中id = 1;
使用可延迟约束,您不需要其他更新语句.
(然而,使用循环参考的设计经常是有问题的!)
我经常不使用可延迟的约束,但我不想没有它们.
可延迟约束的一个缺点是错误检查.除非您commit的数据正确,否则您不知道.这使得找出什么地方出了错有点复杂.如果在执行insert(delete或者update)时遇到错误,您会立即知道哪些值导致了错误.
| 归档时间: |
|
| 查看次数: |
1252 次 |
| 最近记录: |