쏭의 개발 블로그
Primary Key 생성 전략 본문
[1] DB Auto_increment
데이터베이스가 자동으로 증가하는 숫자를 부여하여 PK를 생성하는 방식이다. 데이터가 삽입될 때 자동으로 증가하는 번호가 할당되며, 삭제된 값은 자동으로 복구되지 않는다.
장점과 단점은 다음과 같다.
장점
- 관리가 간편하며, 단일 데이터베이스 환경에서 성능이 우수하다.
- 정렬된 상태를 유지하므로 B+ Tree 기반 인덱스 성능 최적화가 가능하다
- 데이터 삽입 속도가 빠르다.
단점
- 분산 환경에서의 중복 문제 : 분산 데이터베이스 환경에서는 PK가 중복되어 식별자의 유일성이 보장되지 않는다. 여러 샤드에서 동일한 pk를 가지는 경우가 예시이다.
- 보안 문제 : PK를 클라이언트 측에 노출 시 데이터 개수나 특별 시점의 식별자 예측 가능하다. 예를 들어, 사용자가 방금 가입했을 때의 user id가 1000이라면 사용자는 1000명 가입했다고 추정할 수 있다.
이러한 장단점으로 인해 애플리케이션에서 PK의 중복을 직접 구분하는 상황이나 단일 데이터베이스 환경에서 사용하는 것이 좋다. 보안 요구사항이 낮음 시스템의 경우도 사용할 수 있다.
💡보안 문제 해결방법 - PK와 UNIQUE INDEX 사용
AUTO_INCREMENT를 사용할 경우, PK가 클라이언트에게 노출되는 보안 문제가 발생할 수 있다. 이를 해결하기 위해 PK와 UNIQUE index를 함께 사용하는 방법이 있다. PK만 DB내의 식별자로 사용하고, 애플리케이션에서의 식별자를 위해 별도의 UNIQUE 인덱스를 사용할 수 있다. 예를 들어, PK는 DB에서 auto_increment인 id로 설정하고, unique index는 UUID로 설정한 후, unique index만 클라이언트에 노출할 수 있다. 하지만 이 경우, Secondary Index로 포인터를 찾은 후 Clustered Index로 데이터에 접근하므로 조회 비용이 증가할 수 있다.
[2] 유니크 문자열 또는 숫자
PK를 고유한 문자열 또는 난수를 생성하여 지정하는 방법이다. 정렬 데이터가 아니라 랜덤 데이터를 삽입한다.
대표적인 유니크 문자열에는 UUID가 있다. UUID는 128비트의 고유한 문자열을 생성하는 알고리즘으로, 랜덤성이 강하여 충돌 확률이 매우 낮지만 길이가 길어 인덱싱 성능이 저하될 수 있다.
유니크 문자열 또는 숫자 전략의 장점은 키 생성 방식이 간단하다는 점이다. 충돌 가능성이 매우 낮고 보안성
장점
- 키 생성 방식이 간단하다
- 128비트의 크기로 시간 정보와 관계없이 생성되므로 중복 가능성이 매우 낮다.
- 완전 랜덤한 방식으로 예측할 수 없다.
- 유니크 정렬 문자열(ex. UUID v7, ULID 등)과 유니크 정렬 숫자(ex. snowflake) 보다 구현이 간단하다.
단점
- 랜덤 데이터로 인해 성능 저하 발생이 가능하다.
성능 저하가 일어나는 이유는 아래 2자기 때문이다.
- 데이터 삽입 시 B+ tree 재구성 및 디스크 I/O 증가
- PK 범위 조회시, 랜덤 I/O로 성능 저하
일단, 데이터 삽입 시 B+ tree 재구성과 디스크 I/O가 증가할 수 있다. Clustered index는 데이터를 정렬된 상태로 유지한다. 새로운 데이터를 추가할 때 정렬된 순서를 맞춰야 하다보니, 만약 데이터가 들어갈 공간이 부족하다면 기존 데이터를 나누고 재배치하는 작업이 필요할 수 있다. 이 과정에서 B+ tree가 재구성되고 그로 인해 디스크에서 추가적인 읽기, 쓰기 작업이 증가할 수 있다.
또한, PK 범위 조회시, 랜덤 I/O로 성능 저하가 발생할 수 있다. PK 기반으로 특정 범위를 조회할 때, Clustered Index를 사용하면 정렬된 데이터에 접근해야한다. 하지만 랜덤한 위치에 있는 데이터를 읽어야 할 경우, 디스크에서 연속된 데이터를 가져오는 순차 I/O가 아니라 랜덤 I/O가 발생한다. 랜덤 I/O는 물리적으로 여러 위치에서 데이터를 찾아야 해서 속도가 느려지고 성능이 저하될 수 있다.
[3] 유니크 정렬 문자열
유니크 정렬 문자열은 PK를 생성할 때 각 ID가 고유하면서도 생성된 순서대로 정렬이 가능하도록 만드는 방식이다. 보통 128bit 알고리즘이며, UUID 처럼 고유성을 유지하면서도 정렬이 가능하도록 시간 기반의 요소를 포함하는 것이 핵심이다.
대표적인 예시로는 UUID v7과 ULID가 있다.
UUID v7은 시간 기반으로 생성되는 UUID로, 생성시간을 포함하여 정렬할 수 있는 기능을 제공하는 방식이다. ULID는 26자로 UUID보다 짧고 생성 순서대로 정렬이 가능한 ID 방식이다. 특수문자가 없이 URL-safe하고 (ex) 01F8MECHZX3TBXYN5RRTG1X3J6 과 같이 표현한다.
장점
- 분산 환경에 대한 PK 중복 문제를 해결한다.
- 보안 문제를 해결한다.
- 랜덤 데이터에 의한 성능 문제를 해결한다.
- ID가 일정한 패턴을 가지므로 AUTO_INCREMENT와 유니크 문자열 또는 숫자 방식보다 인덱싱 성능이 더 좋다.
단점
- PK가 크면 클수록 데이터는 더 많은 공간을 차지
- PK가 크면 클수록 비교 연산에 의한 정렬/조회에 더 많은 비용 소모
CLUSTER INDEX는 PK 기준으로 만들어지고, SECONDARY INDEX는 데이터에 접근할 수 있는 포인터를 가진다. 이에 따라 데이터는 더 많은 공간과 비용을 소모하게 되는 것이다.
[4] 유니크 정렬 숫자
유니크 정렬 숫자는 PK를 생성할 때 각 ID가 고유하면서도 생성된 순서대로 정렬이 가능하도록 만드는 방식이다. 숫자 기반 ID를 사용하여 생성된 순서대로 정렬이 가능하도록 설계되고 일반적으로 64bit를 사용한다.
대표적인 예시에는 Snowflake와 TSID가 있다.
[Snowflake]
분산 시스템에서 고유한 64비트 ID를 생성하는 알고리즘이다. 분산 환경에서도 중복 없이 순차적으로 ID를 생성하기 위한 규칙이다. 10자로 구성되어있고, 시간 기반 정렬과 성능 최적화가 가능하다.
[1비트][41비트: 타임스탬프][10비트: 노드 ID][12비트: 시퀀스 번호]
- 타임스탬프 : 순차성
- 노드ID + 시퀀스 번호 : 고유성
[TSID]
Twitter의 Snowflake와 ULID spec을 합쳐 만든 자바의 라이브러리이다. 대규모 분산 시스템에서의 병렬 처리 가능 및 고유성을 보장하고, 통산 8바이트로 공간 효율성이 있다.
장단점은 다음과 같다.
장점
- 분산 환경에 대한 PK 중복 문제를 해결 가능하다.
- 보안 문제를 해결할 수 있다.
- 랜덤 데이터에 의한 성능 문제를 해결한다.
- UUID보다 작은 크기(64bit)로 인덱스 성능 최적화가 가능하다.
- 생성된 순서대로 정렬할 수 있다.
단점
- 정렬을 위해 타임스탬프를 나타내는 비트 수의 제한으로, 키 생성을 위한 시간적인 한계가 발생할 수 있다.
이러한 장점으로 인해 MSA 기반 분산환경에서 고유 식별자로 사용한다. 대규모 데이터 저장소에서 PK 성능 최적화가 필요한 경우에도 사용할 수 있다.
데이터베이스 환경에 따른 PK 선택 기준
각 데이터베이스 및 시스템 환경에 따라 적합한 PK 전략을 정리하면 다음과 같다.
환경 | 고려해야 할 사항 | 적합한 PK 생성 방식 |
단일 데이터베이스 |
- 단일 노드에서 동작하므로 PK 충돌 가능성이 없음 - 단순한 정수형 PK가 성능적으로 유리함. |
✅ Auto-Increment ID ✅ 유니크 정렬 숫자 (고유 ID 생성 필요 시) |
분산 데이터베이스 |
- 여러 노드에서 동일한 PK가 생성될 가능성이 있음. - PK의 유일성이 보장되어야 함. - Auto-Increment 방식은 충돌 가능성이 있음. |
✅ 유니크 정렬 숫자 ✅ 유니크 정렬 문자열 |
대규모 트래픽 처리 |
- PK가 정렬되지 않으면 인덱스 성능 저하. - Clustered Index에서 랜덤 삽입이 발생하면 성능 저하. - 트랜잭션이 많을 경우 PK 생성 성능도 중요. |
✅ 유니크 정렬 숫자 ✅ 유니크 정렬 문자열 |
보안이 중요한 시스템 | - ID를 노출할 경우 정보 유출 가능. - Auto-Increment 사용 시 사용자가 데이터 개수를 유추할 수 있음. |
✅ 유니크 문자열 또는 숫자 ✅ 별도 Unique Index 추가 (PK 노출 방지) |
PK 기반 Range Query 필요 | - 정렬된 데이터가 필요. - Auto-Increment는 정렬을 보장하지만 분산 환경에서는 사용 어려움. |
✅ 유니크 정렬 숫자 ✅ 유니크 정렬 문자열 |
참고자료
https://www.devkobe24.com/DB/2025-02-06-primary-key-creation-strategy-unique-string-or-number.html
https://www.devkobe24.com/DB/2025-02-07-primary-key-creation-strategy-unique-alignment-string.html
'Programming' 카테고리의 다른 글
API와 REST API는 무엇일까? (0) | 2023.03.19 |
---|