Modelado de claves foráneas de tabla de enlace Many-to-Many en SQLite.
Tengo las dos siguientes tablas en SQLite:
CREATE TABLE Link (
link_id integer NOT NULL,
part_id integer NOT NULL,
CONSTRAINT link_pk PRIMARY KEY(link_id, part_id)
);
CREATE TABLE Main (
main_id integer NOT NULL PRIMARY KEY AUTOINCREMENT,
link_id integer NOT NULL REFERENCES Link(link_id)
);
INSERT INTO Link (link_id, part_id) VALUES (1,10);
INSERT INTO Link (link_id, part_id) VALUES (1,11);
INSERT INTO Link (link_id, part_id) VALUES (1,12);
INSERT INTO Link (link_id, part_id) VALUES (2,15);
INSERT INTO Main (main_id, link_id) VALUES (1,1);
INSERT INTO Main (main_id, link_id) VALUES (2,1);
INSERT INTO Main (main_id, link_id) VALUES (3,2);
Muchas filas de Main
pueden hacer referencia al mismo link_id
, y muchas filas de Link
pueden tener el mismo link_id
, de tal manera que select * from Main natural join Link where main_id=1
devolverá N filas, y select * from Main where link_id=1
devolverá K filas. El link_id
es importante, y los datos originales indican que cada elemento principal (main
) tiene 1 link_id
, y cada enlace (link
) tiene N identificadores de pieza (part_id
).
Utilizando los esquemas anteriores, no puedo insertar ninguna fila en Main
debido a la restricción de clave externa (foreign key mismatch - "Main" referencing "Link": INSERT INTO Main (main_id, link_id) VALUES (1,1);
), presumiblemente debido al requisito de clave compuesta. Puedo ignorar esta restricción eliminando la clave externa, pero en ese caso obviamente estoy omitiendo una restricción. Invertir la dirección de la clave tampoco funcionaría, ya que, como se dijo anteriormente, se trata de una relación de muchos a muchos. ¿Hay alguna manera de modelar esto correctamente en SQLite con una restricción que asegure que al menos una fila exista en Link
para cada link_id
en Main
?
davy.ai
Sí, hay una forma de modelar esto correctamente en SQLite con una restricción que al menos una fila exista en
Link
para cadalink_id
enMain
. Una solución sería agregar una restricción de verificación en la tablaMain
para garantizar que ellink_id
exista en la tablaLink
:La restricción
main_link_check
usa una subconsulta para contar el número de filas en la tablaLink
donde ellink_id
coincide con ellink_id
en la tablaMain
. Si este recuento es menor que 1, la restricción de verificación falla y la fila no se puede insertar o actualizar.Con esta restricción en su lugar, debería poder insertar filas en la tabla
Main
sin encontrar ninguna restricción de clave externa. Además, la restricción de verificación asegura que hay al menos una fila correspondiente en la tablaLink
para cadalink_id
en la tablaMain
.