다대다 관계를 이해하고 올바르게 설계하는 것은 데이터 모델링의 핵심 역량 중 하나다. 하지만 놀랍게도, 관계형 데이터베이스는 테이블 두 개만으로 다대다(M:N) 관계를 표현할 수 없다.
관계형 데이터베이스의 기본 제약
진행하기 전에 관계형 데이터베이스의 기본 제약을 다시 확인해보자.
관계형 데이터베이스에서 테이블의 행(row)은 다음과 같은 특징을 가진다.
- 기본 키(PK)는 반드시 유일하다.
- 한 테이블 안에서 동일한 PK를 가진 행은 존재할 수 없다.
- 외래 키(FK)는 단일 행만 참조한다.
- 외래 키 값 하나는 상대 테이블의 정확히 한 행만 가리킨다.
- 컬럼은 원자적(atomic)이어야 한다.
- 하나의 컬럼에 여러 값을 넣을 수 없다(제1 정규형).
두 테이블로 다대다 관계 시도

- 100번 주문이 청바지(1), 티셔츠(2)라는 상품을 둘 다 주문했다.
- 101번 주문이 청바지(1) 상품을 주문했다.
- 하나의 주문은 여러 상품을 주문할 수 있다.
- 100번 주문은 청바지(1), 티셔츠(2)를 주문한다.
- 하나의 상품은 여러 주문에 포함될 수 있다.
- 청바지(1) 상품은 100번, 101번 주문에 포함된다.
1. orders 테이블에 외래 키를 두는 방법
orders 테이블

- 이 설계는 제약 2, 제약 3을 위반한다.
- 외래 키는 단일 행만 참조하는 제약 2를 위반했다.
- 컬럼은 원자적이어야 하는 제약 3을 위반했다.
제약 2, 제약 3을 만족하려면 다음과 같이 변경해야 한다.

- 하지만 이 설계는 제약 1을 위반한다.
- 기본 키는 반드시 유일해야 하므로 다음과 같이 100번 주문의 행을 더 늘릴 수는 없다.
- 기본 키는 반드시 유일해야 한다는 제약1을 위반하기 때문에 적용할 수 없다.
따라서 orders 테이블에 외래 키를 둘 수 없다.
2. product 테이블에 외래 키를 두는 방법
product 테이블

- 청바지는 주문 100, 101 두 번 주문되었다.
- 이 설계는 제약 2, 제약 3을 위반한다.
- 외래 키는 단일 행만 참조하는 제약 2를 위반했다.
- 컬럼은 원자적이어야 하는 제약 3을 위반했다.
제약 2, 제약 3을 만족하려면 다음과 같이 변경해야 한다.

- 하지만 이 설계는 제약 1을 위반한다.
- 기본 키는 반드시 유일해야 하므로 다음과 같이 1번 상품의 행을 더 늘릴 수는 없다.
- 기본 키는 반드시 유일해야 한다는 제약 1을 위반하기 때문에 적용할 수 없다
따라서 product 테이블에 외래 키를 둘 수 없다.
결과적으로 product, orders 어디에 외래 키를 두더라도 관계형 데이터베이스의 기본 제약을 위반하게 된다. 따라서 다대다 관계를 표현할 수 없다.
관계형 데이터베이스의 한계와 다른 패러다임
관계형 데이터베이스는 테이블 두 개만으로 다대다(M:N) 관계를 표현할 수 없다.
이처럼 테이블 두 개만으로는 양쪽의 '다(Many)' 관계를 모두 수용할 수 없는 것이 관계형 데이터베이스의 본질적인 한계다. 그렇다고 일대다 관계에서 살펴봤던 것처럼, 하나의 컬럼에 여러 상품 ID를 쉼표로 구분해서 넣는 "1,2,3"과 같은 방식은"제1 정규형"을 위반하고, 인덱스를 사용할 수 없으며, 데이터 수정이 복잡해지는 등 모든 면에서 최악의 설계다. 여러 컬럼(product_id_1, product_id_2, ...)을 두는 것 또한 확장성이 없고 문제가 많다.
이것이 바로 관계형 데이터베이스의 한계이자 특징이다. 테이블의 각 컬럼은 원자적인(atomic) 값 하나만 가져야 한다는 강력한 제약 덕분에 데이터 정합성을 지킬 수 있지만, 그 대가로 다대다 같은 유연한 관계는 직접 표현하지 못하는 것이다. 이것은 관계형 데이터베이스가 외래 키 하나로 단일 행을 가리키는 방식으로 관계를 맺기 때문에 발생하는 구조적인 한계다.
다른 패러다임에서는??
1) JAVA
class Order {
List<Product> products; // 주문은 상품 목록을 가진다.
}
class Product {
List<Order> orders; // 상품은 주문 목록을 가진다.
}
- 각 객체가 상대방 객체의 목록(List)을 직접 참조하면 그만이다.
2) NoSQL
// 주문(Order) 문서
{
"order_id": 1001,
"ordered_at": "2025-08-15",
"products": [ // 주문한 상품 정보를 배열로 포함
{ "product_id": 1, "name": "노트북", "price": 1500000 },
{ "product_id": 5, "name": "마우스", "price": 25000 }
]
}
- MongoDB 같은 문서 데이터베이스에서는 하나의 "문서(Document)" 안에 다른 데이터를 배열 형태로 포함할 수 있어 "M:N" 관계를 비교적 쉽게 표현할 수 있다.
'데이터 베이스 > 설계 1편, 현대적 데이터 모델링 완전 정복' 카테고리의 다른 글
| Ch07. 논리적 모델링(4) - 식별, 비식별 관계의 개념 (0) | 2026.06.27 |
|---|---|
| Ch06. 논리적 모델링(3) - 다대다 관계 개념적, 논리적 모델링 (0) | 2026.06.26 |
| Ch06. 논리적 모델링(3) - 다대다 관계 속성 (0) | 2026.06.26 |
| Ch06. 논리적 모델링(3) - 다대다 관계 연결 테이블 (0) | 2026.06.26 |
| Ch06. 논리적 모델링(3) - 일대일 주 테이블에 FK (0) | 2026.06.25 |