식별자용 데이터 타입: 여권 번호는 왜 정수가 아닌가
SQL 데이터베이스에서 여권 번호를 저장할 때 적절한 데이터 타입을 선택하는 간단한 질문이 개발자들을 두 진영으로 나눕니다: 데이터 의미를 고려하는 사람들과 형식에만 매달리는 사람들. INTEGER 대신 VARCHAR를 선택하지 않으면 선행 0이 사라져 식별이 깨질 수 있으며, 수백만 사용자 시스템에서 치명적입니다. 이 글에서는 데이터의 본질에 기반한 데이터베이스 스키마 설계의 핵심 원리를 분석합니다.
데이터 의미 vs. 외형
대부분의 개발자들이 인터뷰에서 여권 번호의 숫자를 보면 본능적으로 INTEGER나 BIGINT 같은 숫자 타입을 선택합니다. 이는 피상적인 분석의 전형적인 실수입니다. 핵심은 데이터의 구성 요소가 아니라 사용 방식입니다. 여권 시리즈나 번호에 산술 연산을 하지 않습니다—동등 비교, 검색, 전송만 할 뿐입니다. 이는 수량이 아닌 식별자입니다. 따라서 문자열 타입이 적합합니다: 시리즈는 CHAR(4), 번호는 CHAR(6), 전체는 CHAR(10). INTEGER로 저장하면 선행 0이 영구적으로 사라집니다: 0306이 306으로 변해 문서가 무효화되며 오류 로그도 남지 않습니다.
실전에서의 실수 파장
잘못된 데이터 타입 선택은 이론이 아닙니다—프로덕션에서 자주 터집니다. 주차 허가 서비스에서 여권 필드를 NUMBER로 설정해 선행 0이 조용히 잘려 데이터베이스 기록과 종이 문서가 불일치했습니다. 코드 리뷰와 테스트를 통과했으나 0으로 시작하는 시리즈 사용자에게 발각됐습니다. 러시아에는 수백만 개의 이런 여권이 있어 문제 규모가 거대합니다. 공간 절약이나 인덱스 속도 같은 최적화 주장은 설득력이 없습니다:
- CHAR(4)는 단일 바이트 숫자에서 INTEGER와 동일한 4바이트를 사용합니다.
- VARCHAR 인덱스는 숫자와 마찬가지로 O(log n) 효율로 작동하며, 고정 문자열에서는 차이가 미미합니다.
바이트 절약이 데이터 손실 위험을 정당화할 수 없습니다.
다른 식별자에 적용하는 규칙
"산술 연산을 하지 않으면 숫자가 아니다"라는 규칙은 러시아 및 글로벌 시스템의 많은 ID에 적용됩니다. 주요 예시:
- SNILS (11자리, XXX-XXX-XXX XX 형식): 대시 제거 후 VARCHAR(14) 또는 CHAR(11), BIGINT 아님.
- 개인 TIN (12자리): 01~09 지역에서 0으로 시작 가능하니 VARCHAR(12) 필수.
- 전화번호: 국제 형식 '+' 유지 위해 VARCHAR(20)만.
- 우편번호: 국제 알파벳 가능하니 CHAR(6).
- 은행 계좌 (20자리): 오버플로 방지 위해 CHAR(20).
문자열 타입은 유연성을 보장하고 형식 변경 시 데이터 손실을 막습니다.
핵심 요약
- 의미 우선: 외형이 아닌 연산에 기반해 데이터 타입 선택.
- 선행 0 중요: 숫자 타입이 제거해 수백만 기록 ID 파괴.
- 최적화는 후순위: 바이트나 마이크로초 절약으로 나쁜 데이터 교환 금지.
- 보편 원리: SNILS, TIN, 전화 등에 적용.
- 스키마 감사: 기존 DB에서 숨겨진 위험 점검.
적절한 데이터 타입 선택법
우수한 엔지니어는 데이터베이스 필드 설계 시 세 질문을 합니다:
- 의미는? (ID, 수량, 텍스트?)
- 연산은? (비교, 검색, 산술?)
- 비즈니스 규칙은? (형식, 길이, 문자?)
답변이 선택을 결정합니다: ID는 문자열, 수량은 숫자. 이는 문제 해결과 코피페이스 코딩을 구분하며, 비용 큰 버그를 초기에 차단합니다.
러시아 ID 데이터 타입
| 데이터 | 형식 | 적합 타입 | 흔한 실수 | 오류 영향 |
|------|--------|------------|----------------|--------------|
| 여권 시리즈 | 4자리 | CHAR(4) | INTEGER | 선행 0 손실, 문서 무효 |
| 여권 번호 | 6자리 | CHAR(6) | INTEGER | 0 제거, ID 파괴 |
| 전체 여권 | 10자리 | CHAR(10) | BIGINT | 최대 두 자리 선행 0 손실 |
| SNILS | 11자리 | CHAR(11) | BIGINT | 01~09 코드 제거 |
| 개인 TIN | 12자리 | CHAR(12) | BIGINT | 01~09 숫자 손실 |
| 전화번호 | +7... | VARCHAR(20) | BIGINT | '+' 저장 불가, 국제 미지원 |
| 우편번호 | 6자리 | CHAR(6) | INTEGER | 알파벳 국제 코드 미지원 |
| 은행 계좌 | 20자리 | CHAR(20) | 적합 INT 없음 | 오버플로, 금융 위험 |
이 표는 스키마 설계와 감사 체크리스트입니다.
— Editorial Team
아직 댓글이 없습니다.