Bảng trung gian không còn là "bảng nối kỹ thuật" nữa mà trở thành một thực thể có tên riêng.
Đặt tên theo nghiệp vụ (enrollments, memberships, subscriptions) rồi cho nó cột dữ liệu như bảng bình thường.
create table enrollments (
student_id bigint not null references students(id),
course_id bigint not null references courses(id),
enrolled_at timestamptz not null default now(),
grade numeric(4,2),
status text not null default 'active',
primary key (student_id, course_id)
);Khoá chính composite hay surrogate id?
- primary key (student_id, course_id) diễn đạt đúng ràng buộc "một sinh viên chỉ đăng ký một môn một lần" và không tốn index thừa.
- Thêm id bigserial khi bảng này lại được bảng khác tham chiếu (vd assignments trỏ về một lần đăng ký), hoặc khi ORM/framework yêu cầu khoá chính đơn cột. Lúc đó vẫn phải giữ unique (student_id, course_id) — bỏ nó là mở đường cho bản ghi trùng.
Một dấu hiệu để nhận ra tình huống này: nếu có lúc cùng một cặp được phép xuất hiện nhiều lần (đăng ký lại ở học kỳ sau) thì khoá chính phải bao gồm cột phân biệt, ví dụ primary key (student_id, course_id, term_id).