En SQL Server, una restricción de clave externa (y un CHECK
restricción) puede ser confiable o no confiable.
Cuando se confía en una restricción, esto significa que el sistema ha verificado la restricción. Cuando no es de confianza, la restricción tiene no ha sido verificado por el sistema.
Básicamente, cuando tiene una restricción que no es de confianza, también podría tener datos no válidos en su base de datos. Con esto quiero decir que podría tener datos que violen la restricción.
Esto significa que ya no mantiene la integridad referencial dentro de sus relaciones, lo que normalmente no es una buena práctica cuando se ocupa de una base de datos relacional en producción.
En este artículo, verificaré la "confiabilidad" de mis restricciones existentes y luego las actualizaré para que vuelvan a ser confiables.
Ejemplo 1:revisar las restricciones existentes
Puede averiguar si una restricción es de confianza o no consultando sys.foreign_keys
vista del sistema.
Así:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Resultado:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Bien, esto me dice que tengo dos restricciones de clave externa y ambas no son de confianza.
Una de las restricciones está deshabilitada, por lo que tiene sentido que no sea de confianza (los datos incorrectos pueden ingresar a la base de datos siempre que la restricción esté deshabilitada).
Pero la otra restricción está habilitada, por lo que realmente no debería desconfiar. No ser de confianza significa que podría haber datos no válidos en la base de datos. No significa que haya existencia datos no válidos, solo que podrían ser.
Básicamente, al estar habilitado, verificará los datos futuros, pero no puede garantizar los datos existentes. Si se confía en una restricción, puede estar seguro de que todos los datos existentes son válidos.
Devolver solo restricciones que no son de confianza
Es posible que prefiera usar un WHERE
cláusula para devolver solo las restricciones que no son de confianza. Así:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys WHERE is_not_trusted = 1;
Resultado:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Entonces, en este caso, el resultado es el mismo (porque todas las restricciones actuales no son de confianza).
Ejemplo 2:restaurar la confianza
Para restaurar la confianza en su restricción habilitada, simplemente vuelva a habilitarla mientras usa WITH CHECK
opción.
Así:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;
Ahora, cuando consultamos sys.foreign_keys
obtenemos un resultado diferente:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Resultado:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Podemos ver que ahora se confía en la restricción, porque is_not_trusted
la bandera está establecida en 0
.
Ejemplo 3:¿Cómo se convirtió la restricción en No confiable?
Cuando deshabilita una restricción de clave externa, automáticamente deja de ser de confianza. Cuando vuelve a habilitar la misma restricción, tiene la oportunidad de restaurar su confianza. Si no hace esto, seguirá sin ser de confianza.
Cuando habilita una restricción de clave externa, tiene la opción de especificar WITH CHECK
o WITH NOCHECK
. Si especifica lo último, su restricción seguirá siendo no confiable una vez que se haya habilitado.
Es importante tener en cuenta que WITH NOCHECK
es la opción predeterminada, por lo que si no especifica explícitamente que debe ser de confianza, la restricción se habilitará como no confiable.
Sin embargo, sucede lo contrario cuando crea una restricción de clave externa. Cuando crea la restricción por primera vez, la opción predeterminada es WITH CHECK
. Por lo tanto, si omite esta configuración, se confiará en ella de manera predeterminada (a menos que tenga datos no válidos, en cuyo caso no se habilitará). Sin embargo, puede anular esta configuración especificando explícitamente WITH NOCHECK
cuando crea la restricción.
Para demostrar cómo sus restricciones habilitadas pueden permanecer fácilmente como no confiables, volveré a habilitar la otra tecla (la deshabilitada), pero usaré la configuración predeterminada:
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists; SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Resultado:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Entonces, siendo perezoso (u olvidadizo) y no especificando explícitamente WITH CHECK
, logré habilitar una restricción manteniendo intacto su estado "no confiable".
La conclusión clave de esto es:si desea que se confíe en sus restricciones reactivadas, siempre debe habilitarlas usando WITH CHECK
.