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í?

ingrese la descripción de la imagen aquí

Respuestas:


12

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.


17

SQL Server le permite hacer muchas cosas tontas.

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)

CREATE TABLE T1(
    T1_Id INT PRIMARY KEY CLUSTERED  NOT NULL,
    Filler CHAR(4000) NULL,
) 

INSERT INTO T1 VALUES (1, '');

CREATE TABLE T2(
    T2_Id INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
    T1_Id INT NOT NULL CONSTRAINT FK REFERENCES T1 (T1_Id), 
    Filler CHAR(4000) NULL,
)


ALTER TABLE T1 ADD CONSTRAINT
    UQ_T1 UNIQUE NONCLUSTERED(T1_Id) 


/*Execution Plan uses clustered index*/ 
INSERT INTO T2 VALUES (1,1) 

ALTER TABLE T2  WITH CHECK ADD  CONSTRAINT FK2 FOREIGN KEY(T1_Id)
REFERENCES T1 (T1_Id)    

ALTER TABLE T2 DROP CONSTRAINT FK

/*Now Execution Plan now uses non clustered index*/    
INSERT INTO T2 VALUES (1,1)    

DROP TABLE  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.

Es como tener el mismo cheque 2 o más veces.


-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.


2

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 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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.