LoginSignup
15

UUID 以外のユニークなIDって何があるの?

Last updated at Posted at 2022-12-05

はじめに

いつもユニークな ID に UUID を使っているのですが、他には何かあるのでしょうか?
気になったので調べてみました!

紹介するもの

この記事ではこれらを紹介します

利用数

npm のDL数を2022年の月別で比べてみます。グラフは npm-stat を使わせていただきました。

UUID と NanoID がよく使われているようです。
UUID が NanoID の 3倍、NanoID が CUID の30倍使われています。

image.png

UUID と NanoID を除くと以下のようになりました。

image.png

それぞれの特徴

UUID がとても使われているのはわかりました。続いて、それぞれの特徴を紹介します。

UUID

まずはみんな大好き UUIDです!ここではメジャーなバージョン4を紹介します。

UUIDバージョン4 は16進数の文字32個で構成されています。ひとつのUUIDにつき128ビットありますが、そのうち6ビット (1文字と半分) を規格で使っています。

形式は以下です。
RRRRRRRR-RRRR-4RRR-rRRR-RRRRRRRRRRRR ※Rがランダム、4が固定、rが2ビットだけ固定

6ビットを使っているので、122ビットが乱数になりますね。つまり $2^{122} \approx 5.3×10^{36}$ 通りの UUID が存在することになります。

衝突確率について、衝突するまでの生成回数の期待値は $2^{122/2} \approx 2.3*10^{18}$ 個となります。まず衝突しないですね。
参考:誕生日攻撃

NanoID

次は NanoID です!

NanoID はUUIDの問題とされていた、「生成結果の文字列が長い」ことを解決したものです。
UUID が36文字なのに対し、NanoID は21文字です。かなり短くなりましたね。

また、ランダム部分が 126ビットあって UUID の122ビットと比べて少し強固です。

形式です。
V1StGXR8_Z5jdHi6B-myT

生成速度が気になっていたのですが、NanoID の作者がまとめてくださっていました。ありがたい。

$ node ./test/benchmark.js
crypto.randomUUID         21,119,429 ops/sec
uuid v4                   20,368,447 ops/sec
@napi-rs/uuid             11,493,890 ops/sec
uid/secure                 8,409,962 ops/sec
@lukeed/uuid               6,871,405 ops/sec
nanoid                     5,652,148 ops/sec
customAlphabet             3,565,656 ops/sec
secure-random-string         394,201 ops/sec
uid-safe.sync                393,176 ops/sec
cuid                         208,131 ops/sec
shortid                       49,916 ops/sec

ULID

続いてULIDです!

ULID は、UUIDの問題を解消したものとなっています。
ULID が解消した UUIDの問題は 「生成結果の文字列が長い」「ソートできない」 です。
そう。ULIDは生成時間でソートできるのです。よさそうですね。

形式は以下です。
01AN4Z07BY79KA1307SR9X4MV3 ※前半48bit がtimestamp で、後半80bit がランダムです。

前半に timestamp があるからソートできるんですね!また、16進数ではなく英数字を使うことで UUID よりも文字数が減っています。
タイムスタンプは西暦 10889年まで対応しています。未来永劫つかえる UUID に比べると短い期間ですが、それでも十分でしょう。
UUID に比べてランダム部分のbit数が少ないですが、同じミリ秒内に $1.21*10^{24}$ 個までの生成であればソート可能性が保たれるとのことです。timestamp がミリ秒単位で変わるので、こちらも実用上は問題なさそうですね。

CUID

最後にCUIDです!

CUID は UUID の問題を解決しながら、ULID よりも良いとされているものです。
ULID との具体的な違いはこちら https://github.com/paralleldrive/cuid/issues/103

まずは形式です。
ch72gsb320000udocl363eofy
分解するとこうなります。 c - h72gsb32 - 0000 - udoc - l363eofy
c: 固定値
h72gsb32: timestamp
0000: Counter
udoc : クライアントのfingerprint
l363eofy: ランダム

です。UUID や ULIDに比べていろいろありますね。

CUID の特徴です。

  • スケーラブル
  • fingerprintがあるので、複数のクライアント間では衝突しない
  • 水平方向のスケーラビリティができる
  • パフォーマンスが良い

ULID に比べてランダム部が小さいですが、同じミリ秒内に10000までの生成であればソート可能性が保たれます。同じくtimestamp がミリ秒で変わるので、実用上は問題ないことがほとんどだと思います。

ソースを見てみると、非推奨となっている String.prototype.substr() が使われていました。要注意かも?

さいごに

私は UUID しか知らなかったのですが、生成順でソートできるのは良さそうですね!
それぞれの利点と欠点を知って、使いわけるのはかなりアリだなって思いました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15