What are cons and pros a of defining a constraint deferrable

constraints, database-design, oracle, sql

Solution

The major use case for deferrable constraints is that you don't need to worry about the order in which you do DML statements for multiple tables that have a foreign key relationship.

Consider the following example:

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
);

If the constraints are immediate you have to insert (or delete) rows (that reference each other) in the proper sequence, which can e.g. be a problem when bulk loading data. If the constraints are deferred you can insert/delete the rows in any sequence as long as everything is fine when you commit your transaction.

So with a deferrable constraint (which the above example does not create!) you could the following:

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

That would not be possible if the constraints were immediate.

A special case of the above example are cyclic references:

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);

Without declaring the constraints as deferrable you will not be able to insert data into those tables at all.

The workaround for DBMS that do not support deferrable constraints would be to make the fk columns nullable. And then insert null values first:

insert into one values (1, null); insert into two values (1, 1); update one set id_two = 1 where id = 1;

With a deferrable constraint you don't need the additional update statement.

(The design using a cyclic reference is however very often questionable!)

I don't use deferrable constraints where often, but I wouldn't want to live without them.

One drawback of deferrable constraints is error checking though. You don't know until you `commit` if your data is correct. That makes finding out what went wrong a bit more complicated. If you get the error when doing the `insert` (or `delete` or `update`) you immediately know which values caused the error.

Problem

We are using Oracle database in our projects. And we define as much as constraints that can be applied to database, (including primary, unique, check and foreign key constraints). It seems that defining constraints DEFERRABLE allows us to DEFER them when it is required, so why shall any constraint be defined as NOT DEFERRABLE? Why databases such as Oracle have NOT DEFERRABLE as default case? Are there any pros for defining a constraint NOT DEFERRABLE?

Original source