게시글(BOARD)과 댓글(COMMENT)의 관계를 예로 들어보자. 하나의 게시글에는 여러 댓글이 달릴 수 있다. (1:N) 이 관계를 식별 관계, 비식별 관계로 각각 모델링 해보면서 장단점을 알아보자.
비식별 관계
이 방식은 자식 테이블인 COMMENT가 자신만의 고유한 기본 키(comment_id)를 가지는 구조다.

- ERD에서 비식별 관계는 점선으로 표시된다. 식별 관계는 실선으로 표시된다.
DROP TABLE IF EXISTS comment_non_identifying;
DROP TABLE IF EXISTS board_non_identifying;
CREATE TABLE board_non_identifying (
board_id BIGINT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
PRIMARY KEY (board_id)
);
CREATE TABLE comment_non_identifying (
comment_id BIGINT NOT NULL AUTO_INCREMENT, -- 독립적인 PK
board_id BIGINT NOT NULL, -- 일반 컬럼 + FK
content TEXT NOT NULL,
PRIMARY KEY (comment_id),
CONSTRAINT fk_comment_board_non FOREIGN KEY (board_id)
REFERENCES board_non_identifying (board_id)
);
- comment_non_identifying 테이블은 "comment_id"라는 독립적인 대리 키(Surrogate Key)를 PK로 사용한다.
- "board_id(FK)"는 어떤 게시글에 달린 댓글인지를 나타내는 단순 외래 키일뿐, PK의 일부가 아니다.
장점
- 단순하고 명확하다: "comment_id" 하나만 알면 특정 댓글을 조회, 수정, 삭제할 수 있다. PK가 단순하여 관리가 매우 쉽다.
- 유연하다: 만약 비즈니스 로직이 변경되어 댓글을 다른 게시글로 옮겨야 하는 상황이 생기면, "board_id(FK)" 값만 UPDATE 하면 그만이다.
- 관계가 느슨하게 연결되어 있어 변화에 유연하다.
- ORM 친화적이다: JPA/Hibernate 같은 ORM 기술은 이런 단순한 대리 키 구조에서 가장 자연스럽고 효율적으로 동작한다.
단점
- PK만 봐서는 부모와의 관계를 직관적으로 알기 어렵다. (큰 단점은 아니다)
데이터 입력 및 조회
-- 데이터 입력
INSERT INTO board_non_identifying (title) VALUES ('첫 번째 게시글'); -- board_id:
INSERT INTO board_non_identifying (title) VALUES ('두 번째 게시글'); -- board_id:
INSERT INTO comment_non_identifying (board_id, content) VALUES (1, '1번 글의 첫 댓글입니다.'); -- comment_id: 1
INSERT INTO comment_non_identifying (board_id, content) VALUES (1, '1번 글의 두번째 댓글입니다.'); -- comment_id: 2
INSERT INTO comment_non_identifying (board_id, content) VALUES (2, '2번 글의 첫댓글입니다.'); -- comment_id: 3


- 결과를 보면 알 수 있듯이, 각 댓글은 "board_id"와 관계없이 "comment_id"라는 고유한 값(1, 2, 3)으로 완벽하게 식별된다.
- 댓글을 조회하거나 수정할 때 "comment_id=2"와 같이 하나의 값만 사용하면 되므로 매우 직관적이다.
식별 관계
이 방식은 자식 테이블인 COMMENT가 부모의 기본 키(board_id)를 물려받아 자신의 기본 키의 일부로 삼는 구조다.

- ERD에서 식별 관계는 실선으로 표시된다. 비식별 관계는 점선으로 표시된다.
DROP TABLE IF EXISTS comment_identifying;
DROP TABLE IF EXISTS board_identifying;
CREATE TABLE board_identifying (
board_id BIGINT NOT NULL AUTO_INCREMENT,
title VARCHAR(255) NOT NULL,
PRIMARY KEY (board_id)
);
CREATE TABLE comment_identifying (
board_id BIGINT NOT NULL, -- PK의 일부 + FK
comment_no BIGINT NOT NULL, -- PK의 일부, 해당 board_id 내에서 순차 증가
content TEXT NOT NULL,
PRIMARY KEY (board_id, comment_no), -- 복합 기본 키 (Composite PK)
CONSTRAINT fk_comment_board_iden FOREIGN KEY (board_id)
REFERENCES board_identifying (board_id)
);
- comment_identifying 테이블의 PK는 "(board_id, comment_no)" 두 개의 컬럼으로 구성된 복합키다.
- 일대다 관계이므로 부모로부터 받은 PK인 "board_id" 만으로는 PK를 구성할 수 없다.
- "comment_no" 같은 추가 정보가 필요하다.
- "board_id"는 PK이면서 동시에 board_identifying 테이블을 참조하는 FK다.
- 일대다 관계이므로 부모로부터 받은 PK인 "board_id" 만으로는 PK를 구성할 수 없다.
- "comment_no"는 댓글 순서에 맞추어 애플리케이션에서 번호를 만들어야 한다(채번). 데이터베이스가 제공하는 자동 증가값(auto increment)을 사용할 수 없다
장점
- PK 자체가 비즈니스 의미를 가진다: "(board_id=10, comment_no=3)"이라는 PK는 "10번 게시글의 3번째 댓글"이라는 명확한 의미를 가진다.
- 데이터 정합성 강화: 이 구조에서는 "board_id" 없이 comment가 존재할 수 없다는 것이 명확하게 표현된다.
- 쿼리 최적화 가능성: 게시글과 댓글을 항상 같이 조회하는 경우, 복합키 인덱스가 효율적으로 사용될 수 있다.
단점
- 복잡하다: 복합키는 관리하기가 번거롭다. 조회, 수정, 삭제 시 항상 두 개의 키 값을 모두 사용해야 한다.
- 유연성이 없다: 부모의 PK가 자식 PK의 일부가 되므로, 댓글을 다른 게시글로 옮기는 등의 비즈니스 요구사항 변경에 대응하기 매우 어렵다.
- PK 값 자체를 변경해야 하기 때문이다.
- 확장성이 떨어진다: 만약 댓글에 "reply"라는 대댓글 기능이 추가된다면, PK 구조가 계속해서 길어지고 복잡해지는 문제가 발생한다.
- ORM 매핑의 복잡성: ORM에서 복합키를 매핑하려면 별도의 식별자 클래스를 만드는 등 추가적인 작업이 필요하다.
데이터 입력 및 조회
-- 데이터 입력
INSERT INTO board_identifying (title) VALUES ('첫 번째 게시글'); -- board_id: 1
INSERT INTO board_identifying (title) VALUES ('두 번째 게시글'); -- board_id: 2
-- 애플리케이션 레벨에서 comment_no를 계산해서 넣어주어야 한다.
INSERT INTO comment_identifying (board_id, comment_no, content) VALUES (1, 1, '1번 글의 첫 댓글입니다.');
INSERT INTO comment_identifying (board_id, comment_no, content) VALUES (1, 2, '1번 글의 두 번째 댓글입니다.');
INSERT INTO comment_identifying (board_id, comment_no, content) VALUES (2, 1, '2번 글의 첫 댓글입니다.');


- 여기서는 "comment_no" 컬럼만 보면 "1"이라는 값이 중복된다.
- 하지만 기본 키는 "(board_id, comment_no)" 두 개를 합친 복합키이므로 "(1, 1)", "(1, 2)", "(2, 1)"은 모두 고유한 값으로 인정된다.
- 특정 댓글을 조회하려면 "WHERE board_id = 1 AND comment_no = 2"와 같이 항상 두 개의 키 값을 조건으로 사용해야 한다.
'데이터 베이스 > 설계 1편, 현대적 데이터 모델링 완전 정복' 카테고리의 다른 글
| Ch07. 논리적 모델링(4) - 식별, 비식별 관계의 SQL 쿼리/성능 (0) | 2026.06.27 |
|---|---|
| Ch07. 논리적 모델링(4) - 식별 관계의 문제점 (0) | 2026.06.27 |
| Ch07. 논리적 모델링(4) - 식별, 비식별 관계의 개념 (0) | 2026.06.27 |
| Ch06. 논리적 모델링(3) - 다대다 관계 개념적, 논리적 모델링 (0) | 2026.06.26 |
| Ch06. 논리적 모델링(3) - 다대다 관계 속성 (0) | 2026.06.26 |