데이터베이스를 설계한다는 건 단순히 테이블을 만드는 일이 아니다. 현실 세계의 구조를 데이터로 옮기는 모델링 과정이다.
데이터베이스를 처음 설계할 때는 보통 세 단계를 거친다.
이 중 우리가 오늘 집중할 부분은 개념적 설계, 즉 ERD(Entity Relationship Diagram)다.
한 데이터가 다른 데이터와 딱 하나씩만 연결되는 관계다.
User ── 1:1 ── UserProfile
한 명의 사용자에게 프로필이 정확히 하나만 존재하는 구조다. 실무에서는 자주 등장하진 않지만, 보안상 민감한 정보를 분리하거나 성능 최적화를 위해 활용된다.
게시판 서비스를 예시로 보자.
User ── 1:N ── Post
여기서 핵심 규칙이 하나 있다.
N 쪽 테이블이 FK(Foreign Key)를 가진다.
그래서 Post 테이블은 이렇게 생긴다.
Post
├── post_id (PK)
├── user_id (FK) ← 작성자를 가리키는 외래키
├── title
└── content
유저가 게시글에 좋아요를 누르는 기능을 생각해보자.
User ── N:N ── Post
그런데 관계형 데이터베이스에서는 N:N 관계를 직접 구현하지 않는다. 대신 중간 테이블(Associative Table) 을 만들어 두 개의 1:N 관계로 분해한다.
Like
├── like_id (PK)
├── user_id (FK)
├── post_id (FK)
└── created_at
이렇게 하면 Like 테이블의 한 row는 이런 의미를 갖는다.
"user_id=3 인 유저가 post_id=7 인 게시글에 좋아요를 눌렀다."
그리고 분해된 관계는 다음과 같다.
User ── 1:N ── Like
Post ── 1:N ── Like
한 유저가 같은 게시글에 좋아요를 두 번 누르면 안 되므로, DB 레벨에서 UNIQUE 제약 조건을 걸어준다.
UNIQUE (user_id, post_id)
이 한 줄로 중복 좋아요를 애플리케이션 로직이 아닌 데이터베이스 수준에서 방지할 수 있다.
댓글(Comment)은 FK가 두 개인 케이스다.
댓글은 반드시 두 가지를 알아야 한다.
1. 어떤 게시글에 달린 댓글인지 → post_id
2. 누가 작성한 댓글인지 → user_id
Comment
├── comment_id (PK)
├── post_id (FK)
├── user_id (FK)
└── content
따라서 다음 두 가지 관계가 동시에 성립한다.
Post ── 1:N ── Comment
User ── 1:N ── Comment
지금까지 살펴본 게시판 서비스의 ERD 관계를 정리하면 다음과 같다.
User ── 1:N ── Post
User ── 1:N ── Comment
Post ── 1:N ── Comment
User ── 1:N ── Like
Post ── 1:N ── Like
(User ↔ Post 간의 N:N 좋아요 관계는 Like 중간 테이블로 분해됨)
ERD 설계에서 가장 중요한 건 현실 세계의 구조를 기반으로 생각하는 것이다.
이 질문들에 답하다 보면 자연스럽게 테이블 구조와 FK의 위치가 결정된다. 테이블을 먼저 생각하지 말고, 현실의 관계를 먼저 생각하자.
잘못된 내용이나 보완할 부분이 있다면 댓글로 알려주세요! 🙏