I'm working on a database schema involving four tables: A, B, C, and D. The relationships among these tables are as follows:
- Table
Acan have one or many records from TableB. - Table
Ccan have one or many records from TableD. - There is a many-to-many relationship between Tables
AandC, forming a weak entity (joint table) "AC".
CREATE TABLE A (
id INT PRIMARY KEY
);
CREATE TABLE B (
id INT PRIMARY KEY,
a_id INT,
FOREIGN KEY (a_id) REFERENCES A(id)
);
CREATE TABLE C (
id INT PRIMARY KEY
);
CREATE TABLE D (
id INT PRIMARY KEY,
c_id INT,
FOREIGN KEY (c_id) REFERENCES C(id)
);
CREATE TABLE AC (
a_id INT,
c_id INT,
PRIMARY KEY (a_id, c_id),
FOREIGN KEY (a_id) REFERENCES A(id),
FOREIGN KEY (c_id) REFERENCES C(id)
);
My requirements : For each AC record, I need to link the Bs associated with its A to the Ds associated with its C.
Explanations : This looks like a ternary relationship involving AC, B and D : In the context of an AC record, a B needs to be linked to a D. But we have the added constraints of the B needing to belong to the A of the AC record, and the D needing to belong to the C of the same AC record.
What I've tried : I've tried creating a simple "assignment" table which references AC, B and D. However, I couldn't enforce the constraints mentioned above.
CREATE TABLE assignment (
id INT PRIMARY KEY,
ac_a_id INT, -- Foreign key referencing 'a_id' in AC
ac_c_id INT, -- Foreign key referencing 'c_id' in AC
b_id INT, -- Foreign key referencing 'id' in B
d_id INT, -- Foreign key referencing 'id' in D
FOREIGN KEY (ac_a_id, ac_c_id) REFERENCES AC(a_id, c_id),
FOREIGN KEY (b_id) REFERENCES B(id),
FOREIGN KEY (d_id) REFERENCES D(id)
);
What would be a good approach to model this relationship? Are there specific SQL constructs or design patterns that would best fit this scenario?
Thanks for your help.

While
ACis a weak entity, it is more properly referred to as an associative table (also called a bridge table). There isn't any need for an "assignment" table referencingAC,B, andD, you've already modeled the relationship betweenBandD. To demonstrate, run the following commands to create and populate the tables:The following query returns the associated rows from
BandDthroughAC:The output from the preceding query is:
The following query demonstrates the "link" between
BandD:The output shows that the row in
Bwithid= 203 is associated withDrows withids of 402 and 403: