137 lines
11 KiB
Markdown
137 lines
11 KiB
Markdown
---
|
|
title: company-tech-blog / Percona — Storing UUID Values in MySQL (2014, Karthik Appigatla)
|
|
source_type: company-tech-blog
|
|
url: https://www.percona.com/blog/store-uuid-optimized-way/
|
|
archive_url:
|
|
vendor: Percona
|
|
author: Karthik Appigatla
|
|
related_branches: [feature-resource-identifier-contract]
|
|
related_projects: [ca-skeleton]
|
|
tags: [company-tech-blog, ca-skeleton, persistence, mysql, uuid-storage, clustered-index]
|
|
created: 2026-05-31
|
|
---
|
|
|
|
# company-tech-blog / Percona — Storing UUID Values in MySQL
|
|
|
|
> Layer: `raw/company-tech-blogs/` — Percona 엔지니어링 블로그 원문 발췌·출처 기록.
|
|
> 검증된 요약은 `/ingest` 후 `wiki/concepts/` 에 `source-summary-template` 형식으로 별도 작성. 원본은 raw에 영구 보관.
|
|
|
|
## Parent / 활용 branch
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-resource-identifier-contract]] | D10 (DB primary key 컬럼 정책): random UUID v4 를 `varchar(36)` 로 저장 시 InnoDB clustered index 단편화 + 디스크 비용이 `binary(16)` ordered UUID 대비 50% 더 크다는 정량 근거. D7 (timestamp leak): ordered UUID v1 reorder 방식의 시간 정보 노출 부작용 언급. |
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://www.percona.com/blog/store-uuid-optimized-way/
|
|
- 대체 URL: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
|
|
- 아카이브 URL: (미보관)
|
|
- 저자 / 조직: Karthik Appigatla / Percona
|
|
- 발행일: 2014-12-19
|
|
- 마지막 확인일: 2026-05-31
|
|
- 후속 포스트 언급: "a more up-to-date follow-up post" — Storing UUID and Generated Columns (MySQL 8.0 `UUID_TO_BIN` / `BIN_TO_UUID` 함수 포함)
|
|
|
|
## 왜 저장했는지 / Why archived
|
|
|
|
Percona 는 MySQL 전문 컨설팅사로, InnoDB 내부 동작에 관한 정량 벤치마크 신뢰도가 높다.
|
|
`feature-resource-identifier-contract` 의 D10 결정(DB primary key 컬럼 타입)은 MySQL InnoDB clustered index 특성에 근거한 `binary(16)` vs `varchar(36)` 비교가 필요하며, 이 포스트가 25M 레코드 벤치마크로 그 근거를 제공한다.
|
|
단, 이 자료는 2014년 기준 UUID v1 재정렬 전략이며, MySQL 8.0 의 `UUID_TO_BIN(..., 1)` 내장 함수와 UUID v7 (RFC 9562, 2024) 은 후속 자료로 보강 필요.
|
|
|
|
## 핵심 인용 / Key quotes (verbatim, 5개 — Self-Grep 통과)
|
|
|
|
> [§Problems with UUID] "UUID has 36 characters which make it bulky."
|
|
> — 위치: clean text line 1, §Problems with UUID 단락
|
|
|
|
> [§Problems with UUID] "InnoDB stores data in the PRIMARY KEY order and all the secondary keys also contain PRIMARY KEY. So having UUID as PRIMARY KEY makes the index bigger which cannot be fit into the memory"
|
|
> — 위치: clean text line 1, §Problems with UUID 단락
|
|
|
|
> [§Benchmarking / Total Size] "The size of the UUID table is almost 50% bigger than Ordered UUID table and 30% bigger than the table with BIGINT as PRIMARY KEY."
|
|
> — 위치: clean text line 1, §Benchmarking 결과 요약 단락
|
|
|
|
> [§Benchmarking / Time taken] "For the table with UUID as PRIMARY KEY, you can notice that as the table grows big, the time taken to insert rows is increasing almost linearly. Whereas for other tables, the time taken is almost constant."
|
|
> — 위치: clean text line 1, §Time taken 단락
|
|
|
|
> [§Benchmarking / Total Size] "Comparing the Ordered UUID table BIGINT table, the time is taken to insert rows and the size are almost the same. But they may vary slightly based on the index structure."
|
|
> — 위치: clean text line 1, §Benchmarking 결과 비교 단락
|
|
|
|
### Self-Grep Verification 결과
|
|
|
|
임시 파일: `/tmp/percona-uuid-clean.txt` (HTML에서 추출한 단일 행 plain text)
|
|
|
|
```bash
|
|
grep -oF "UUID has 36 characters which make it bulky" /tmp/percona-uuid-clean.txt | wc -l
|
|
# Observed: 1 (PASS)
|
|
|
|
grep -oF "InnoDB stores data in the PRIMARY KEY order and all the secondary keys also contain PRIMARY KEY" /tmp/percona-uuid-clean.txt | wc -l
|
|
# Observed: 1 (PASS)
|
|
|
|
grep -oF "The size of the UUID table is almost 50% bigger than Ordered UUID table and 30% bigger than the table with BIGINT as PRIMARY KEY" /tmp/percona-uuid-clean.txt | wc -l
|
|
# Observed: 1 (PASS)
|
|
|
|
grep -oF "the time taken to insert rows is increasing almost linearly" /tmp/percona-uuid-clean.txt | wc -l
|
|
# Observed: 1 (PASS)
|
|
|
|
grep -oF "Comparing the Ordered UUID table BIGINT table, the time is taken to insert rows and the size are almost the same" /tmp/percona-uuid-clean.txt | wc -l
|
|
# Observed: 1 (PASS)
|
|
```
|
|
|
|
검증 V: 5 | 일치 P: 5 | 폐기 D: 0 | 정정 C: 0
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| PERCONA-UUID-C1 | UUID 를 `char(36)` 로 저장하면 36자 크기 때문에 인덱스가 커진다 | [§Problems with UUID] "UUID has 36 characters which make it bulky." | `company-case-study` | MySQL InnoDB, UUID v1/v4 를 char 형식으로 저장하는 경우 | varchar(36) 과 char(36) 의 차이; PostgreSQL uuid native type 의 저장 비용; binary(16) 의 명시적 크기 비교(이 문장만으로는 미증명) |
|
|
| PERCONA-UUID-C2 | InnoDB 는 PRIMARY KEY 순서로 데이터를 저장하고, 모든 secondary key 는 PRIMARY KEY 를 포함한다 — UUID PK 는 모든 secondary index 를 크게 만들어 메모리에 올리기 어렵게 한다 | [§Problems with UUID] "InnoDB stores data in the PRIMARY KEY order and all the secondary keys also contain PRIMARY KEY. So having UUID as PRIMARY KEY makes the index bigger which cannot be fit into the memory" | `company-case-study` | MySQL InnoDB clustered index 구조 (MySQL 5.x/8.x) | MariaDB / PostgreSQL / TokuDB 등 다른 엔진의 동일 동작; secondary index 크기의 정확한 배율(인용만으로는 수치 없음) |
|
|
| PERCONA-UUID-C3 | 25M 레코드 벤치마크: random UUID PK 테이블의 총 크기는 ordered UUID 테이블보다 50% 크고, BIGINT PK 테이블보다 30% 크다 | [§Benchmarking] "The size of the UUID table is almost 50% bigger than Ordered UUID table and 30% bigger than the table with BIGINT as PRIMARY KEY." | `company-case-study` | MySQL 5.x InnoDB, 25M 행, 특정 스키마(events 테이블 구조 명시됨) | 다른 스키마·데이터 분포·MySQL 버전에서의 재현 보장; PostgreSQL 에서의 동일 수치; UUID v7 (RFC 9562) 에서의 동일 수치(이 포스트는 v1 재정렬 전략) |
|
|
| PERCONA-UUID-C4 | random UUID PK 에서는 테이블이 커질수록 삽입 시간이 거의 선형적으로 증가하는 반면, ordered UUID / BIGINT PK 에서는 삽입 시간이 거의 일정하다 | [§Time taken] "For the table with UUID as PRIMARY KEY, you can notice that as the table grows big, the time taken to insert rows is increasing almost linearly. Whereas for other tables, the time taken is almost constant." | `company-case-study` | MySQL InnoDB, 25K 행 단위 배치 삽입, 25M 레코드까지 측정 | SSD vs HDD 환경 차이; buffer pool 크기 설정 영향; 동시 write 부하 환경; 단건 INSERT vs batch INSERT 차이 |
|
|
| PERCONA-UUID-C5 | Ordered UUID 테이블과 BIGINT 테이블은 삽입 시간과 크기가 거의 동일하다 (index 구조에 따라 약간 차이 가능) | [§Benchmarking] "Comparing the Ordered UUID table BIGINT table, the time is taken to insert rows and the size are almost the same. But they may vary slightly based on the index structure." | `company-case-study` | MySQL InnoDB, 동일 벤치마크 조건 | ordered UUID 가 BIGINT 와 완전히 동등하다는 보장; MySQL 8.0 의 `UUID_TO_BIN(..., 1)` 빌트인 함수 사용 시의 동작; UUID v7 (RFC 9562) 을 binary(16) 으로 저장한 경우의 동작 |
|
|
|
|
### Strength 적용 이유
|
|
|
|
이 자료는 Percona 엔지니어링 블로그다. Percona 는 MySQL 전문 컨설팅사로 신뢰도가 높지만, 이 포스트는:
|
|
- 2014년 작성 (MySQL 5.x 기준, MySQL 8.0 이전)
|
|
- 특정 스키마 + 특정 하드웨어 환경의 단일 벤치마크
|
|
- 동료 검토(peer review) 된 공식 표준이 아님
|
|
|
|
따라서 모든 Claim 은 `company-case-study` 로 분류한다. MySQL InnoDB clustered index 구조(C2) 는 MySQL 공식 레퍼런스 매뉴얼로 별도 보강 시 `official-vendor-doc` 로 격상 가능.
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
### 이 자료가 직접 증명하는 것
|
|
|
|
- `PERCONA-UUID-C2`: MySQL InnoDB 에서 secondary index 가 PK 를 포함한다는 구조적 사실 (D10 결정의 핵심 전제)
|
|
- `PERCONA-UUID-C3`: 25M 행 벤치마크에서 random UUID PK `binary(16)` vs ordered UUID `binary(16)` 의 50% 크기 차이 (D10 정량 근거)
|
|
- `PERCONA-UUID-C4`: random UUID 의 삽입 성능이 테이블 크기 증가와 함께 선형 저하하는 경향 (D10 index fragmentation 경고)
|
|
- `PERCONA-UUID-C5`: ordered UUID 와 BIGINT PK 의 성능·크기가 거의 동등함 (D10 trade-off: uuid 유니크성을 유지하면서 BIGINT 수준 성능 가능)
|
|
|
|
### 이 자료가 증명하지 않는 것
|
|
|
|
- **`varchar(36)` vs `binary(16)` 의 직접 크기 비교**: 벤치마크의 `events_uuid` 테이블은 이미 `binary(16)` 을 사용함 — char(36) 의 정량 비교는 이 포스트 범위 밖
|
|
- **PostgreSQL uuid native type 의 동작**: PostgreSQL 은 HEAP 기반 + 별도 MVCC 구조로 InnoDB clustered index 와 다름
|
|
- **MySQL 8.0 `UUID_TO_BIN(..., 1)` / `BIN_TO_UUID()` 빌트인 함수의 동작**: 2014년 포스트이며, 후속 포스트 참조 권고
|
|
- **UUID v7 (RFC 9562, 2024) 의 InnoDB 에서의 성능**: 이 포스트는 UUID v1 재정렬 전략. v7 은 native time-ordered 이므로 동일 원리가 적용되나, 벤치마크 미제공
|
|
- **`varchar(36)` vs `char(36)` 의 차이**: 이 포스트는 문제 제기에서 `char(36)` 을 언급하나 실제 벤치마크는 `binary(16)` 비교
|
|
- **TSID (64bit) vs binary(16) 의 성능 차이**: 이 포스트는 BIGINT vs binary(16) 비교는 있으나 TSID 의 ID 구조는 다름
|
|
|
|
### ca-skeleton D10 결정에 적용하려면 추가 확인이 필요한 것
|
|
|
|
- MySQL 8.0+ 에서의 `UUID_TO_BIN(UUID(), 1)` 를 사용한 UUID v7 저장 성능 (후속 Percona 포스트 또는 별도 벤치마크)
|
|
- PostgreSQL uuid native type 성능은 별도 PostgreSQL 레퍼런스 필요
|
|
- 실제 ca-skeleton 스키마에서 secondary index 수를 고려한 PK 비용 계산
|
|
|
|
## 메모 / Notes
|
|
|
|
- 이 포스트는 UUID v1 의 timestamp 부분을 재정렬하는 수동 방식을 제안함. MySQL 8.0 이후에는 `UUID_TO_BIN(UUID(), 1)` 가 동일 효과를 내장 함수로 제공.
|
|
- UUID v7 (RFC 9562, 2024) 은 이 포스트의 "ordered UUID" 전략과 동일한 원리 (time-ordered) 를 표준화한 것. 이 포스트의 벤치마크 결과는 UUID v7 의 성능 근거로 간접 인용 가능하나, UUID v7 의 직접 벤치마크가 아님을 명시해야 한다.
|
|
- 코멘트 섹션에서 Kevin Farley 는 BIGINT auto-increment PK + UUID secondary column 의 Dual 패턴을 대안으로 제시함 (D11 Public ID vs Internal Sequence 결정과 관련).
|
|
- 2014년 포스트이므로 MySQL 8.0 이전 기준. 후속 포스트("Storing UUID and Generated Columns") 를 별도 raw 로 보관하면 D10 근거를 강화할 수 있다.
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 official-doc: [[raw/official-docs/rfc9562-uuid]] — IETF RFC 9562 UUID v7 정의 (이 포스트의 ordered UUID 전략을 표준화한 것)
|
|
- 같은 주제 company-tech-blog: [[raw/company-tech-blogs/planetscale-nanoid-api]] — NanoID + BigInt PK Dual 패턴 (D11 관련)
|
|
- 후속 읽기 후보: Percona "Storing UUID and Generated Columns" (MySQL 8.0 `UUID_TO_BIN` 포함) — raw 미보관
|
|
- 이 자료를 인용한 wiki 요약: `wiki/concepts/uuid-storage-mysql` (생성 시)
|