C.W.K.
Stream
Lesson 08 of 10 · published

One-to-Many, Many-to-Many

~14 min · schema, relationships

Level 0스키마 새싹
0 XP0/86 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

거의 모든 걸 커버하는 두 모양

대부분 데이터 관계가 두 패턴으로 압축돼:

  • One-to-many: 한 author 가 여러 book 씀; 한 customer 가 여러 order. '여러' 쪽이 '하나' 쪽 가리키는 FK 가짐.
  • Many-to-many: 여러 student 가 여러 course; 여러 post 가 여러 tag. Junction 테이블 + 두 FK 필요.

One-to-one 은 위장한 one-to-many

진짜 1:1 필요하면 보통 FK 에 UNIQUE 제약 건 1:N. (보통 정답은 '테이블 안 나누고 컬럼을 부모에 박기'.)

Junction 테이블이 first-class

students 랑 courses 연결하는 junction 이 hack 아니라 올바른 모양. 자체 데이터 가질 수 있음: enrollment 날짜, 역할, 성적. Composite PK (student_id, course_id) 가 관계 행의 자연스러운 정체성.

Code

One-to-many: author 와 book·sql
CREATE TABLE authors (
    id   INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE books (
    id        INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    title     TEXT NOT NULL,
    author_id INTEGER NOT NULL REFERENCES authors(id) ON DELETE RESTRICT
);

CREATE INDEX books_author_id_idx ON books (author_id);
Junction + 추가 데이터로 many-to-many·sql
CREATE TABLE students (
    id   INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE courses (
    id   INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE enrollments (
    student_id INTEGER NOT NULL REFERENCES students(id) ON DELETE CASCADE,
    course_id  INTEGER NOT NULL REFERENCES courses(id)  ON DELETE CASCADE,
    enrolled_on DATE NOT NULL DEFAULT CURRENT_DATE,
    grade      TEXT,
    PRIMARY KEY (student_id, course_id)
);
Junction 통한 쿼리·sql
SELECT c.name AS course
FROM   enrollments e
JOIN   students s ON s.id = e.student_id
JOIN   courses  c ON c.id = e.course_id
WHERE  s.name = 'Alice'
ORDER  BY c.name;

External links

Exercise

프로젝트의 many-to-many 관계 (또는 발명) 잡고 junction 테이블 설계 — 관계가 가지면 좋을 추가 컬럼 포함. 그 추가 컬럼이 두 메인 테이블이 아니라 junction 에 속하는 이유 설명.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.