En primer lugar, existe una regla general de diseño que una tabla modela ya sea un tipo de entidad única o una relación entre tipos de entidades, pero no ambas. Por lo tanto, imagino tres tablas, Media
(entidad), Idea
(entidad) y IdeasMedia
(relación). PD. sabes que el singular de 'media' es 'medio', ¿verdad? :)
He aquí algunos DDL de SQL-92 estándar que se centra en sólo teclas:
CREATE TABLE Media (MediaID INTEGER NOT NULL UNIQUE);
CREATE TABLE Idea (IdeaID INTEGER NOT NULL UNIQUE);
CREATE TABLE IdeasMedia
(
MediaID INTEGER NOT NULL REFERENCES Media (MediaID),
IdeaID INTEGER NOT NULL REFERENCES Idea (IdeaID)
);
CREATE ASSERTION Idea_must_have_media DEFERRABLE
CHECK (
NOT EXISTS (
SELECT *
FROM Idea AS i
WHERE NOT EXISTS (
SELECT *
FROM IdeasMedia AS im
WHERE im.MediaID = i.IdeaID
)
)
);
Hay un escenario 'huevo y la gallina' aquí: no se puede crear una idea con y sin una referencia a IdeasMedia
pero puede ¡No cree un IdeasMedia
sin crear un Idea
!
La solución ideal (basada en conjuntos) sería que SQL Standard admitiera asignaciones múltiples, p.
INSERT INTO Media (MediaID) VALUES (22),
INSERT INTO Idea (IdeaID) VALUES (55),
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55);
donde el punto y coma indica el límite instrucción SQL a la que se comprueban las restricciones de puntos y las comas que denotan los subsentencias.
Lamentablemente, no hay planes para agregar este paradigma basado en conjuntos al estándar SQL.
La solución (procedimiento) de SQL-92 para esto es la siguiente:
BEGIN TRANSACTION;
INSERT INTO Media (MediaID) VALUES (22);
SET CONSTRAINTS Idea_must_have_media DEFERRED;
-- omit the above if the constraint was declared as INITIALLY DEFERRED.
INSERT INTO Idea (IdeaID) VALUES (55);
INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (55, 22);
SET CONSTRAINTS Idea_must_have_media IMMEDIATE;
-- above may be omitted: constraints are checked at commit anyhow.
COMMIT TRANSACTION;
Lamentablemente, SQL Server no admite ni CREATE ASSERTION
CHECK
restricciones que pueden hacer referencia a otras tablas ni limitaciones diferibles!
Personalmente, me gustaría manejar esto en SQL Server como sigue:
- Crear 'ayudante' procedimientos almacenados para agregar, modificar y eliminar
Ideas
y sus respectivos IdeasMedia
relaciones.
- Elimina los privilegios de actualización de las tablas para obligar a los usuarios a usar los procesos .
- Posiblemente use desencadenadores para manejar escenarios al eliminar
Media
y Idea
entidades.
Ciertamente, esta implementación (nuevo procedimiento) está muy lejos del enfoque basado en el ideal establecido, lo que probablemente explica por qué la mayoría de los codificadores de SQL hacen la vista gorda a la exigencia de una relación 1: 1..N y en su lugar asume que el diseñador significó 1: 0..N !!
No estoy seguro de cómo podría hacer esto manteniendo 'Media' en una tabla separada: ¿cómo va a insertar los datos? Primero debe insertar en una tabla, luego en la segunda. Lo que puedes intentar es colocar los primeros "Medios" en la "Idea" (des-normalización) y declarar los campos como "no nulos", pero no lo recomendaría. Es posible que esté mejor con un poco de lógica en el código en lugar de la base de datos. –
Estoy de acuerdo con Aleks. Creo que esta es una regla de negocios que pertenece a un nivel intermedio en alguna parte, no en la base de datos. – David
@Aleks asociar un FK NOT NULL de Idea a Media no es infrecuente. Es simple, y sí, primero tendrá que llenar los medios. – vol7ron