はじめに 「UUID生成」は“かぶらないIDを雑に、でも安全に作る”技
業務システムを作っていると、ほぼ必ず出てくるのが「一意なIDが欲しい」という場面です。
注文ID、トランザクションID、ファイル名、トークン、セッションキー…。
ここで頼りになるのが UUID(GUID) です。
C# では Guid 型として標準で用意されていて、「ほぼ絶対にかぶらないID」を一行で生成できる道具だと思ってください。
ここでは、初心者向けに、
UUID(GUID)とは何か
C# での基本的な生成方法
文字列としてのフォーマット("D", "N", "B" など)の違い
業務ユーティリティとしてどうラップすると使いやすいか
を、例題付きでかみ砕いて説明していきます。
UUID / GUID の基本をおさえる
UUID と GUID の違い(ざっくりでOK)
用語としては、
- UUID(Universally Unique Identifier)
- GUID(Globally Unique Identifier)
がありますが、C# の世界では Guid 型として実装されています。
ここでは「UUID = GUID = Guid」くらいの理解で大丈夫です。
重要なのは、「ほぼ絶対に重複しない128ビットのID」という性質です。
「乱数+時間+その他いろいろ」を組み合わせて作られるので、
普通の業務システムで「かぶったらどうしよう」と心配する必要はまずありません。
典型的な見た目
よく見る形式はこんな感じです。
550e8400-e29b-41d4-a716-446655440000
8桁-4桁-4桁-4桁-12桁 の16進数で構成されています。
これが「文字列としてのUUID」です。
C# での基本:Guid.NewGuid()
一番シンプルな生成方法
UUIDを生成するコードは、たったこれだけです。
using System;
Guid id = Guid.NewGuid();
Console.WriteLine(id);
C#実行すると、例えばこんな感じの値が出ます。
550e8400-e29b-41d4-a716-446655440000
Guid.NewGuid() が「新しいUUIDを1つ作る」メソッドです。
これを呼ぶたびに、ほぼ絶対にかぶらない新しいIDが生成されます。
文字列として扱いたい場合
DBのキーやログに出したいときは、文字列にします。
Guid id = Guid.NewGuid();
string idString = id.ToString();
Console.WriteLine(idString); // 550e8400-e29b-41d4-a716-446655440000
C#ToString() のデフォルトは "D" フォーマット(ハイフン付き)です。
この形が一番よく使われます。
フォーマットの違いを知っておく(”D”, “N”, “B”, “P”)
よく使うフォーマット4種類
Guid.ToString には、いくつかのフォーマット指定子があります。
よく使うのはこの4つです。
Guid id = Guid.NewGuid();
Console.WriteLine(id.ToString("D")); // 550e8400-e29b-41d4-a716-446655440000
Console.WriteLine(id.ToString("N")); // 550e8400e29b41d4a716446655440000
Console.WriteLine(id.ToString("B")); // {550e8400-e29b-41d4-a716-446655440000}
Console.WriteLine(id.ToString("P")); // (550e8400-e29b-41d4-a716-446655440000)
C#ざっくりまとめると、
"D":ハイフン付き(デフォルト、よく見る形)"N":ハイフンなし(32桁の16進数だけ)"B":{}で囲む"P":()で囲む
業務でよく使うのは "D" と "N" です。
どれを使うかの目安
ハイフン付き "D" は、人間が見て識別しやすいので、ログや画面表示に向いています。
ハイフンなし "N" は、ファイル名やURLパラメータ、キー文字列など、
「余計な記号を入れたくない」場面でよく使われます。
例えば、ファイル名に使うならこうです。
string fileName = Guid.NewGuid().ToString("N") + ".tmp";
// 例: 550e8400e29b41d4a716446655440000.tmp
C#業務ユーティリティとしてラップする
「Guid.NewGuid() をそのまま書かない」メリット
小さなサンプルなら Guid.NewGuid() を直接書いてもいいのですが、
業務システムでは、ユーティリティクラスにまとめておくと後々楽です。
理由は、
- フォーマットを一箇所で統一できる
- テスト時に差し替えやすくなる(固定のIDを返すなど)
- 「何のためのIDか」が名前から分かる
からです。
シンプルなユーティリティ例
using System;
public static class UuidUtil
{
// ハイフン付き(デフォルト)UUID文字列
public static string NewStringD()
{
return Guid.NewGuid().ToString("D");
}
// ハイフンなしUUID文字列
public static string NewStringN()
{
return Guid.NewGuid().ToString("N");
}
// Guid 型そのものが欲しい場合
public static Guid NewGuid()
{
return Guid.NewGuid();
}
}
C#使い方はこんな感じです。
string orderId = UuidUtil.NewStringN(); // 注文ID用にハイフンなし
string logId = UuidUtil.NewStringD(); // ログ用にハイフン付き
Guid rawId = UuidUtil.NewGuid(); // DBのGuidカラム用
C#「どの形式をどこで使うか」をユーティリティのメソッド名で表現しておくと、
呼び出し側のコードがかなり読みやすくなります。
UUIDを「キー」として使うときの考え方
連番IDとの違い
DBの主キーとして、よくある選択肢は、
- 整数の連番(
int/bigint) - UUID(
uniqueidentifier/char(36)など)
です。
UUIDのメリットは、
- アプリ側だけで発行できる(DBに聞きに行かなくていい)
- システムをまたいでもIDがかぶりにくい
- 外部に漏れても「件数や順番」がバレにくい
といったところです。
一方で、
- 文字列としては長い
- インデックスのサイズが大きくなる
- 人間が手入力するには向かない
というデメリットもあります。
「外部公開するID」「トレース用ID」「分散システム間で共有するID」などにはUUIDが向いています。
「内部だけで使う単純なテーブルの主キー」なら、連番でも十分です。
「見せるID」と「内部ID」を分けるのもアリ
実務では、
- DBの主キーは連番
- 外部に見せるID(URLやAPIレスポンス)はUUID
という二重構造にすることもよくあります。
例えば、
public class Order
{
public long Id { get; set; } // DB内部用の連番
public string PublicId { get; set; } // 外部公開用のUUID文字列
}
C#PublicId に UuidUtil.NewStringN() を入れておけば、
URLに https://example.com/orders/550e8400e29b41d4a716446655440000 のように載せても、
内部の連番構造が外からは見えません。
UUIDをパースする・検証する
文字列から Guid に戻す
UUID文字列を受け取って Guid に戻したい場合は、Guid.Parse / Guid.TryParse を使います。
string text = "550e8400-e29b-41d4-a716-446655440000";
Guid id = Guid.Parse(text); // 不正な文字列なら例外
// 例外を避けたいなら TryParse
if (Guid.TryParse(text, out var parsed))
{
Console.WriteLine(parsed);
}
else
{
Console.WriteLine("UUIDとして不正な文字列です");
}
C#"D" 形式でも "N" 形式でも、Guid.TryParse はちゃんと解釈してくれます。
UUID文字列の検証ユーティリティ
「これはUUIDとして妥当な文字列か?」だけを見たい場合は、Guid.TryParse をラップしたユーティリティを用意しておくと便利です。
public static class UuidValidator
{
public static bool IsValidUuid(string? value)
{
if (string.IsNullOrWhiteSpace(value))
{
return false;
}
return Guid.TryParse(value.Trim(), out _);
}
}
C#これで、
Console.WriteLine(UuidValidator.IsValidUuid("550e8400-e29b-41d4-a716-446655440000")); // true
Console.WriteLine(UuidValidator.IsValidUuid("550e8400e29b41d4a716446655440000")); // true
Console.WriteLine(UuidValidator.IsValidUuid("not-a-uuid")); // false
C#のように、「UUIDっぽいかどうか」を簡単にチェックできます。
まとめ 「UUID生成ユーティリティ」は“世界でかぶらないIDを、気負わず配るための道具”
UUID(GUID)は、「ほぼ絶対にかぶらないID」を簡単に作るための標準ツールです。
C# では Guid.NewGuid() 一発で生成でき、ToString("D") / "N" で用途に応じた文字列にできます。
押さえておきたいポイントは、
Guid.NewGuid() がUUID生成の基本ToString("D")(ハイフン付き)と "N"(ハイフンなし)を使い分ける
ユーティリティクラスにラップして、フォーマットと用途を名前で表現する
外部公開IDやトレースIDにはUUIDが向いているGuid.TryParse を使えば、UUID文字列の検証やパースも簡単にできる
ここまで理解できれば、「なんとなく Guid.NewGuid() を呼んでいる」段階から一歩進んで、
“業務の中で意味のあるID設計”の一部として、UUID生成ユーティリティを自分の手で組み込めるようになっていきます。
