Tengo una tabla que contiene datos, y una de esas filas debe existir en otra tabla. Por lo tanto, quiero una clave externa para mantener la integridad referencial.
CREATE TABLE table1
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
SomeData VARCHAR(100) NOT NULL
)
CREATE TABLE table2
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
MoreData VARCHAR(30) NOT NULL,
CONSTRAINT fk_table2_table1 FOREIGN KEY (AnotherID) REFERENCES table1 (AnotherID)
)
Sin embargo, como puede ver, la tabla a la que formo una clave externa, la columna no es la PK. ¿Hay alguna forma de crear esta clave externa, o tal vez una mejor manera de mantener esta integridad referencial?
sql
sql-server
Craig
fuente
fuente
table1.ID
?Respuestas:
Si realmente desea crear una clave foránea para una clave no primaria, DEBE ser una columna que tenga una restricción única.
De libros en línea :
Entonces, en su caso, si lo hace
AnotherID
único, se permitirá. Si no puede aplicar una restricción única, no tiene suerte, pero esto realmente tiene sentido si lo piensa.Aunque, como se ha mencionado, si tiene una clave primaria perfectamente buena como clave candidata, ¿por qué no usarla?
fuente
Como otros han señalado, idealmente, la clave externa se crearía como referencia a una clave primaria (generalmente una columna IDENTIDAD). Sin embargo, no vivimos en un mundo ideal y, a veces, incluso un cambio "pequeño" en un esquema puede tener efectos significativos en la lógica de la aplicación.
Considere el caso de una tabla de Cliente con una columna de SSN (y una clave primaria tonta), y una tabla de Reclamación que también contiene una columna de SSN (poblada por la lógica de negocios de los datos del Cliente, pero no existe FK). El diseño es defectuoso, pero ha estado en uso durante varios años, y se han construido tres aplicaciones diferentes en el esquema. Debería ser obvio que eliminar a Claim.SSN y establecer una verdadera relación PK-FK sería ideal, pero también sería una revisión importante . Por otro lado, poner una restricción ÚNICA en Customer.SSN y agregar un FK en Claim.SSN, podría proporcionar integridad referencial, con poco o ningún impacto en las aplicaciones.
No me malinterpreten, estoy a favor de la normalización, pero a veces el pragmatismo vence al idealismo. Si se puede ayudar a un diseño mediocre con una curita, se podría evitar la cirugía.
fuente
Nigromancia
Supongo que cuando alguien aterriza aquí, necesita una clave externa para la columna en una tabla que contiene claves no únicas.
El problema es que si tiene ese problema, el esquema de la base de datos se desnormaliza.
Por ejemplo, mantiene las salas en una tabla, con una clave principal de room-uid, un campo DateFrom y DateTo, y otro uid, aquí RM_ApertureID para realizar un seguimiento de la misma sala y un campo de borrado suave, como RM_Status, donde 99 significa 'eliminado' y <> 99 significa 'activo'.
Entonces, cuando crea la primera sala, inserta RM_UID y RM_ApertureID como el mismo valor que RM_UID. Luego, cuando finaliza la sala a una fecha y la restablece con un nuevo rango de fechas, RM_UID es newid (), y el RM_ApertureID de la entrada anterior se convierte en el nuevo RM_ApertureID.
Entonces, si ese es el caso, RM_ApertureID es un campo no único, por lo que no puede establecer una clave externa en otra tabla.
Y no hay forma de establecer una clave externa para una columna / índice no único, por ejemplo, en T_ZO_REM_AP_Raum_Reinigung (DONDE RM_UID es realmente RM_ApertureID).
Pero para prohibir los valores no válidos, debe establecer una clave foránea, de lo contrario, la basura de datos es el resultado más temprano que tarde ...
Ahora, lo que puede hacer en este caso (salvo reescribir toda la aplicación) es insertar una restricción CHECK, con una función escalar que verifica la presencia de la clave:
fuente
Las claves primarias siempre deben ser únicas, las claves externas deben permitir valores no únicos si la tabla es una relación de uno a muchos. Está perfectamente bien usar una clave externa como clave principal si la tabla está conectada por una relación uno a uno, no una relación uno a muchos.
Una restricción FOREIGN KEY no tiene que estar vinculada solo a una restricción PRIMARY KEY en otra tabla; También se puede definir para hacer referencia a las columnas de una restricción ÚNICA en otra tabla.
fuente