개념적·논리적·물리적 데이터 모델의 차이

아티클 · 2026-09-11

"ERD 그려주세요"라는 요청 하나에도 실은 세 가지 서로 다른 결과물이 숨어 있을 수 있습니다. 데이터 모델링은 흔히 개념적(Conceptual) → 논리적(Logical) → 물리적 (Physical) 세 단계를 거치며 점점 구체화됩니다. 이 글은 "고객"이라는 하나의 개념이 세 단계를 지나며 어떻게 달라지는지 끝까지 따라가 봅니다.

왜 세 단계로 나누는가

세 단계를 나누는 이유는 관심사를 분리하기 위해서입니다. 요구사항을 논의하는 자리에서 갑자기 "VARCHAR(255)로 할까요 TEXT로 할까요"라는 이야기가 나오면 비즈니스 담당자는 대화에서 밀려납니다. 반대로 실제 테이블을 만드는 단계에서 "고객이라는 개념이 존재한다" 수준의 추상적인 이야기만 하고 있으면 개발이 진행되지 않습니다. 단계를 나누면 각 단계에 맞는 사람이, 맞는 수준의 디테일로 논의에 참여할 수 있습니다.

개념적 모델(Conceptual Model)

업무 용어로 어떤 대상(엔티티)들이 있고 서로 어떻게 관련되는지만 표현합니다. 데이터 타입, 키, 심지어 속성 목록조차 생략하는 경우가 많습니다. 이 단계의 청중은 비즈니스 담당자·기획자이고, 목표는 "우리가 다루는 도메인을 제대로 이해했는가"를 확인하는 것입니다.

고객 ── 주문 ── 상품
(주문은 한 명의 고객이 내고, 여러 상품을 담을 수 있다)

이 단계에서는 "고객에 이메일이 있는가, 전화번호가 있는가"조차 아직 확정하지 않아도 됩니다. 핵심은 엔티티와 관계 자체가 비즈니스를 정확히 반영하는지입니다.

논리적 모델(Logical Model)

개념적 모델에 속성(attribute), 기본키, 정규화 규칙을 더합니다. 여전히 특정 DBMS에 종속되지 않습니다 — "정수형"이라고는 하지만 MySQL의 INT인지 PostgreSQL의 INTEGER인지는 아직 신경 쓰지 않습니다. 이 단계의 청중은 데이터 모델러·아키텍트이고, 목표는 정규화된 구조와 관계(식별/비식별, 카디널리티)를 정확히 정의하는 것입니다.

엔티티속성기본키
고객고객번호, 이름, 이메일, 가입일고객번호
주문주문번호, 고객번호(FK), 주문일시, 상태주문번호

이 단계에서 이미 정규화식별·비식별 관계 판단이 끝나 있어야 합니다.

물리적 모델(Physical Model)

논리적 모델을 실제 DBMS 문법으로 구체화합니다. 정확한 데이터 타입과 길이, 인덱스, 파티션, NOT NULL·CHECK 같은 제약조건, 그리고 실제 컬럼 네이밍 규칙이 전부 이 단계에서 확정됩니다. 이 단계의 청중은 DBA·백엔드 개발자이고, 산출물은 곧바로 실행 가능한 DDL입니다.

CREATE TABLE customers (
  customer_id  BIGINT       PRIMARY KEY AUTO_INCREMENT,
  name         VARCHAR(50)  NOT NULL,
  email        VARCHAR(255) NOT NULL UNIQUE,
  joined_at    TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE orders (
  order_id     BIGINT       PRIMARY KEY AUTO_INCREMENT,
  customer_id  BIGINT       NOT NULL REFERENCES customers(customer_id),
  ordered_at   TIMESTAMP    NOT NULL,
  status       VARCHAR(20)  NOT NULL DEFAULT 'pending'
);

하나의 예제로 끝까지 — "고객"의 여정

단계"고객"은 무엇인가
개념적주문을 내는 주체. 존재한다는 사실과 주문과의 관계만 확정
논리적고객번호(PK), 이름, 이메일, 가입일이라는 속성을 가진 엔티티. 이메일은 유일해야 한다는 규칙까지 정의됨
물리적customers 테이블. customer_id BIGINT AUTO_INCREMENT, email VARCHAR(255) UNIQUE 등 정확한 타입·제약까지 확정된 실행 가능한 DDL

같은 "고객"이지만 단계마다 다루는 디테일의 수준이 완전히 다릅니다. 개념적 단계의 논의를 건너뛰고 바로 물리적 모델부터 시작하면, 나중에 "사실 이건 고객이 아니라 법인 고객과 개인 고객으로 나뉘어야 했다"는 걸 뒤늦게 발견하고 테이블 구조 전체를 갈아엎어야 하는 일이 생깁니다.

단계를 건너뛰면 생기는 일

현실에서는 세 단계를 늘 순서대로, 따로따로 진행하지는 않습니다. 특히 소규모 프로젝트에서는 개념적 모델 없이 바로 논리적·물리적 모델부터 시작하는 경우가 흔합니다. 그 자체가 잘못은 아니지만, 건너뛴 단계의 질문이 사라지는 건 아니라는 점을 알아둘 필요가 있습니다.

게시판을 예로 들어 보겠습니다. 개념적 논의 없이 바로 posts, comments 테이블부터 만들면, "댓글에 또 댓글을 달 수 있는가(대댓글)", "삭제된 게시글의 댓글은 어떻게 되는가" 같은 질문이 개념 단계에서 미리 정리되지 않은 채로 물리적 설계에 넘어옵니다. 결국 테이블을 만들고 나서야 "아, 대댓글도 지원해야 하는구나"를 깨닫고 comments.parent_comment_id를 뒤늦게 추가하는 식으로 되돌아가게 됩니다. 개념 단계의 질문은 사라지는 게 아니라 나중에 더 비싼 형태(테이블 구조 변경)로 돌아올 뿐입니다.

그래서 실무적인 절충안은 "세 단계를 반드시 별도 문서로 나눠라"가 아니라, 테이블을 만들기 전에 최소한 개념 단계의 질문만큼은 의식적으로 던져 보라는 것입니다 — "이 엔티티가 정말 하나인가, 둘로 나뉘어야 하는가", "이 관계가 정말 이런 카디널리티가 맞는가"를 컬럼 타입을 고민하기 전에 먼저 확인하는 것만으로 충분합니다.

YourERD는 어느 단계인가

YourERD는 물리적 모델에 가깝게 동작합니다 — 실제 데이터 타입, 기본키·외래키 제약을 다루고 MySQL DDL을 바로 내보낼 수 있습니다. 동시에 컬럼마다 논리명(한글 설명)을 함께 적을 수 있어, 논리적 모델이 담아야 할 "이 속성이 비즈니스적으로 무엇을 의미하는지"라는 정보도 물리 모델 위에 함께 기록할 수 있습니다.