El uso de múltiples claves foráneas en la misma columna en SQL Server
10
SQL Server me permite crear múltiples claves foráneas en una columna, y cada vez que use un nombre diferente puedo crear otra clave que haga referencia al mismo objeto. Básicamente todas las claves están definiendo la misma relación. Quiero saber cuál es el uso de tener múltiples claves externas que se definen en la misma columna y hacer referencia a la misma columna en otra tabla. ¿Cuál es el beneficio de que SQL Server nos permite hacer algo así?
No es beneficioso tener restricciones redundantes que difieren solo por nombre. Del mismo modo, no hay ningún beneficio en tener índices redundantes que difieren solo por nombre. Ambos agregan gastos generales sin valor.
El motor de base de datos de SQL Server no le impide hacerlo. Las buenas convenciones de nomenclatura de restricción (p. Ej., FK_ReferencingTable_ReferencedTable) pueden ayudar a proteger a uno de estos errores.
Incluso puede crear una clave externa en una columna que haga referencia a sí misma , a pesar del hecho de que esto nunca se puede violar, ya que cada fila cumplirá la restricción en sí misma.
Un caso extremo en el que la capacidad de crear dos claves externas en la misma relación sería potencialmente útil es porque el índice utilizado para validar claves externas se determina en el momento de la creación. Si aparece un índice mejor (es decir, más estrecho) más tarde, esto permitiría crear una nueva restricción de clave externa vinculada al mejor índice y luego la restricción original se eliminaría sin tener ningún espacio sin restricción activa.
(Como en el ejemplo a continuación)
CREATETABLE T1(
T1_Id INT PRIMARYKEYCLUSTEREDNOTNULL,
Filler CHAR(4000)NULL,)INSERTINTO T1 VALUES(1,'');CREATETABLE T2(
T2_Id INT IDENTITY(1,1)PRIMARYKEYNOTNULL,
T1_Id INT NOTNULLCONSTRAINT FK REFERENCES T1 (T1_Id),
Filler CHAR(4000)NULL,)ALTERTABLE T1 ADDCONSTRAINT
UQ_T1 UNIQUENONCLUSTERED(T1_Id)/*Execution Plan uses clustered index*/INSERTINTO T2 VALUES(1,1)ALTERTABLE T2 WITHCHECKADDCONSTRAINT FK2 FOREIGNKEY(T1_Id)REFERENCES T1 (T1_Id)ALTERTABLE T2 DROPCONSTRAINT FK
/*Now Execution Plan now uses non clustered index*/INSERTINTO T2 VALUES(1,1)DROPTABLE T2, T1;
Como un aparte para el período intermedio mientras existen ambas restricciones, cualquier inserción termina siendo validada contra ambos índices.
¿Se podría usar una transacción para garantizar la misma actualización de restricción sin espacios? ¿Es este método sin transacción mejor debido a un menor bloqueo, tal vez?
binki
13
No sirve de nada tener restricciones de clave externa idénticas, es decir, en las mismas columnas y hacer referencia a la misma tabla y columnas.
-En desacuerdo. Podría existir la posibilidad de que la tabla primaria necesite dos comprobaciones separadas. Vea el ejemplo a continuación, el remitente y el receptor son totalmente diferentes - stackoverflow.com/questions/40400483/…
trex
@trex estás hablando de algo diferente. La pregunta aquí dice: "Quiero saber de qué sirve tener múltiples claves foráneas que están definidas en la misma columna y referencia a la misma columna en otra tabla ".
ypercubeᵀᴹ
@ ypercubeᵀᴹ - Lo tengo. Gracias por dejarlo claro
trex
6
La misma razón por la que puede crear 50 índices en la misma columna, agregar un segundo archivo de registro, establecer la memoria máxima del servidor en 20 MB ... la mayoría de las personas no harán estas cosas, pero puede haber razones legítimas para hacerlas ocasionalmente, por lo que no hay beneficio en la creación de gastos generales en el motor para agregar controles contra cosas que son simplemente desaconsejadas.
Cuando comience a pasar de azul a verde, debe crear temporalmente copias adicionales de las cosas.
Lo que queremos hacer es crear temporalmente una clave externa adicional CHECK WITH NOCHECKy ON UPDATE CASCADE ON DELETE SET NULL; lo que esto hace es que es una clave externa que funciona pero las filas existentes no se verifican cuando se crea la clave.
Más tarde, después de limpiar todas las filas que deberían coincidir, crearíamos la nueva clave externa sin ninguna opción de comando (el valor predeterminado CHECK WITH CHECKes lo que normalmente desea) y soltaríamos la clave externa temporal.
Tenga en cuenta que si acaba de soltar y recrear la clave foránea, algunas filas de basura podrían pasar por alto.
No sirve de nada tener restricciones de clave externa idénticas, es decir, en las mismas columnas y hacer referencia a la misma tabla y columnas.
Es como tener el mismo cheque 2 o más veces.
fuente
La misma razón por la que puede crear 50 índices en la misma columna, agregar un segundo archivo de registro, establecer la memoria máxima del servidor en 20 MB ... la mayoría de las personas no harán estas cosas, pero puede haber razones legítimas para hacerlas ocasionalmente, por lo que no hay beneficio en la creación de gastos generales en el motor para agregar controles contra cosas que son simplemente desaconsejadas.
fuente
Suena como una cosa azul-verde.
Cuando comience a pasar de azul a verde, debe crear temporalmente copias adicionales de las cosas.
Lo que queremos hacer es crear temporalmente una clave externa adicional
CHECK WITH NOCHECK
yON UPDATE CASCADE ON DELETE SET NULL
; lo que esto hace es que es una clave externa que funciona pero las filas existentes no se verifican cuando se crea la clave.Más tarde, después de limpiar todas las filas que deberían coincidir, crearíamos la nueva clave externa sin ninguna opción de comando (el valor predeterminado
CHECK WITH CHECK
es lo que normalmente desea) y soltaríamos la clave externa temporal.Tenga en cuenta que si acaba de soltar y recrear la clave foránea, algunas filas de basura podrían pasar por alto.
fuente