UUID は「ほぼかぶらない ID を即席で作る道具」
業務システムでは、「世界中どこで作っても、まずかぶらない ID」が欲しくなる場面がよくあります。
注文番号、トランザクション ID、一時ファイル名、トレース ID、外部連携のキー…人間が連番を振るのは危険だし、複数サーバーで同時に動くと「誰がどの番号を取るか」の調整も面倒です。
そこで出てくるのが UUID(Universally Unique Identifier)です。
Java には標準で java.util.UUID クラスがあり、「ほぼ二度とかぶらないランダムな ID」を簡単に生成できます。
ここでは、初心者向けに「UUID って何者か」「どう使うか」「業務でどうユーティリティ化すると気持ちいいか」をかみ砕いて話していきます。
Java の UUID 基本:使い方と形をまず押さえる
UUID.randomUUID() で一発生成
一番基本の使い方はこれです。
import java.util.UUID;
UUID uuid = UUID.randomUUID();
System.out.println(uuid.toString());
Java出力されるのは、だいたいこんな形の文字列です。
550e8400-e29b-41d4-a716-446655440000
ハイフンで区切られた 32 桁の 16 進数(+ハイフン 4 つ)で、合計 36 文字の文字列です。
この形は「バージョン 4 UUID」と呼ばれるランダム型の UUID で、Java の randomUUID() はこれを生成します。
ここで大事なのは、「自分で何も考えなくても、ほぼかぶらない ID が一瞬で手に入る」という感覚です。
連番を管理しなくていい、DB に取りに行かなくていい、サーバー間で調整しなくていい──これが UUID の一番の価値です。
UUID を文字列として扱うか、UUID 型のまま扱うか
UUID はクラスなので、そのままオブジェクトとして持つこともできますし、toString() して文字列として扱うこともできます。
UUID uuid = UUID.randomUUID();
String idAsString = uuid.toString(); // 文字列として保存・表示
UUID parsed = UUID.fromString(idAsString); // 文字列から UUID に戻す
JavaDB に保存するときや JSON に出すときは文字列にすることが多く、
アプリ内部では UUID 型のまま扱う、という設計もよくあります。
初心者のうちは、「外に出すときは文字列、内側では UUID 型でも文字列でもどちらでもよい」と覚えておけば十分です。
「ほぼかぶらない」の意味をちゃんとイメージする
かぶる確率は現実的にはゼロと思っていいレベル
UUID v4 は 128 ビットの値で、そのうちランダムに使われるのは実質 122 ビット程度です。
組み合わせの数は天文学的で、「地球上の全コンピュータが毎秒何億個と UUID を生成し続けても、宇宙が終わるまでにかぶる確率はほぼゼロ」と言われるレベルです。
もちろん数学的には「絶対にかぶらない」とは言えませんが、業務システムのスケールでは「かぶらない前提で設計してよい」と考えて問題ありません。
この「ほぼ絶対にかぶらない ID を、どこからでも勝手に生成してよい」という性質が、分散システムやマイクロサービスで特に強力です。
連番と UUID のトレードオフ
UUID は便利ですが、「人間が読むには長くてつらい」「ソート順が時間順にならない」といったデメリットもあります。
一方、連番(1, 2, 3, …)は人間には分かりやすいですが、複数サーバーで一意にするには DB のシーケンスや集中管理が必要になります。
業務では、「外部に見せる注文番号は連番+プレフィックス」「内部の主キーやトレース ID は UUID」といった使い分けをすることが多いです。
UUID は「人間に優しい ID」ではなく、「システムに優しい ID」だと捉えるとしっくりきます。
実務で使いやすくする UUID ユーティリティの例
文字列としての UUID を返すユーティリティ
業務コードでは、「とにかく新しい ID が欲しい」という場面が頻出します。
そのたびに UUID.randomUUID().toString() と書くのは少しうるさいので、ユーティリティにまとめてしまうのが定番です。
import java.util.UUID;
public final class Uuids {
private Uuids() {}
// 標準形式(ハイフンあり)の UUID 文字列を生成
public static String newId() {
return UUID.randomUUID().toString();
}
// ハイフンなし 32 桁の UUID 文字列を生成
public static String newCompactId() {
return UUID.randomUUID().toString().replace("-", "");
}
}
Java使う側はこうなります。
String orderId = Uuids.newId();
System.out.println(orderId); // 550e8400-e29b-41d4-a716-446655440000 みたいな文字列
String token = Uuids.newCompactId();
System.out.println(token); // 550e8400e29b41d4a716446655440000 みたいな 32 桁
JavanewCompactId() のようにハイフンを抜いた形式は、「URL に埋め込みたい」「ファイル名に使いたい」「DB のカラム長を節約したい」といった場面でよく使われます。
ただし、どの形式を使うかはシステム全体で統一しておくことが大事です。
UUID 文字列のバリデーション
外部から UUID 文字列を受け取る場合、「本当に UUID の形式か」をチェックしたくなることがあります。UUID.fromString は、不正な形式の文字列を渡すと IllegalArgumentException を投げるので、これを利用して簡単なバリデーションができます。
public static boolean isValidUuid(String s) {
if (s == null) return false;
try {
UUID.fromString(s);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}
Java使い方はこうです。
String input = getIdFromRequest();
if (!isValidUuid(input)) {
// 400 Bad Request にするなど
}
Javaこれで、「UUID っぽいけど実は違う文字列」が紛れ込むのを防げます。
業務では、「外から来るものは疑う」「中で作るものは信じる」というスタンスが基本なので、入口でこうしたチェックをしておくと安心です。
UUID をどこで生成するか、という設計の話
DB で生成するか、アプリで生成するか
一意な ID を作る方法としては、DB のシーケンスや AUTO_INCREMENT を使う方法もあります。
UUID を使う場合でも、「DB 側で UUID を生成する」のか「アプリ側で UUID を生成する」のか、という選択肢があります。
アプリ側で UUID.randomUUID() を呼ぶメリットは、次のようなものです。
アプリだけで完結するので、DB に依存しない ID 生成ができる。
DB に行く前に ID が決まるので、ログやトレースに使いやすい。
テストコードでも簡単に ID を生成できる。
一方、DB 側で UUID を生成する場合は、「DB が真の ID 発行元になる」というメリットがありますが、
アプリから見ると「INSERT してみないと ID が分からない」こともあり、ログ設計やトレース設計が少しややこしくなります。
初心者向けには、「まずはアプリ側で UUID.randomUUID() を使う」設計から入るのが分かりやすいです。
トレース ID や相関 ID としての UUID
マイクロサービスや分散システムでは、「1 件のリクエストがシステム内をどう流れたか」を追跡するために、トレース ID(相関 ID)を付けることがよくあります。
ここでも UUID がよく使われます。
例えば、HTTP リクエストを受けたときに 1 つ UUID を生成し、それをログのすべての行に付けるようにします。
String traceId = Uuids.newId();
log.info("[traceId={}] リクエスト開始", traceId);
// 以降のログにも traceId を付けて出す
Java障害が起きたときに、「この traceId のログを全部見せて」と言えば、そのリクエストに関するログだけを抽出できます。
UUID の「かぶらない」「どこでも生成できる」という性質が、こうしたトレース設計と非常に相性が良いです。
UUID を使うときに意識しておきたい注意点
並び順やソートを期待しない
UUID v4 はランダムなので、「生成順に並べると時間順になる」といった性質はありません。
「新しい順に並べたい」「日付で範囲検索したい」といった要件がある場合は、別途タイムスタンプや連番を持つ必要があります。
「ID の見た目から何か意味を読み取る」こともできません。
UUID はあくまで「意味のない一意なラベル」です。
人間に見せる ID としては不親切
UUID は長くて読みにくいので、「電話で読み上げる」「紙に書く」といった用途には向きません。
顧客に見せる注文番号や受付番号には、もっと短くて分かりやすい形式(連番+チェックディジットなど)を使うのが普通です。
その場合でも、内部的な主キーやトレース ID として UUID を併用する、という設計はよくあります。
「外向きの ID」と「内向きの ID」を分ける、という発想を持っておくと、設計の幅が広がります。
まとめ:初心者が UUID 生成で身につけるべき感覚
UUID は、「世界中どこで作っても、まずかぶらない ID を、アプリだけで即座に作れる道具」です。
Java では UUID.randomUUID() で簡単に生成でき、toString() で文字列として扱えます。
業務で本当に効いてくるのは、「ID をどこで生成するか」「どの形式で統一するか」「どこまで UUID に任せるか」という設計の部分です。
ユーティリティとして Uuids.newId() のようなメソッドを用意しておくと、現場のコードがかなりスッキリします。

