본문 바로가기
C.W.K.
Stream
Lesson 07 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

다른 테이블의 행을 가리키는 약속

외래 키는 이 열의 값이 다른 테이블에 실제로 존재해야 한다고 선언해. PostgreSQL은 INSERT와 UPDATE 때마다 확인하므로, 존재하지 않는 고객을 가리키는 주문 같은 고아 데이터가 생기지 않아.

삭제할 때의 네 가지 선택

  • RESTRICT 또는 NO ACTION은 참조하는 행이 있으면 부모 삭제를 막아.
  • CASCADE는 부모와 함께 소유된 자식도 지워. 주문과 주문 항목처럼 생명 주기가 묶인 관계에 써.
  • SET NULL은 부모가 사라져도 자식은 남기고 외래 키만 비워. 열이 NULL을 허용해야 해.
  • SET DEFAULT는 미리 정한 기본값으로 바꾸며, 그 값 역시 유효한 참조여야 해.

갱신 규칙도 따로 정할 수 있어

ON UPDATE는 부모 키가 바뀔 때 자식 키를 어떻게 다룰지 정해. 안정적인 대리 키는 애초에 바뀌지 않게 설계하는 편이 낫지만 자연 키를 쓴다면 동작을 명시해야 해. 외래 키 자체가 참조하는 쪽의 색인을 자동으로 만들어 주지는 않는다는 점도 기억해.

Code

부모와 자식 관계 만들기·sql
CREATE TABLE departments (
    id   INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name TEXT UNIQUE NOT NULL
);

CREATE TABLE employees (
    id            INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name          TEXT NOT NULL,
    department_id INTEGER REFERENCES departments(id) ON DELETE SET NULL
);

-- 됨:
INSERT INTO departments (name) VALUES ('Engineering');
INSERT INTO employees (name, department_id) VALUES ('Alice', 1);

-- 거절:
INSERT INTO employees (name, department_id) VALUES ('Bob', 99);
-- ERROR: insert or update on table "employees" violates foreign key constraint
부모가 소유하는 자식에 CASCADE 적용·sql
CREATE TABLE orders (
    id       INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    customer_id INTEGER NOT NULL REFERENCES customers(id) ON DELETE RESTRICT,
    placed_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE order_items (
    id        INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    order_id  INTEGER NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
    product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE RESTRICT,
    quantity  INTEGER NOT NULL CHECK (quantity > 0)
);
-- order 삭제 → item 삭제 cascade.
-- order 있는 customer 삭제 → 거절 (RESTRICT).

External links

Exercise

가지고 있는 스키마에서 부모와 자식 관계 하나를 골라 현재 ON DELETE 동작을 한 문장으로 설명해. 이유를 모른다면 실제 동작을 확인하고 선택 근거를 문서화해.

Progress

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

댓글 0

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

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