¿Cómo diseñar esta base de datos para evitar la dependencia cíclica?

12

Hay dos tablas:

  1. Usuario
  2. Habla a

El usuario contiene una referencia a la Dirección.

La dirección contiene las columnas CreatedBy y ModifiedBy, que hace referencia al usuario.

¿Cómo diseño esta base de datos para evitar una dependencia cíclica?

Shashi
fuente
44
¿Está seguro de que ModifiedBy no es una referencia al usuario de la base de datos que realizó el cambio, en lugar del usuario de las aplicaciones (que residiría en la tabla Usuario)? De cualquier manera, en realidad no importa. No veo por qué hay un problema real.
Philᵀᴹ
Cuál se creará primero. Como CreatedBy y Modifiedby son datos imprescindibles. Y la tabla de usuario no debe tener addressid como nulo. Problema de huevo de gallina. A medida que resuelvo esto creando una nueva tabla UserAddress que contiene la referencia para userid y addressid
Shashi
2
Siempre podría usar restricciones diferidas si su DBMS las admite.
Colin 't Hart
Nota: el modelo relacional admite hacer dos inserciones o actualizaciones como una operación atómica, es una verdadera pena que esto no sea compatible con SQL (ya que las restricciones diferidas, aunque las sugerí, son bastante horribles).
Colin 't Hart

Respuestas:

7

En lugar de buscar consejos y trucos (se incluyen restricciones diferidas), le sugiero que simplemente diseñe su salida de este "bloqueo de referencia", así que intente algo como esto:


Hechos

  • El usuario(UserID) existe
  • La dirección(AddressID) fue creada por el usuario(UserID) .
  • Dirección(AddressID) fue creada en Fecha(DateCreated) .
  • La dirección(AddressID) fue modificada por última vez por el usuario(UserID) en la fecha(ModifiedOn) .
  • El usuario(UserID) reside en la dirección(AddressID) desde la fecha(ValidFrom) .

Restricciones

  • Each La dirección fue creada por el exactly one usuario . It is possible that more than one La dirección fue creada por el the same usuario .

  • Each Dirección fue creada en exactly one Fecha . It is possible that more than one Dirección fue creada en the same Fecha .

  • For each Dirección and Fecha , la that dirección fue modificada por el at most one usuario en la that fecha .

  • For each and Fecha del usuario , el that usuario reside en la at most one dirección desde la that fecha .


Lógico

ingrese la descripción de la imagen aquí


En lo que respecta a la dirección obligatoria, verifique eso en la capa de aplicación y envuelva las declaraciones de carga en una transacción, de esa manera obtendrá todo o nada.

Damir Sudarevic
fuente
5

No tiene más remedio que crear la dependencia cíclica en 2 operaciones como se muestra a continuación porque no existe una tabla cuando crea la primera.

CREATE TABLE A (A_ID INT PRIMARY KEY, B_FK INT);
CREATE TABLE B (B_ID INT PRIMARY KEY, A_FK INT REFERENCES A(A_ID));

ALTER TABLE A ADD B_FK INT;

Si desea evitar la dependencia cíclica. Luego debe eliminar una restricción REFERENCES o puede agregar una referencia DELETE y UPDATE CASCADE de una manera. También podría implementar un GATILLO si su lógica es algo compleja.

PollusB
fuente
1
Al eliminar las restricciones, se elimina la dependencia cíclica de la definición, pero no del diseño. Puede agregar una tabla de Eventos para registrar el UserID y AddressID que creó o modificó la dirección por última vez, pero eso solo aleja la dependencia un paso más allá. En el otro sentido, si la tabla Usuario tuviera columnas CreatedBy y ModifiedBy, la dependencia cíclica existiría en una tabla. Esto es similar a una tabla de empleados con una columna de supervisor donde el supervisor también es un empleado. Como Phil indicó, no hay problema.
Leigh Riffel
@LeighRiffel Estoy de acuerdo. Pero la tabla de eventos que propone en realidad elimina todas las dependencias cíclicas.
ypercubeᵀᴹ
@ypercube De hecho lo hace; No estoy seguro de cómo crucé ese cable. Para que quede claro, probablemente no debería crear una tabla de eventos aunque elimine la dependencia cíclica.
Leigh Riffel
De todos modos, no creo que esta respuesta aborde el problema. La pregunta (creo) es sobre cómo evitar la ruta cíclica, no cómo crear las FK con la ruta cíclica en primer lugar.
ypercubeᵀᴹ