¿Es aceptable tener una referencia circular entre dos tablas en el campo de clave externa?
Si no, ¿cómo se pueden evitar estas situaciones?
Si es así, ¿cómo se pueden insertar los datos?
A continuación se muestra un ejemplo de dónde (en mi opinión) una referencia circular sería aceptable:
CREATE TABLE Account
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Contact
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50),
AccountID INT FOREIGN KEY REFERENCES Account(ID)
)
ALTER TABLE Account ADD PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)
database-design
foreign-key
rdbms
KidCode
fuente
fuente
Respuestas:
Dado que está utilizando campos anulables para las claves foráneas, de hecho, puede construir un sistema que funcione correctamente de la manera que lo imagina. Para insertar filas en la tabla Cuentas, debe tener una fila presente en la tabla Contactos a menos que permita inserciones en Cuentas con un PrimaryContactID nulo. Para crear una fila de contactos sin tener una fila de Cuenta presente, debe permitir que la columna AccountID en la tabla Contactos sea anulable. Esto permite que las cuentas no tengan contactos y permite que los contactos no tengan cuenta. Quizás esto sea deseable, quizás no.
Dicho esto, mi preferencia personal sería tener la siguiente configuración:
Esto proporciona la capacidad de:
IX_AccountsContactsXRef_Primary
índice. Este índice contiene un filtro, por lo que solo funcionará en plataformas que los admitan. Dado que este índice se especifica con laUNIQUE
opción, solo puede haber un único contacto principal para cada cuenta.Por ejemplo, si desea mostrar una lista de todos los contactos, con una columna que indica el estado "principal", que muestra los contactos principales en la parte superior de la lista para cada cuenta, puede hacer lo siguiente:
El índice filtrado evita la inserción de más de un contacto principal por cuenta, al tiempo que proporciona un método rápido para devolver una lista de contactos principales. Uno podría imaginar fácilmente otra columna,
IsActive
con un índice filtrado no único para mantener un historial de contactos por cuenta, incluso después de que ese contacto ya no esté asociado con la cuenta:fuente
No, no es aceptable tener referencias de claves foráneas circulares. No solo porque sería imposible insertar datos sin eliminar y recrear constantemente la restricción. pero porque es un modelo fundamentalmente defectuoso de todos y cada uno de los dominios que se me ocurren. En su ejemplo, no puedo pensar en ningún dominio en el que la relación entre la Cuenta y el Contacto no sea NN, que requiera una tabla de unión con referencias FK a la Cuenta y al Contacto.
fuente
Puede hacer que su objeto externo apunte al contacto principal, en lugar de a la cuenta. Sus datos se verían así:
fuente