NewSQL ではなぜ連番 PRIMARY KEY を使うべきではないのか
TiDB、CockroachDB、YugabyteDB、Cloud Spanner…
近年「NewSQL(分散SQLデータベース)」が一般化しつつあります。
しかし、従来型 MySQL/PostgreSQL の感覚で ID を設計すると、
性能が大きく劣化する “罠” があります。
結論:NewSQL では AUTO_INCREMENT(連番)を使うと性能が落ちる。
現状は UUIDv4 を使うべき。
そして将来、UUIDv7 が正式サポートされれば v7 が最適解になる。
この記事では、
連番が生む問題 → UUIDがどう解決するか
という形で全体を整理します。
❌ 連番 PRIMARY KEY が NewSQL でダメな理由(3つ)
1. ホットスポットが発生する(分散DBで特に致命的)
NewSQL はデータを複数ノードに分散して保持します。
その際、PRIMARY KEY が シャードキーとして使われるケースが多いです。
連番ID(AUTO_INCREMENT)の場合:
- すべての新規レコードが「PK最大値の付近」に挿入
- → 1つのノードに書き込みが集中
- → ホットスポット発生 → 全体性能が低下
公式の警告(一次情報)
CockroachDB:
“Sequential keys cause hotspots… avoid monotonically increasing primary keys.”
Cloud Spanner:
“Primary keys with increasing values lead to hotspotting.”
2. インデックス末尾に集中し、ページ分割が頻発する
インデックス(B-tree / LSM-tree)も連番に弱いです。
- PKの値が常に「右端(最大値)」に追加
- 同じページばかり更新
- ページが満杯 → 分割(split)を繰り返す
- ページ分割は最も高コストな処理の1つ
→ 単体 MySQL / PostgreSQL でも遅くなりますが、
分散DBではこれが倍化するためさらに深刻。
3. セキュリティ的にも弱い(予測可能)
- 連番IDはURLやAPIで露出しやすい
- 次に発行されるIDが推測可能
- アクセスコントロールミス → IDOR脆弱性につながる
✔ では、UUID はこれらの問題をどう解決するのか?
解決①:ホットスポットを起こしにくい
UUID(特に v4)は ランダム なので、
- 新規IDが値空間のどこに落ちるか分散される
- シャードへの書き込みが偏りにくい
- 1ノードだけが過負荷になる現象が起きにくい
つまり、
連番の「常に末尾に集中する」問題を、
UUID は「分散させる」ことで解消する。
解決②:インデックス全体に散るため、ページ分割が起きにくい
UUID の値は B-tree / LSM のさまざまなページに散るため、
- 同じページに集中しない
- どのページもまんべんなく更新される
- 1つのページだけ膨れ続ける状況が起きない
- → ページ分割(split)が減る → 挿入が安定
B-tree にとって「連番」は最悪で、
「ランダムに散るキー」のほうが遥かに効率的です。
解決③:推測不能 → セキュリティも向上
UUID はランダム(または時系列+ランダム)であるため、
- 連番のように推測されない
- URLやAPIで露出しても安全性が高い
✔ 現状は UUIDv4 が最適(理由は3つ)
1. 主要な NewSQL が公式にサポート済み
- CockroachDB →
gen_random_uuid()は UUIDv4 を実装 - YugabyteDB → PostgreSQL互換なので UUIDサポート
- TiDB → MySQL互換で UUID(文字列)利用実績が多い
- Spanner → UUIDv4 をアプリ側生成が一般的
2. 完全ランダムのため偏りが起きない
- シャーディングに最適
- インデックスにも優しい
3. ライブラリも豊富で実績多数
- Node.js / Go / Python / Java どれでも簡単に生成可能
🚀 将来、UUIDv7 がサポートされたら “v7 が最適” になる理由
UUIDv7 は最新仕様(RFC 9562)で登場した
「時系列+ランダム」のハイブリッドUUID です。
✔ v7 は v4 と連番の “いいとこ取り”
● 前半:ミリ秒単位の timestamp
→ ほぼ単調増加 → インデックス効率が極めて良い
● 後半:暗号学的ランダム
→ シャードが偏らない → ホットスポットが起きにくい
つまり、
UUIDv4 の“分散性”と、
AUTO_INCREMENT の“増加順挿入の効率”を兼ね備えた理想形。
✔ v7 はインデックスとも相性が良い
- 「前半が増加 → B-tree に優しい」
- 「後半が分散 → ページ分割が起きにくい」
インデックス性能で見ても v4より優秀。
✔ v7 はセキュアで予測不能
- v1 と違い MAC アドレスなどは含まない
- 衝突確率は v4 と同等で極めて低い
✔ ただし注意:現時点では主要 NewSQL がネイティブ対応していない
2025年時点で公式サポート状況はまだ限定的なため
実運用では v4 が安全。
✔ 最終まとめ
| ID方式 | ホットスポット | インデックス効率 | セキュリティ | 現状実用性 | 将来性 |
|---|---|---|---|---|---|
| AUTO_INCREMENT | ❌ 最悪 | ❌ 分割多発 | ❌ 推測可能 | × 避けるべき | × |
| UUIDv4 | ○ 分散される | ○ ランダムで安定 | ◎ 予測不可 | ◎ 現時点の最適解 | ○ |
| UUIDv7 | ◎ 最も減る | ◎ 時系列+分散で最強 | ◎ 予測不可 | △ まだサポート少 | ◎ 将来の最適解 |
🎯 結論
NewSQL では AUTO_INCREMENT を使わない。
今は UUIDv4 を使うのが最適。
将来、UUIDv7 が正式サポートされたら v7 に移行する。なぜなら、UUIDv7 は
「時系列性・分散性・高速性・インデックス効率・安全性」
のすべてを満たす唯一の識別子だから。
📚 参考文献(一次情報)
- CockroachDB Docs — Primary Key & UUID
https://www.cockroachlabs.com/docs/stable/uuid - Cloud Spanner Docs — Hotspotting
https://cloud.google.com/spanner/docs/schema-design#primary-keys - TiDB Docs
https://docs.pingcap.com/tidb/stable/ - RFC 9562(UUIDv7 specification)
Discussion