본문 바로가기
Tech/DB Design

식별자 설계 - 3

by Augustine™ 2026. 8. 2.

식별자는 단순한 일련번호가 아니다

프로젝트에서 다음과 같은 말을 자주 듣는다.

“모든 테이블에 ID 하나씩 넣으면 되지 않는가?”

“PK는 자동 증가 숫자로 만들면 되는 것 아닌가?”

기술적으로는 가능하다.

고객ID, 상품ID, 주문ID, 주문상품ID를 모두 자동 증가 숫자로 만들 수 있다.

이렇게 하면 기본키 구조는 단순해진다.

외래키 연결도 편리해진다.

하지만 ID 컬럼을 추가했다고 식별자 설계가 끝나는 것은 아니다.

다음 질문은 여전히 남는다.

같은 이메일로 고객이 두 번 등록되어도 되는가?
같은 상품코드가 두 번 등록되어도 되는가?
같은 주문번호가 두 번 생성되어도 되는가?
하나의 주문에 동일한 주문상품이 중복 등록되어도 되는가?
외부 결제 승인번호는 중복될 수 있는가?
택배 송장번호는 어느 범위에서 유일한가?

자동 증가 ID는 행을 구별해준다.

하지만 업무상 동일한 데이터가 중복 등록되는 것을 막아주지는 않는다.

식별자 설계는 ID 컬럼을 추가하는 작업이 아니다.

업무에서 동일성과 중복을 정의하는 작업이다.


식별자의 필수 요건

어떤 속성이나 속성 집합을 식별자라고 부르기 위해서는 먼저 기본적인 요건을 만족해야 한다.

엔터티의 인스턴스를 식별하기 위해 반드시 갖추어야 하는 성질이다.

첫째, 유일성을 만족해야 한다

식별자는 엔터티에 존재하는 각각의 인스턴스를 서로 다르게 구별할 수 있어야 한다.

서로 다른 두 인스턴스가 같은 식별자 값을 가져서는 안 된다.

고객번호가 고객의 식별자라면 서로 다른 두 고객에게 같은 고객번호가 부여되어서는 안 된다.

주문번호가 주문의 식별자라면 서로 다른 두 주문에 같은 주문번호가 존재해서는 안 된다.

복합식별자의 경우에는 식별자를 구성하는 각각의 속성이 아니라 속성의 조합 전체가 유일해야 한다.

예를 들어 상품코드가 판매자 안에서만 유일하다면 상품코드 하나로는 상품을 식별할 수 없다.

다음과 같이 판매자번호와 상품코드를 함께 사용해야 한다.

판매자번호 + 상품코드

판매자번호는 여러 상품에서 반복될 수 있다.

상품코드 역시 판매자가 다르면 반복될 수 있다.

하지만 판매자번호와 상품코드의 조합은 하나의 상품만 가리켜야 한다.

둘째, 최소성을 만족해야 한다

식별자는 인스턴스를 구별하는 데 필요한 최소한의 속성으로 구성되어야 한다.

고객번호 하나만으로 고객을 유일하게 구별할 수 있다고 해보자.

다음 조합들도 고객을 유일하게 구별할 수 있다.

고객번호 + 고객명
고객번호 + 이메일
고객번호 + 가입일

그러나 이 조합들은 식별자 후보가 될 수 없다.

고객번호만 남겨도 고객을 식별할 수 있기 때문이다.

식별자를 구성하는 속성 중 하나를 제거했을 때에도 여전히 유일성이 유지된다면 그 속성은 식별에 필요하지 않다.

후보식별자는 유일성뿐 아니라 최소성까지 만족해야 한다.

따라서 후보식별자는 다음과 같이 정의할 수 있다.

엔터티의 각 인스턴스를 유일하게 구별할 수 있는 최소한의 속성 또는 속성 집합

유일하지만 최소하지 않은 속성 조합은 슈퍼키가 될 수는 있지만 후보식별자는 될 수 없다.

셋째, 주식별자의 값은 반드시 존재해야 한다

후보식별자 가운데 엔터티를 대표하는 식별자로 선택된 것이 주식별자다.

주식별자는 모든 인스턴스에서 반드시 값을 가져야 한다.

주식별자의 값이 없다면 해당 인스턴스가 무엇인지 확정할 수 없기 때문이다.

예를 들어 고객번호가 고객의 주식별자라면 고객번호가 없는 고객 인스턴스는 존재할 수 없다.

관계형 데이터베이스에서 주식별자는 일반적으로 기본키로 구현된다.

기본키를 구성하는 컬럼에는 NULL 값을 저장할 수 없다.

복합 기본키라면 기본키를 구성하는 모든 컬럼이 반드시 값을 가져야 한다.

다만 후보식별자와 주식별자를 구분할 필요가 있다.

업무적으로 후보식별자가 될 수 있는 속성이라도 특정 시점에 값이 존재하지 않을 수 있다면 주식별자로 선택하기 어렵다.

예를 들어 고객의 이메일이 중복되지 않더라도 선택 가입자에게는 이메일이 없을 수 있다면 이메일은 모든 고객을 식별하는 주식별자로 사용할 수 없다.

주식별자를 선택할 때 고려할 기준

식별자의 필수 요건을 만족하는 후보가 여러 개 존재할 수 있다.

이때 후보식별자 중 어느 것을 주식별자로 선택할 것인지 결정해야 한다.

다음 조건은 식별자가 성립하기 위한 절대적인 요건이라기보다, 안정적인 주식별자를 선택하기 위한 기준이다.

첫째, 값이 가능한 한 변경되지 않아야 한다

식별자는 다른 엔터티가 관계를 맺는 기준으로 사용된다.

주식별자의 값이 변경되면 이를 참조하는 외래키에도 영향을 줄 수 있다.

예를 들어 고객 이메일을 주식별자로 사용했다고 해보자.

고객이 이메일을 변경하면 고객을 참조하는 주문, 배송, 상담, 결제 등의 데이터도 영향을 받을 수 있다.

데이터베이스가 연쇄 갱신을 지원하더라도 식별자의 변경은 넓은 범위의 데이터와 시스템에 영향을 줄 수 있다.

따라서 고객명, 이메일, 전화번호, 주소처럼 업무 과정에서 바뀔 가능성이 높은 속성은 주식별자로 선택할 때 주의해야 한다.

변경 가능한 속성이라고 해서 식별자가 될 수 없는 것은 아니다.

업무 규칙상 유일성과 최소성을 만족한다면 후보식별자는 될 수 있다.

다만 여러 후보 중 주식별자를 선택할 때는 값이 더 안정적인 후보를 우선적으로 검토하는 것이 바람직하다.

둘째, 다른 인스턴스에 재사용되지 않아야 한다

한 번 특정 인스턴스에 부여된 식별자 값은 가능하면 다른 인스턴스에 다시 사용하지 않아야 한다.

탈퇴한 고객의 고객번호를 새로운 고객에게 다시 부여했다고 해보자.

과거 주문이 고객번호만으로 연결되어 있다면 새로운 고객의 주문처럼 해석될 수 있다.

취소된 주문번호를 새로운 주문에 다시 사용하면 과거 주문과 현재 주문을 구별하기 어려워진다.

식별자 값이 시점에 따라 서로 다른 인스턴스를 가리키면 동일성의 의미가 불안정해진다.

따라서 식별자는 해당 인스턴스의 생명주기가 종료된 뒤에도 다른 인스턴스에 재사용하지 않는 것이 안전하다.

다만 재사용 금지는 관계형 모델이 형식적으로 요구하는 후보키의 필수 조건은 아니다.

특정 시점의 릴레이션 안에서 유일성이 보장된다면 키의 형식적 요건은 만족할 수 있다.

그러나 이력 데이터와 장기간의 참조 관계를 관리하는 업무 시스템에서는 비재사용성이 의미적 무결성을 유지하기 위한 중요한 원칙이 된다.

셋째, 가능한 한 단순해야 한다

여러 후보식별자가 동일한 업무 객체를 안정적으로 식별할 수 있다면 구조가 단순한 식별자를 우선적으로 고려할 수 있다.

식별자를 구성하는 속성이 많아지면 이를 참조하는 외래키도 함께 길어진다.

다음과 같은 복합식별자를 생각해보자.

주문번호 + 상품번호 + 옵션번호 + 판매자번호

배송상품, 취소상품, 반품상품, 환불상품이 이 주문상품을 참조한다면 각 엔터티에 네 개의 외래키 속성이 전달될 수 있다.

관계가 여러 단계로 이어지면 모델과 쿼리가 복잡해질 수 있다.

이 경우 주문상품일련번호와 같은 단일 인조식별자를 주식별자로 선택하는 방안을 검토할 수 있다.

그러나 단순성만을 이유로 모든 엔터티에 일련번호를 부여해서는 안 된다.

인조식별자를 주식별자로 선택하더라도 업무적으로 중복되어서는 안 되는 속성 조합은 별도로 관리해야 한다.

예를 들어 주문상품일련번호를 기본키로 사용하더라도 다음 속성 조합이 업무상 유일해야 한다면 별도의 유일성 제약이 필요하다.

주문번호 + 상품번호 + 옵션번호 + 판매자번호

단순성은 업무의 동일성 규칙을 제거하기 위한 기준이 아니다.

여러 후보 중 참조 구조와 변경 영향을 고려하여 대표 식별자를 선택하기 위한 기준이다.


필수 요건과 선택 기준은 구분해야 한다

식별자의 요건과 주식별자의 선택 기준을 같은 의미로 사용해서는 안 된다.

식별자가 성립하려면 반드시 유일성과 최소성을 만족해야 한다.

주식별자로 선택된 값은 모든 인스턴스에 반드시 존재해야 한다.

반면 불변성, 비재사용성, 단순성은 여러 후보식별자 중 어떤 것을 대표 식별자로 선택할 것인지 판단하는 기준이다.

이를 정리하면 다음과 같다.

구분항목의미

식별자의 필수 요건 유일성 각 인스턴스를 서로 다르게 구별할 수 있어야 한다
식별자의 필수 요건 최소성 식별에 필요하지 않은 속성이 포함되어서는 안 된다
주식별자의 필수 요건 필수값 모든 인스턴스에서 식별자 값이 존재해야 한다
주식별자 선택 기준 불변성 값이 가능한 한 변경되지 않아야 한다
주식별자 선택 기준 비재사용성 다른 인스턴스에 같은 값을 다시 사용하지 않는 것이 바람직하다
주식별자 선택 기준 단순성 참조와 관리가 지나치게 복잡하지 않아야 한다

식별자에 대해 설명할 때 이 둘을 분리하면 개념이 훨씬 명확해진다.

유일성이나 최소성은 있으면 좋은 특성이 아니다.

식별자를 식별자답게 만드는 필수 조건이다.

반면 단순성은 반드시 지켜야 하는 절대 원칙이 아니다.

업무의 동일성 규칙을 정확하게 표현한다는 전제 아래에서 적용해야 하는 설계 판단 기준이다.

 

외래키는 엔터티 사이의 관계를 지킨다

고객과 주문의 관계를 보자.

고객 한 명은 여러 주문을 할 수 있다.

주문 하나는 한 고객이 한다.

주문 엔터티에는 고객을 가리키는 값이 필요하다.

고객의 주식별자가 고객일련번호라면 주문에는 고객일련번호가 외래키로 들어간다.

외래키는 다른 테이블의 기본키 또는 유일성이 보장된 키를 참조하여 관계의 무결성을 유지한다.

존재하지 않는 고객번호를 주문에 입력하지 못하게 하는 것이 대표적인 역할이다. PostgreSQL과 SQL Server의 공식 문서도 외래키를 테이블 사이의 참조 무결성을 유지하는 제약조건으로 설명한다.

예를 들어 고객 테이블에 고객번호 100번이 없는데 주문 테이블에 고객번호 100번을 입력할 수 있다면 문제가 생긴다.

그 주문은 존재하지 않는 고객을 가리킨다.

이것을 고아 데이터라고 부르기도 한다.

관계선만 그었다고 관계가 보장되는 것은 아니다.

물리 데이터베이스에서는 외래키 제약조건을 통해 관계를 보호해야 한다.

다만 모든 업무 규칙을 기본키와 외래키만으로 표현할 수 있는 것은 아니다.

“회원 한 명은 동시에 최대 5권까지 대여할 수 있다”와 같은 규칙은 단순한 외래키만으로 표현하기 어렵다.

“현재 연체 중인 회원은 대여할 수 없다”는 규칙도 마찬가지다.

기본키와 외래키는 식별과 참조 관계를 지킨다.

업무 조건 전체를 대신하는 것은 아니다.


RFP와 인터뷰에서 식별자 단서를 찾는 방법

식별자는 요구사항 문서에 항상 명확하게 적혀 있지 않다.

다음과 같은 문장을 찾아야 한다.

“회원 가입 시 회원번호를 자동으로 부여한다.”

이 문장은 회원번호가 식별자 후보라는 단서다.

“회원번호는 탈퇴 후에도 재사용하지 않는다.”

이 문장은 식별자의 재사용 금지 규칙을 보여준다.

“같은 이메일로 중복 가입할 수 없다.”

이 문장은 이메일에 업무적 유일성 제약이 필요하다는 단서다.

“상품코드는 판매자가 직접 입력한다.”

이 문장은 상품코드의 생성 주체를 확인해야 한다는 단서다.

“판매자가 다르면 같은 상품코드를 사용할 수 있다.”

이 문장은 상품코드 하나만으로는 상품을 식별할 수 없다는 뜻이다.

이 경우 다음과 같은 복합식별자가 필요할 수 있다.

판매자번호 + 상품코드

또는 상품일련번호를 주식별자로 만들고 판매자번호와 상품코드 조합에 유일성 제약을 둘 수도 있다.

“주문번호는 연도별로 1번부터 다시 시작한다.”

이 문장도 중요하다.

주문번호 1001번이 매년 존재할 수 있다는 뜻이다.

따라서 주문번호 하나만으로 전체 주문을 구별할 수 없다.

다음 조합이 필요할 수 있다.

주문연도 + 주문번호

또는 전체 시스템에서 유일한 주문일련번호를 별도로 만들 수 있다.

“송장번호는 택배사별로 부여한다.”

이 문장은 송장번호의 유일성 범위를 확인해야 한다는 뜻이다.

택배사가 다르면 같은 송장번호가 존재할 수 있다면 다음 조합으로 구별해야 할 수 있다.

택배사코드 + 송장번호

식별자를 찾을 때는 단어만 보아서는 안 된다.

값이 어느 범위에서 유일한지 확인해야 한다.


유일성의 범위를 확인해야 한다

“상품코드는 유일하다”라는 말은 충분하지 않다.

어디에서 유일한지 물어야 한다.

  • 전체 회사에서 유일한가?
  • 판매자 안에서만 유일한가?
  • 매장 안에서만 유일한가?
  • 연도 안에서만 유일한가?
  • 국가 안에서만 유일한가?
  • 현재 데이터에서만 유일한가?
  • 삭제된 데이터까지 포함하여 영구적으로 유일한가?

예를 들어 판매자가 직접 상품코드를 부여한다고 해보자.

판매자 A도 상품코드 1001을 사용할 수 있다.

판매자 B도 상품코드 1001을 사용할 수 있다.

그렇다면 상품코드만으로 상품을 식별할 수 없다.

판매자번호와 상품코드를 함께 사용해야 한다.

판매자번호 상품코드 상품명
A 1001 고급 수건
B 1001 주방 세제

상품코드는 판매자 안에서는 유일하다.

하지만 쇼핑몰 전체에서는 유일하지 않다.

따라서 상품의 업무식별자는 다음과 같다.

판매자번호 + 상품코드

이것이 복합식별자가 필요한 대표적인 이유다.

식별자는 값 자체만으로 결정되지 않는다.

업무 범위와 함께 결정된다.


화면의 번호와 데이터 식별자는 다를 수 있다

주문 목록 화면에 다음 번호가 표시된다고 해보자.

번호 주문번호 고객명 주문일
1 ORD-1003 김민수 2026-07-14
2 ORD-1002 이영희 2026-07-14
3 ORD-1001 박민수 2026-07-13

화면의 번호 1, 2, 3은 주문을 식별하는 값처럼 보인다.

하지만 검색 조건이나 정렬 순서가 바뀌면 번호도 바뀐다.

다음 페이지로 이동하면 다시 1부터 시작할 수도 있다.

이 번호는 화면에서 행의 순서를 보여주는 값이다.

주문의 식별자가 아니다.

엑셀의 행 번호도 마찬가지다.

화면에 보인다고 해서 모두 속성이 되는 것은 아니다.

숫자로 되어 있다고 해서 모두 식별자가 되는 것도 아니다.

데이터 모델러는 화면의 표시 값과 업무 데이터의 식별자를 구분해야 한다.


식별자는 업무의 동일성 규칙이다

고객번호를 PK로 정했다.

상품번호를 PK로 정했다.

주문번호를 PK로 정했다.

이렇게 말하면 식별자 설계가 끝난 것처럼 보인다.

하지만 더 중요한 것은 그 앞에 있다.

왜 고객번호가 고객을 식별하는가?

이메일은 왜 주식별자로 선택하지 않았는가?

상품코드는 어느 범위에서 유일한가?

주문번호는 언제까지 유일한가?

주문상품의 동일성을 결정하는 속성은 무엇인가?

식별자를 정한다는 것은 컬럼에 열쇠 표시를 붙이는 일이 아니다.

업무에서 두 데이터가 같은 대상인지 다른 대상인지 정의하는 일이다.

같은 고객인지 판단할 기준이 없으면 고객 데이터는 중복된다.

같은 상품인지 판단할 기준이 없으면 판매 통계가 틀어진다.

같은 주문상품인지 판단할 기준이 없으면 수량이 중복 계산될 수 있다.

좋은 식별자는 데이터 한 행을 구별하는 데서 끝나지 않는다.

업무의 동일성과 중복을 설명할 수 있어야 한다.


이번 장의 모델

이번 예제에서는 다음과 같이 식별자를 정한다.

고객

주식별자:

고객일련번호

보조식별자 후보:

이메일

다만 이메일은 변경될 수 있고 탈퇴 후 재사용될 수 있으므로, 유일성의 적용 범위와 기간을 추가로 정의해야 한다.

판매자

주식별자:

판매자일련번호

업무식별자:

사업자등록번호

사업자등록번호의 변경 가능성, 개인 판매자의 존재 여부, 해외 판매자의 식별 기준은 추가 인터뷰가 필요하다.

상품

주식별자:

상품일련번호

업무적 유일성 조건:

판매자일련번호 + 판매자상품코드

상품코드는 판매자 안에서는 유일하지만 쇼핑몰 전체에서는 중복될 수 있다.

주문

주식별자:

주문일련번호

업무식별자:

주문번호

주문번호는 고객과 운영자가 조회에 사용하는 외부 노출 식별자다.

주문일련번호와 주문번호를 하나로 통합할 수도 있지만, 두 값의 생성 규칙과 사용 목적이 다르다면 분리할 수 있다.

주문상품

주식별자:

주문상품일련번호

업무적 유일성 조건:

주문일련번호 + 상품일련번호 + 상품옵션일련번호

다만 동일 상품과 동일 옵션을 한 주문에 여러 줄로 등록할 수 있는 업무라면 이 조합은 유일하지 않을 수 있다.

이 경우 주문항목순번 등 다른 구분 기준이 필요하다.


모델링은 식별자에 대한 질문에서 깊어진다

엔터티를 처음 도출할 때는 명사를 찾는다.

정규화를 할 때는 속성이 어디에 속하는지 묻는다.

식별자를 정할 때는 동일성을 묻는다.

“어떤 경우에 같은 고객이라고 보는가?”

“어떤 경우에 같은 상품이라고 보는가?”

“어떤 범위에서 주문번호가 유일한가?”

“삭제된 번호를 다시 사용할 수 있는가?”

“업무 속성이 바뀌어도 같은 대상으로 보아야 하는가?”

이 질문에 답하지 않고 일련번호부터 만드는 것은 위험하다.

인조식별자는 모델을 편리하게 만들 수 있다.

하지만 업무의 동일성 규칙을 대신해주지는 않는다.

복합식별자는 업무 의미를 명확하게 보여줄 수 있다.

하지만 너무 많은 속성으로 구성되면 관계 구조가 복잡해질 수 있다.

본질식별자는 업무 의미를 가진다.

하지만 변경되거나 외부 정책에 영향을 받으면 안정성이 떨어질 수 있다.

따라서 식별자에는 모든 상황에 적용되는 하나의 정답이 없다.

좋은 식별자는 업무 규칙을 충분히 확인한 뒤 결정해야 한다.

무엇으로 식별했는가보다 더 중요한 질문이 있다.

왜 그것으로 식별했는가?

그 이유를 설명할 수 있어야 한다.

그때 식별자는 단순한 PK 컬럼이 아니라 업무를 지탱하는 기준이 된다.

'Tech > DB Design' 카테고리의 다른 글

속성이란  (0) 2026.08.02
식별자 설계 - 4  (0) 2026.08.02
식별자 설계 - 2  (0) 2026.07.15
정규화-3  (0) 2026.07.08
정규화-2  (0) 2026.07.08

댓글