Firestoreの自動生成 IDが衝突しないか実際に試そうとしてみる。


Firestoreでaddするときに生成されるIDって衝突しないのか問題

こちらでも案内されていますが、そうそう衝突しないそうです。

FirestoreのautoIDで生成されるのは20桁のランダムな英数の組み合わせです。

autoIdのロジックこのようになってます。(すこし手直ししてます)

autoId: function() {
 const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
 let autoId = '';
 for (let i = 0; i < this.strength; i++) {
  autoId += chars.charAt(Math.floor(Math.random() * chars.length));
 }
 return autoId;
}

いきなり20桁で衝突するまでループさせたらブラウザが落ちるので、すこしづつ桁を増やして衝突するまでの回数をカウントしてみました。理屈的には最大で「大文字小文字英数26+26+10=62文字^桁」個作れば必ず衝突するはず。期待値は計算がよくわかりませんw

検証結果

3桁から始めたんですが、クライント(mac - chrome)では、しばらくほっておいても6桁までしか答えがでませんでした。同じ桁で5回試してます。

桁数 繰り返し 衝突までの回数
3 0 482
3 1 196
3 2 896
3 3 674
3 4 513
4 0 4,862
4 1 4,459
4 2 10,343
4 3 10,119
4 4 10,252
5 0 32,336
5 1 36,289
5 2 57,630
5 3 30,874
5 4 19,568
6 0 341,898
6 1 86,129
6 2 421,980
6 3 174,363
6 4 480,189

平均値など

各桁5回しか試してないので偏差は誤差大きそうなので出してません。

桁数 衝突回数:平均値 衝突回数:最大62^桁
3 552 238,328
4 8,007 14,776,336
5 35,339 916,132,832
6 300,912 56,800,235,584

なんか思ってた(期待値)より少ない回数で衝突してますね。

これが誕生日のパラドックスってのでしょうか?

実際には6桁ではなくて20桁ですので、62^20=7.0442343e+35=704,423,430,000,000,000,000,000,000,000,000,000個ですので、実害ない程度では衝突しないんでしょう。

ただ自分は心配性なので、そのドキュメントIDで既に他のドキュメントがあるかチェックしたいな...

ただ、

const id = firestore.collection('hoge').doc().id;
const docRef = firestore.collection('hoge').doc(id);

などで、docRefをとっても実際にget()しないと空かどうかわからないですよねぇ?get()するとdocument readの割り当てを消費しちゃいますし...