First, there is a design rule in which a table models one entity type or relationship between entity types, but not both. Therefore, I present three tables: Media (entity), Idea (entity) and IdeasMedia (relation). postscript you know that the only "media" is "average", right? :)
Here are a few standard SQL-92 DDLs that focus only on keys:
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 ) ) );
Here's the chicken and egg scenario: it's impossible to create an idea without an IdeasMedia link, but can't create an IdeasMedia without creating an Idea !
An ideal (set-based) solution would be for SQL Standard to support multiple assignment, for example.
INSERT INTO Media (MediaID) VALUES (22), INSERT INTO Idea (IdeaID) VALUES (55), INSERT INTO IdeasMedia (MediaID, IdeaID) VALUES (22, 55);
where a semicolon indicates the boundary of the SQL statement at which point constraints are checked, and commas representing subqueries.
Unfortunately, there are no plans to add this set-based paradigm to the SQL standard.
The SQL-92 solution (procedural) is as follows:
BEGIN TRANSACTION; INSERT INTO Media (MediaID) VALUES (22); SET CONSTRAINTS Idea_must_have_media DEFERRED;
Unfortunately, SQL Server does not support CREATE ASSERTION and CHECK constraints, which can reference other tables and deferred constraints!
Personally, I would handle this in SQL Server as follows:
- Create โhelperโ stored procedures for adding, modifying, and deleting
Ideas and their corresponding IdeasMedia . - Remove update privileges from tables to force users to use proxy.
- You can use triggers to process scripts when deleting
Media and Idea .
Of course, this (again procedural) implementation is far from an ideal set-based approach, which probably explains why most SQL encoders turn a blind eye to the requirement of a 1: 1..N relationship and instead assume a constructor meant 1: 0. .N !!