04 / 32 · 5 min
How many, and must there be one
A drawing with boxes and lines says two things connect. It does not say how many, or whether the connection is optional. Those two questions decide what the tables look like.
Cardinality: how many
One to one. A person and their passport. Rare in practice, and usually a sign the two should be one table unless you are separating rarely used columns.
One to many. A customer and their orders. The overwhelming majority of real relationships.
Many to many. A student and their courses. A student takes several, a course holds several.
Participation: must there be one
Total participation means every row must take part. Every order must have a customer. Partial means it may not. A customer may have no orders.
The two questions combine into the four cases, and each one lands somewhere different in the schema:
| Relationship | Where the link lives |
|---|---|
| One to one | foreign key on either side, UNIQUE |
| One to many | foreign key on the many side |
| Many to many | a separate table holding both keys |
Why one to many puts the key on the many side
A customer has many orders. Putting a list of order identifiers on the customer row breaks the first normal form and cannot be indexed usefully. Putting customer_id on each order is one value per row, and finding a customer's orders is an index lookup.
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INT NOT NULL REFERENCES customers(id)
);NOT NULL here is the total participation: an order without a customer is not allowed. Drop it and participation becomes partial.
Many to many always becomes a table
CREATE TABLE enrolments (
student_id INT REFERENCES students(id),
course_id INT REFERENCES courses(id),
enrolled_on DATE NOT NULL,
grade TEXT,
PRIMARY KEY (student_id, course_id)
);That table is often where the interesting columns live. The enrolment date and the grade belong to the pair, not to the student and not to the course, and there is nowhere else they could go. Noticing that is usually what turns a confusing design into an obvious one.