Leí esto sobre la palabra clave SQL DEFERRABLE
en Database Systems - The Complete Book .
El último [NO DEFERRABLE] es el predeterminado y significa que cada vez que se ejecuta una instrucción de modificación de la base de datos, la restricción se verifica inmediatamente después, si la modificación podría violar la restricción de clave externa.
Sin embargo, si declaramos que una restricción es DEFERRABLE , entonces tenemos la opción de hacer que espere hasta que se complete una transacción antes de verificar la restricción.
Seguimos la palabra clave DEFERRABLE por cualquiera INICIALMENTE DIFERIDO o INICIALMENTE INMEDIATA . En el primer caso, la verificación se aplazará justo antes de que se confirme cada transacción. En este último caso, la verificación se realizará inmediatamente después de cada extracto.
¿En qué se NOT DEFERRABLE
diferencia de DEFERRABLE INITIALLY IMMEDIATE
? En ambos casos, al parecer, las restricciones se verifican después de cada declaración individual.
DEFERRABLE
establece la intención del diseñador de que diferir la restricción es una acción que vale la pena o es necesaria. Este no es el caso de la gran mayoría de las limitaciones de la base de datos y el etiquetado de todos, yaDEFERRABLE
que perdería esta útil distinción.NOT DEFERRABLE
suele ser el más rápido.Aparte de las otras respuestas (correctas), cuando se habla de PostgreSQL , se debe decir que:
con NOT DEFERRABLE cada fila se marca en el momento de la inserción / actualización
con DEFERRABLE (actualmente INMEDIATO ) todas las filas se verifican al final de la inserción / actualización
con DEFERRABLE (actualmente DEFERRED ) todas las filas se verifican al final de la transacción
Por lo tanto , no es correcto decir que una restricción DEFERRABLE actúa como una NO DEFERRABLE cuando se establece en INMEDIATO.
Desarrollemos esta diferencia:
Esto produce correctamente:
Pero si eliminamos la instrucción DEFERRABLE INICIALMENTE INMEDIATA,
ADENDA (12 de octubre de 2017)
De hecho, este comportamiento está documentado aquí , sección "Compatibilidad":
fuente
NOT DEFERRABLE
es la velocidad ( consulte aquí , sección Restricciones de unicidad no diferidas , "Tenga en cuenta que esto puede ser significativamente más lento que la comprobación de unicidad inmediata" ).DEFERRABLE
restricción no puede ser referenciada como claves foráneas en otras tablas ( ver aquí , sección Parámetros , "Las columnas referenciadas deben ser las columnas de una restricción de clave primaria o única no diferible en la tabla referenciada" ).NOT DEFERRABLE
simplemente porque funciona mejor?NOT DEFERRABLE
2) si al menos una FK hace referencia a la restricción, usamosNOT DEFERRABLE
también 3) en los otros casos, usamosDEFERRABLE INITIALLY IMMEDIATE
. Esto podría disminuir ligeramente el rendimiento de esas restricciones, pero asegura la máxima compatibilidad con otros DBMS que usamos (Oracle, SqlServer). PK y FK no son un problema porque nunca actualizamos sus valores (lo que creo que es un buen hábito de programación para DB).Aparte de lo obvio de poder aplazar, la diferencia es en realidad el rendimiento. Si no hubiera una penalización de desempeño, entonces no habría necesidad de tener la opción de elegir diferible o no; todas las restricciones simplemente serían diferibles.
La penalización del rendimiento tiene que ver con las optimizaciones que la base de datos puede realizar dado el conocimiento de cómo se restringen los datos. Por ejemplo, el índice que se crea para respaldar una restricción única en Oracle no puede ser un índice único si la restricción es diferible, ya que se debe permitir el permiso temporal de duplicados. Sin embargo, si la restricción no se puede aplazar, el índice puede ser único.
fuente
Llego muy tarde a la fiesta, pero quería agregar que, a partir de diciembre de 2018, solo dos bases de datos que conozco (puede haber más) ofrecen algún nivel de implementación de esta característica estándar de SQL :
* 1 Aunque Oracle 12c acepta el
NOT DEFERRABLE
estado de restricción , en realidad lo ignora y lo hace funcionar comoDEFERRABLE INITIALLY IMMEDIATE
.Como ve, Oracle no implementa el primer tipo (
NOT DEFERRABLE
), y es por eso que los desarrolladores que usan Oracle (el OP en este caso) pueden confundirse y considerar los dos primeros tipos equivalentes.Curiosamente, Oracle y PostgreSQL tienen un tipo predeterminado diferente. Quizás tenga implicaciones en el rendimiento.
fuente
NO DEFERRABLE: no puede cambiar la comprobación de restricciones, Oracle la comprueba después de cada declaración (es decir, directamente después de insertar la declaración).
DEFERRABLE INICIALMENTE INMEDIATO: Oracle verifica la restricción después de cada declaración. PERO, puede cambiarlo después de cada transacción (es decir, después de confirmar):
fuente