MongoDBに自動インクリメントIDがなく、正当な理由があるという選択された回答の作成者に強く同意しません。 。 10genが自動インクリメントIDの使用を推奨しなかった理由はわかりません。それは憶測です。クラスター環境で12バイトIDの一意性を確保する方が簡単なため、10genがこの選択を行ったと思います。したがって、ほとんどの新規参入者に適合するデフォルトのソリューションであるため、製品の採用が増え、10genのビジネスに適しています。
それでは、商用環境でのObjectIdの使用経験について皆さんに話させてください。
私はソーシャルネットワークを構築しています。約600万人のユーザーがいて、各ユーザーには約20人の友達がいます。
ここで、ユーザー(誰が誰をフォローするか)間の関係を格納するコレクションがあると想像してください。このように見えます
_id : ObjectId
user_id : ObjectId
followee_id : ObjectId
一意の複合インデックス{user_id, followee_id}
があります 。このインデックスのサイズは12*2 * 6M * 20=2GBと見積もることができます。これが、私がフォローしている人をすばやく検索するためのインデックスです。私をフォローしている人をすばやく検索するには、逆インデックスが必要です。それはもう2GBです。
そして、これはほんの始まりに過ぎません。私はこれらのIDをどこにでも持っていかなければなりません。ニュースフィードを保存するアクティビティクラスターがあります。それはあなたやあなたの友人が行うすべてのイベントです。どれだけのスペースが必要か想像してみてください。
そして最後に、エンジニアの1人が無意識のうちに決定を下し、参照を、サイズを2倍にするObjectIdを表す文字列として保存することにしました。
インデックスがRAMに収まらない場合はどうなりますか?良いことは何もない、と10genは言います:
インデックスが大きすぎてRAMに収まらない場合、MongoDBはディスクからインデックスを読み取る必要があります。これは、RAMから読み取るよりもはるかに遅い操作です。サーバーに、残りのワーキングセットと組み合わせてインデックスに使用できるRAMがある場合、インデックスはRAMに収まることに注意してください。
つまり、読み取りが遅いということです。ロックの競合が発生します。書き込みも遅くなります。ロックの競合が80%になっているのを見ると、もうショックではありません。
あなたがそれを知る前に、あなたはシャードに分割しなければならず、操作するのが非常に難しい460GBのクラスターになってしまいました。
FacebookはユーザーIDとして64ビットを使用します:)それには理由があります。シーケンシャルIDを生成できます
- 10genのアドバイス 。
- mysqlをカウンターのストレージとして使用する(速度が心配な場合は、 handlersocket )
- 作成したID生成サービスを使用するか、Snowflake> Twitterで。
これが私の一般的なアドバイスです。データはできるだけ小さくしてください。あなたが成長するとき、それはあなたに眠れない夜をたくさん救うでしょう。