Insights·2026-09-29

ERD에서 컬럼으로 둘까, 테이블로 뺄까 — 여러 개 붙으면 테이블이다

대상 하나에 값이 하나만 붙으면 컬럼으로 두고, 여러 개 붙을 수 있으면 테이블로 따로 뺀다. 모바일 청첩장이라면 제목·날짜·장소는 청첩장의 컬럼이고, 하객이 남기는 축하글은 여러 개라 별도 테이블이 된다. 이렇게 하나에 여럿이 붙는 1:N 관계가 가장 흔하고, ERD는 선 끝의 짝대기·동그라미·세 갈래 기호로 이를 표시한다. 라이브 스트리밍 링크처럼 없거나 하나인 값은 컬럼으로 충분하고, 템플릿 1·2·3처럼 정해 둔 값도 계속 늘리고 빼야 하는 순간 테이블로 승격한다.

값이 하나면 컬럼, 여러 개 붙으면 테이블 — 글의 요약 도식

기준은 하나 — 여러 개 붙는가

ERD는 서비스가 무엇을 관리하고 그것들이 서로 어떻게 이어지는지 그린 그림이다. Entity Relationship Diagram의 줄임말로, 관리 대상 하나(엔티티)가 데이터베이스에서는 엑셀 표 같은 테이블 하나가 된다. 표의 세로 칸 하나가 컬럼, 가로 한 줄이 데이터 한 건이다.

강의는 모바일 청첩장 서비스로 설명한다. 관리자가 로그인해서 청첩장을 만든다. 여기서 관리 대상은 관리자와 청첩장 둘이다. 청첩장에 들어가는 제목·날짜·장소·메시지·신랑 이름·신부 이름은 따로 관리할 대상이 아니라 청첩장의 속성이라 청첩장 테이블의 컬럼이 된다.

서비스가 잘 돌자 기능을 하나 더한다. 하객이 '축하해' 같은 축하글을 남기는 기능이다. 축하글은 새로 쓰고, 고치고, 지울 수 있어야 한다. 이걸 청첩장 테이블의 컬럼으로 붙일 수 있을까.

청첩장 하나에 축하글이 딱 하나만 달린다면 붙여도 된다. 굳이 테이블을 따로 만들 필요가 없다. 그런데 결혼식 하나에는 하객 여럿이 축하글을 남긴다. 칸 하나에는 값을 하나만 넣을 수 있으니 이 방식은 불가능하다. 그래서 축하글을 별도 테이블로 빼고 청첩장과 선으로 잇는다.

강의가 강조하는 감각이 이것이다. 어떤 값이 하나만 존재하면 컬럼, 여러 개 생길 수 있으면 테이블이다. 기능을 더할 때마다 이 값이 대상 하나에 몇 개 붙는지를 먼저 묻는다.

축하글이 하나뿐이라면 vs 여러 개라면
[하나뿐이라면] invitations 테이블에 컬럼 하나
id  title          greeting
1   우리 결혼합니다   축하해

[여러 개라면] greetings 테이블로 따로
id  invitation_id  content
1   1              축하해
2   1              행복하게 살아
3   1              결혼 축하드립니다

1:N, 부모와 자식 — 선 끝 기호 읽는 법

테이블 사이의 관계는 대부분 1:N이다. 하나에 여럿이 붙는 관계라는 뜻이다. 관리자 한 명이 청첩장을 여러 장 만들고, 청첩장 한 장에는 축하글이 여러 개 달린다. 둘 다 1:N이다.

하나 쪽을 부모, 여럿 쪽을 자식이라고 부른다. 청첩장은 자기를 만든 관리자 한 명만 바라보니 관리자가 부모이고 청첩장이 자식이다. 자식 테이블에는 부모의 id를 적는 컬럼을 둔다. 청첩장 테이블의 admin_id, 위 예시에서 축하글 테이블의 invitation_id가 그런 칸이다. 이렇게 다른 테이블의 줄을 가리키는 컬럼을 외래 키라고 부른다.

ERD에서는 관계가 있는 두 테이블 사이에 선을 긋고, 선 끝의 모양으로 개수를 표시한다. 하나인 쪽은 짝대기, 여럿인 쪽은 선 끝이 세 갈래로 벌어진 모양이다. 새 발을 닮아 까마귀발 표기법이라고 부른다.

반드시 있어야 하는지도 같은 자리에 적는다. 반드시 있으면 짝대기, 없을 수도 있으면 동그라미다. 관리자가 청첩장을 아직 한 장도 안 만들었을 수 있으니 청첩장 쪽 끝에는 동그라미와 세 갈래가 겹친다. 반대로 청첩장은 관리자 없이는 생기지 않으니 부모 쪽 끝은 보통 짝대기 두 개다.

선 끝의 기호 두 개 중 테이블에 가까운 쪽이 최대 개수, 테이블에서 먼 쪽(선 가운데 쪽)이 최소 개수를 뜻한다. AI가 그려 준 ERD에서 이 기호만 읽어도 서비스가 무엇을 허용하는지 보인다.

기호자리뜻
짝대기 |테이블에 가까운 쪽최대 하나
세 갈래 {테이블에 가까운 쪽여럿
짝대기 |테이블에서 먼 쪽반드시 하나 이상(필수)
동그라미 o테이블에서 먼 쪽없어도 된다(선택)
청첩장 서비스의 관계를 기호로
관리자 ||--o{ 청첩장        관리자 한 명에 청첩장 0장 이상
청첩장 ||--o{ 축하글        청첩장 한 장에 축하글 0개 이상
청첩장 ||--o| 라이브스트림  청첩장 한 장에 링크 0개 또는 1개

하나뿐인데 따로 빼는 경우 — 선택적 1:1

이번에는 라이브 스트리밍 기능이다. 결혼식에 직접 오지 못하는 하객을 위해 식을 생중계해 주는 유료 서비스라서, 신청하는 사람도 있고 안 하는 사람도 있다. 결혼식 하나에 라이브 링크는 없거나 하나다. 여러 개일 필요는 없다.

이런 관계를 1:1, 그중에서도 없을 수도 있으니 선택적 1:1이라고 한다. 라이브 스트림을 별도 테이블로 빼면 청첩장 쪽 끝은 짝대기 두 개, 라이브 스트림 쪽 끝은 동그라미와 짝대기로 그린다.

그런데 강의는 굳이 그럴 필요는 없다고 말한다. 청첩장 테이블에 링크 컬럼을 하나 더하고 신청한 사람만 채우면 된다. 하나만 존재하는 값이니 앞의 기준대로 컬럼이다.

따로 빼는 경우는 칸이 너무 자주 비어 있을 때다. 신청자가 열 명에 한 명꼴이라면 나머지 아홉 줄은 그 칸이 비어 있다. 강의는 이렇게 빈칸이 많아 더 효율적으로 관리하고 싶을 때 1:1로 빼기도 한다고 설명한다. 다만 주류 사용법은 아니다. 1:1은 선택지로만 기억하고, 기본은 컬럼이다.

기본은 컬럼, 빈칸이 대부분이면 따로
[기본] invitations 테이블에 컬럼 하나
id  title          live_stream_url
1   우리 결혼합니다   (비어 있음)
2   봄날의 약속      https://live.example.com/abc

[선택] live_streams 테이블로 따로
id  invitation_id  url
1   2              https://live.example.com/abc

enum이던 템플릿이 테이블이 되는 순간

처음 설계에서 템플릿은 1·2·3 세 가지로 정해 두었다. 이렇게 정해 둔 값만 받고 그 밖의 값이 들어오면 오류를 내는 데이터 타입(칸에 들어갈 값의 종류)을 enum이라고 한다. 로그인 수단을 카카오·구글·애플로 한정하는 것과 같은 방식이다.

그런데 템플릿 디자인이 아쉬워 디자이너를 새로 뽑고 템플릿을 계속 늘리고 싶어졌다고 하자. 처음에는 코드를 고쳐 4번을 더하고, 5번을 더하고, 1번을 뺀다. 이런 일이 자꾸 생기면 그때마다 코드나 데이터베이스를 손대는 일이 번거로워진다.

이때 템플릿을 아예 테이블로 만든다. 템플릿마다 자기 id를 갖고(겹치지 않게 만든 아이디용 문자열인 UUID를 쓴다), 청첩장은 enum 컬럼 대신 template_id 컬럼을 갖는다. template_id는 템플릿 테이블의 id를 가리킨다. 템플릿 하나로 청첩장 여러 장을 만들 수 있으니 템플릿과 청첩장은 1:N이고 템플릿이 부모다.

강의가 남기는 시사점은 이것이다. 몇 가지 값으로 정해 둔 것도 나중에 관리해야 할 필요가 생기면 컬럼이 아니라 테이블로 뺄 수 있다. 추가·삭제가 잦아졌다면 그 값은 속성이 아니라 관리 대상이 된 것이다. 다만 이미 쌓인 청첩장의 1·2·3 값을 새 id로 옮기는 작업은 조심해야 하고, 그 이야기는 04편에서 다룬다.

오늘 해볼 일은 AI에게 지금 프로젝트의 테이블 구조를 정리해 달라고 하고 아래 요청문으로 훑어보는 것이다. 다음 편에서는 청첩장 하나를 관리자 여럿이 함께 관리하는 여럿 대 여럿 관계를 중간 테이블로 푸는 법과, 글자로 쓴 코드를 그림으로 바꿔 주는 머메이드(Mermaid)로 AI에게 ERD를 그려 달라고 하는 법을 본다.

enum 컬럼에서 템플릿 테이블로 (id는 줄여 표기)
[전] invitations — template 이 enum
id  title          template
1   우리 결혼합니다   template_1
2   봄날의 약속      template_2

[후] templates 테이블 + template_id
templates
id    name
t-01  클래식
t-02  플라워

invitations
id  title          template_id
1   우리 결혼합니다   t-01
2   봄날의 약속      t-02
AI에게 줄 요청문
지금 프로젝트의 데이터베이스 테이블과 컬럼을 표로 정리해 줘.
그리고 아래 세 가지를 찾아 줘.
1. 여러 개가 들어갈 수 있는 값을 컬럼 하나에 넣어 둔 곳
   (예: greeting1, greeting2 처럼 번호 붙은 컬럼, 쉼표로 이어 적은 값)
2. 대부분의 줄에서 비어 있는 컬럼
3. 정해 둔 값(enum)인데 앞으로 관리자가 추가·삭제해야 할 것
각각 테이블로 빼야 하는지, 컬럼으로 둬도 되는지 이유와 함께 알려 줘.
아직 아무것도 고치지는 마.