Pregunta

Mi base de datos SQL (Firebird) tiene una tabla llamada tTransaction . Contiene dos columnas, senderFK y receiverFK . Hay otras tres tablas, tBufferStock , tFacility y tOutsideLocation .

Un remitente o un receptor pueden ser un stock de reserva, nuestra propia instalación o una ubicación externa.

Mi problema es que no sé cómo dejar que senderFK o receiverFK hagan referencia a la tabla correcta.

He pensado en una nueva tabla entre el remitente y los tres posibles remitentes con un ID, un número entre 1 y 3 para la tabla y el ID referenciado dentro de esta tabla, pero en realidad eso no resuelve el problema. ¿Alguna idea?

Norbert

¿Fue útil?

Solución

Lo que estás tratando de hacer no se puede hacer en SQL. No puede hacer referencia a hasta tres tablas diferentes con un solo FK.

Lo que debes hacer sería:

  • crear columnas adicionales senderBufferstockFK , senderFacilityFK y senderOutsideLocationFK
  • conectarlos a las tablas apropiadas
  • tiene una restricción de verificación (si es compatible) o un disparador o algún otro mecanismo en tu tabla principal para asegurarte de que solo uno de esos tres tenga un valor en un momento dado

Esto significaría, en un momento dado, solo uno de los tres " fk " la columna podría tener un valor, pero cada columna FK sería un FK específico para una tabla específica.

Puede poner esto directamente en la tabla de la que está hablando, o puede externalizar esto en una tabla separada y desde su tabla principal simplemente haga referencia a que " intermediario " tabla, y desde allí tienen estos tres FK

YourTable.SenderFK --> Intermediary.PK
    Intermediary.SenderBufferstockFK --> tBufferstock.ID
    Intermediary.SenderFacilityFK --> tFacility.ID
    Intermediary.SenderOutsideLocationFK --> tOutsideLocation.ID

O simplemente puedes abandonar la relación FK, ¡pero definitivamente es NO una buena idea!

Marc

Otros consejos

Prueba el siguiente esquema:

tSenderReceiver (type INT, id INT, PRIMARY KEY (type, id))

tTransaction (id INT PRIMARY KEY, senderType INT, senderId INT, receiverType INT, receiverID INT,
      FOREIGN KEY (senderType, senderID) REFERENCES tSenderReceiver,
      FOREIGN KEY (receiverType, receiverID) REFERENCES tSenderReceiver
)

tBufferStock (type INT, id INT,
      CHECK (type = 1),
      PRIMARY KEY (type, id),
      FOREIGN KEY (type, id) REFERENCES tSenderReceiver
)

tFacility (type INT, id INT,
      CHECK (type = 2),
      PRIMARY KEY (type, id),
      FOREIGN KEY (type, id) REFERENCES tSenderReceiver
)

tOutsideLocation (type INT, id INT,
      CHECK (type = 3),
      PRIMARY KEY (type, id),
      FOREIGN KEY (type, id) REFERENCES tSenderReceiver
)

SQL no admite una clave externa de la forma " esta columna en la tabla X o esa columna en la tabla Y " ;. Usted puede:

  1. Refactorice su base de datos para que las tres tablas de clave externa posibles se combinen en una sola, posiblemente llamada tCounterParty. Esto es definitivamente apropiado si la estructura de esas tablas es idéntica o muy similar. Si no son similares, puede seguir este enfoque y usar otras tres tablas, vinculadas a tCounterParty, para contener la información variable.

  2. Mueva su integridad referencial de una clave externa a un disparador, si es compatible con su base de datos.

¿no puedes usar 3 columnas para el remitente y 3 para el receptor? por lo que tendrá bufferSenderFK, facilitySenderFK y facilitySenderFK. para una sola transacción, se puede usar 1 columna y las otras dos serán nulas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top