Relationships
A relationship is a foreign key linking a child table to a parent’s
primary key. In the example library each
book is written by one author, so books (the child) points at authors (the
parent):
add 1:n relationship as books_author from authors.author_id to books.author_id on delete cascadeYou name the relationship with as <name> (here books_author), then give the
parent endpoint from authors.author_id and the child endpoint
to books.author_id. The 1:n reads “one author, many books”.
Viewing a relationship
Section titled “Viewing a relationship”show relationship draws the two tables and the link between them:
show relationship books_author┌───────────────────────┐ ┌───────────────────────────┐│ books │ │ authors │├──────────────┬────────┤ ├──────────────────┬────────┤│ book_id (PK) │ serial │ ┌──────1▶│ author_id (PK) ● │ serial ││ title │ text │ │ │ name │ text ││ author_id ● │ int │n────────┘ │ birth_year │ int ││ published │ int │ └──────────────────┴────────┘│ isbn │ text │└──────────────┴────────┘ on delete cascade · on update no actionRead the diagram like this:
- The child (the table holding the foreign key) is on the left; the parent is on the right.
- A filled dot ● marks each column that takes part in the link.
- The connector runs
n…1— many child rows to one parent row — and the ▶ arrowhead points at the parent key. - The line beneath records the referential actions (below).
A table’s own show table includes a compact Relationships section that
summarises every link it takes part in:
show table booksbooks┌───────────┬────────┬─────────────┐│ Name │ Type │ Constraints │├───────────┼────────┼─────────────┤│ book_id │ serial │ PK ││ title │ text │ NOT NULL ││ author_id │ int │ ││ published │ int │ ││ isbn │ text │ UNIQUE │└───────────┴────────┴─────────────┘Relationships┌─────────────┐ ┌─────────────┐│ books │ │ authors │├─────────────┤ ├─────────────┤│ author_id ● │n───────────────1▶│ author_id ● │└─────────────┘ └─────────────┘ on delete cascade · on update no actionFor a one-line summary of every relationship in the project, use show relationships (see Querying & inspecting).
Referential actions
Section titled “Referential actions”on delete and on update decide what happens to the child rows when a parent
row is deleted or its key changes. The action is one of:
| Action | Effect on the children |
|---|---|
cascade | The children are deleted / updated to match. |
set null | The children’s foreign-key column is set to empty. |
restrict | The change is refused while children still reference the row. |
With on delete cascade, deleting an author removes that author’s books too,
and the result reports each affected relationship:
delete from authors where author_id = 3 1 row(s) deleted related: 1 row(s) deleted in `books` for relationship `books_author` (on delete cascade)Creating the child column at the same time
Section titled “Creating the child column at the same time”If the child column does not exist yet, add --create-fk and the playground
creates it for you with the right type:
add 1:n relationship as loans_member from members.member_id to loans.member_id --create-fkCompound keys
Section titled “Compound keys”To reference a parent’s compound primary key, list the columns on each side, matched in order:
add 1:n relationship from <Parent>.(<a>, <b>) to <Child>.(<x>, <y>)Many-to-many relationships
Section titled “Many-to-many relationships”When two tables relate many-to-many — a student takes many courses, and a
course has many students — you model it with a junction table (also called
a bridge table) that holds a foreign key to each side. create m:n relationship builds that junction for you in one step:
create m:n relationship from Students to CoursesAssuming each parent has a primary key id, this creates a table named
Students_Courses with:
- one foreign-key column per primary-key column of each parent —
Students_idandCourses_id, typed to match the keys they reference; - a compound primary key over those columns, so the same pair can never be linked twice;
- two
1:nrelationships (junction →Students, junction →Courses), each withon delete cascadeandon update cascade— delete a student or a course and its link rows go with it.
The junction is an ordinary table afterwards: rename table, drop table,
insert, or add column all work on it. To choose the name yourself, add
as <name>:
create m:n relationship from Students to Courses as EnrollmentsA few rules keep it predictable:
- Both parents need a primary key — that is what the junction references.
- The two tables must be different; there is no self-referential shorthand. To link a table to itself, build the junction by hand.
- The generated foreign keys always cascade. If you need different
referential actions, or extra columns on the link
from the start (a loan date, say), build the junction by hand instead — a
create tableplus twoadd 1:n relationshipcommands, as the library guide does for itsloanstable.
Removing a relationship
Section titled “Removing a relationship”drop relationship books_authorIn advanced mode
Section titled “In advanced mode”Relationships are ordinary foreign keys, declared with FOREIGN KEY … REFERENCES either inline at CREATE TABLE or added later with ALTER TABLE:
alter table books add foreign key (author_id) references authors (author_id) on delete cascadeSyntax
Section titled “Syntax”add 1:n relationship [as <Name>] from <Parent>.<col> to <Child>.<col> [on delete <action>] [on update <action>] [--create-fk]create m:n relationship from <T1> to <T2> [as <Name>]drop relationship <Name>See also Indexes and Types (why a foreign-key column’s type can differ from the key it references).