본문 바로가기
C.W.K.
Stream
Lesson 08 of 10 · published

일대다와 다대다 관계

~14 min · schema, relationships

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

대부분의 관계를 설명하는 두 모양

일대다에서는 한 부모가 여러 자식을 가질 수 있고 자식은 부모 1개를 가리켜. 고객과 주문이 대표적이야. 다대다에서는 양쪽 모두 여러 상대와 연결되므로 두 외래 키를 가진 연결 테이블을 사이에 둬.

일대일은 제약을 더한 일대다야

자식의 외래 키에 UNIQUE를 더하면 부모 1개당 자식 1개만 허용할 수 있어. 별도 테이블로 나눌 이유가 없다면 같은 테이블의 열로 두는 편이 단순하고, 보안·선택적 존재·수명 주기가 다를 때 분리해.

연결 테이블도 독립된 데이터야

다대다 값을 'red,blue,green' 같은 문자열 한 칸에 넣지 마. 연결 테이블은 등록 시각, 역할, 수량처럼 관계 자체의 속성을 담을 수 있어. 예를 들어 enrollments는 학생과 강좌를 잇는 동시에 등록 기록이라는 정식 개념이야.

Code

일대다 관계인 저자와 책·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);
추가 정보를 담는 다대다 연결 테이블·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)
);
연결 테이블을 거쳐 조회하기·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

프로젝트의 다대다 관계를 하나 고르거나 새로 가정해서 연결 테이블을 설계해. 관계 자체가 가져야 할 추가 열을 포함하고, 그 열이 양쪽 기본 테이블이 아니라 연결 테이블에 속하는 이유를 설명해.

Progress

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

댓글 0

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

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