1:1 / 1:N / N:M,
질문 하나로 전부 갈립니다
4-2에서 잡은 부모-자식 관계 — 그 안에는 세 가지 형태가 있습니다. 1:1, 1:N, N:M. 셋을 구분하는 질문은 단 하나, "한 X가 여러 Y를 가질 수 있나? 그 반대도?" 이 세 개만 구분할 줄 알면 모델링의 90%가 풀립니다.
이번 섹션의 여정
완료 ✓
지금 여기
관계를 DB가 강제
모델링 완성
다음 마일스톤
식별 질문은 단 하나입니다
세 관계를 구분하겠다고 정의 세 개를 외울 필요가 없습니다. 던질 질문은 딱 하나 — 단, 양쪽에 다 던집니다.
“한 X 가 여러 Y 를 가질 수 있나? 그 반대도?” — 두 질문의 답 조합으로 세 관계가 전부 갈립니다.
| 한 X 가 여러 Y? | 한 Y 가 여러 X? | 결과 |
|---|---|---|
| NO | NO | 1:1 |
| YES | NO | 1:N |
| YES | YES | N:M |
외울 게 없어요. “항상 양쪽 다 물어본다” — 이것만 기억하면 됩니다. 이제 흔한 순서대로 하나씩 보겠습니다.
1:N — 실무 데이터의 90%
가장 흔한 형태부터. 회원과 주문에 식별 질문을 양쪽으로 던져보면 —
| 질문 | 답 |
|---|---|
| 한 회원이 여러 주문을 가질 수 있나? | YES — 한 명이 100번 살 수 있죠 |
| 한 주문이 여러 회원을 가질 수 있나? | NO — 한 주문은 한 사람 것 |
한쪽만 YES — 그래서 회원 1 : 주문 N. 말로만 하지 말고 우리 shop DB에서 눈으로 확인해볼까요.
SELECT
order_id,
ordered_at
FROM
orders
WHERE
member_id = 1; -- 1번 회원 김철수의 주문| order_id | ordered_at |
|---|---|
| 1 | 2025-02-01 |
| 6 | 2025-04-10 |
| 14 | 2025-08-01 |
| 20 | 2025-10-12 |
| 27 | 2025-12-10 |
| 34 | 2026-02-15 |
한쪽에만 “여러”가 붙으면 1:N — 그리고 4-2에서 찾은 shop의 부모-자식 4쌍은 전부 이 형태입니다.
N:M — 양쪽 다 “여러”
이번엔 주문과 상품. 같은 질문을 양쪽으로 —
| 질문 | 답 |
|---|---|
| 한 주문이 여러 상품을 가질 수 있나? | YES — 장바구니에 5개 담아 한 번에 주문 |
| 한 상품이 여러 주문에 들어갈 수 있나? | YES — 인기 상품은 1000번 팔리죠 |
양쪽 다 YES — 주문 N : 상품 M. 이것도 shop 데이터로 양방향을 직접 확인해봅니다.
-- 한 상품이 여러 주문에: 22번 상품(SQL 입문서)이 담긴 주문들
SELECT
order_id
FROM
order_items
WHERE
product_id = 22;
-- 한 주문에 여러 상품이: 25번 주문에 담긴 상품들
SELECT
product_id,
quantity
FROM
order_items
WHERE
order_id = 25;| product_id | quantity |
|---|---|
| 27 | 1 |
| 28 | 1 |
| 30 | 1 |
N:M 은 직접 못 만듭니다 — 중간 테이블
여기가 이 강의에서 제일 중요한 지점입니다.
DB 는 N:M 을 직접 표현하지 못합니다. 항상 중간 테이블로
풀어줍니다 — shop 에서는 order_items 가 바로 그 중간
테이블입니다.
4-2에서 order_items 가 두 부모(orders, products)를 가진 자식이었던 게 기억나시나요? 그게 바로 N:M 이 풀린 모습이었던 겁니다. 이 패턴은 도메인만 바뀔 뿐 어디서나 똑같이 나옵니다.
| 도메인 | N:M 관계 | 중간 테이블 |
|---|---|---|
| 쇼핑몰 | 주문 ↔ 상품 | order_items |
| 학원 | 학생 ↔ 강의 | enrollments |
| 블로그 | 게시글 ↔ 태그 | post_tags |
| SNS | 사용자 ↔ 사용자 (팔로우) | follows |
FK 를 두 개 들고 양쪽 부모 사이에 끼어 있는 테이블 — 이런 중간 테이블이 보이면 거의 항상 N:M 관계입니다. N:M 은 ERD 에 항상 “중간 테이블이 끼어있다” 로 나타나요.
order_items 의 PK 는 (order_id, product_id) 복합키입니다. 한 주문에
같은 상품이 두 줄로 못 들어가게 막는 — 중간 테이블의 전형적인 설계예요.
1:1 — 가장 드문 형태
마지막으로 회원과 회원프로필. 양쪽 다 물어보면 —
| 질문 | 답 |
|---|---|
| 한 회원이 여러 프로필을 가질 수 있나? | NO — 한 사람당 1개 |
| 한 프로필이 여러 회원에게 속할 수 있나? | NO |
양쪽 다 NO — 1:1. 그런데 1:1 은 보자마자 자연스러운 의문이 듭니다. “어차피 1개씩 짝인데, 굳이 테이블을 쪼개야 하나?” — 맞는 의문이에요.
굳이 안 쪼갭니다
1:1 이면 두 테이블을 합쳐도 행 수가 안 늘어납니다. “그냥 컬럼으로 넣으면 되잖아?” — 그래서 실무에서 1:1 은 거의 안 씁니다. shop 에도 1:1 은 하나도 없죠.
크기 · 보안 · 선택 정보
① 테이블이 너무 커서 자주 안 쓰는 컬럼을 분리하고 싶을 때 ② 보안 — 주민번호·결제정보 같은 민감 정보를 별도 테이블로 ③ 선택적 정보 — 가입 시 필수가 아니고 나중에 채우는 정보 (프로필 사진, 자기소개).
세 관계 한눈 정리
| 관계 | 두 질문의 답 | 실무 빈도 | 대표 예 |
|---|---|---|---|
| 1:1 | 양쪽 다 NO | 드묾 | 회원 ↔ 회원프로필 |
| 1:N | 한쪽만 YES | 가장 흔함 — 약 90% | 회원 → 주문 |
| N:M | 양쪽 다 YES | 중간 — 항상 중간 테이블 동반 | 주문 ↔ 상품, 학생 ↔ 강의 |
식별 질문 — “한 X 가 여러 Y? 한 Y 가 여러 X?” · N:M 신호 — ERD 에 중간 테이블이 끼어있다.
AI 에게 관계 종류까지 알려주세요
4-2에서 부모-자식 관계를 명시하면 AI 의 SQL 정확도가 확 올라간다고 했죠. 거기에 관계 종류 한 줄을 더하면 정확도가 한 단계 더 올라갑니다.
[관계]
- members 1:N orders
- orders 1:N order_items
- categories 1:N products
- orders N:M products (중간 테이블: order_items)AI 가 JOIN 방향(어느 테이블에서 어느 테이블로 타고 갈지)과 GROUP BY 단위(1쪽 기준으로 묶을지, N쪽 기준으로 묶을지)를 정확히 잡습니다. 3-7에서 본 JOIN 뻥튀기도 — N:M 을 미리 알려주면 AI 가 알아서 피해 갑니다.
자주 막히는 지점
식별 질문의 답으로 충분하지만, 테이블 구조로도 즉시 판별됩니다.
orders 가 member_id 를 들고 있으니 orders 가 N 쪽.한 방향만 물어보고 결론 내리는 게 가장 흔한 실수입니다. 질문은 항상 두 번.
ERD 에 N:M 이라고 써 있는 경우는 없습니다 — 항상 1:N 두 쌍으로 풀린 모습으로 그려져요.
order_items 처럼 양쪽 부모 사이에 끼어 있으면 N:M 신호입니다.부모-자식(4-2)에 관계의 세 종류(4-3)까지 — 이제 관계를 읽는 눈은 갖췄습니다. 다음 강의는 4-4 외래키(FK)와 데이터 무결성 — 이 부모-자식 관계를 DB 가 어떻게 강제하는지 봅니다. 그 전에, 식별 질문이 손에 익었는지 연습 문제로 확인하고 가세요.