uuid gemについて
uuid gemを使用している場合、一意性について心配する必要はありません。ただし、uuid は長い 128 ビットの一意の ID を生成します。したがって、より短いものが必要な場合は、使用したくない場合があります。
ニーズが単純な場合は、より簡単な方法
たとえば、ランダムでもある 8 桁の一意のコードが必要な場合は、メソッドの下のnew_unique_code
私の cortex プロジェクトでそのようなシステムの実装を見ることができます。
これにより、アプリ内のリソースを表す 8 桁の英数字コードが生成されます。特定のコードを生成した後、 を実行しようとしましたが.find_by_code
、それが返された場合、それがまだ使用されていないnil
ことがわかります。
私の特定のケースでは、8 桁の英数字コードにより、数百万の可能なコードのキースペースが得られます (その数は忘れました)。私のアプリのユースケースに基づくと、コード衝突の可能性 (使用されているコードと使用可能なコードの割合) は十分に小さいため、特定のリソースに対して新しいコードを複数回生成する必要がある可能性があります。
その結果、特定のリソースに対して新しいコードを複数回生成する必要が生じることは非常にまれであり、追加の時間はほとんどかかりません。
アプリ内の複数のアプリ サーバー/スレッドはどうですか?
私のソリューションの 1 つの制限は、アプリ サーバーが複数あり、DB サーバーが 1 つしかない場合、2 つの独立したアプリ サーバーが同じコードを生成してから、それらのいずれかが集中型 DB に新しいリソース レコードを作成する可能性があることです。これにより、コードの競合が発生する可能性があり、DB に保存された最初のレコードを除くすべてのレコードが無効とマークされる可能性があります (コード列の一意性制約のため)。この特定のアプリは、単一のアプリ サーバー インスタンス上でのみ実行されます (おそらく今後も実行される可能性があります)。これは私が認識している既知のトレードオフであるため、危険を冒すことができます。
しかし、この問題を解決したい場合は、各アプリ サーバーのランダム コードの範囲を制限して、それらが誤って重複しないようにします。たとえば、値 00000000 ~ 99999999 の間の 8 桁の数値コードとして出力されるランダム コードを生成しているとします。たとえば、このアプリを実行する 3 つのアプリ サーバーがある場合、サーバー #1 を 00000000 から 33333333 の間のコードを生成するように制限し、サーバー #2 を 33333334 から 66666666 に、サーバー #3 を 66666667 から 99999999 に制限します。このようにして、コードが重複しないことが保証され、一意のランダムなキーを 1 日中生成できます。
特定のサーバーを特定の範囲に正確に制限する方法は少し話題から外れますが、利用可能なオプションのいくつかは次のとおりです。
- 各アプリ サーバー内で構成設定を手動で設定します。これは手動です (したがって不安定です) が、変更されない安定した数のアプリ サーバーがある場合は、おそらくこれで問題ありません。
- アプリ サーバーを相互に通信させ、乱数の範囲をネゴシエートします。
- あきらめて、これは非常に賢い人々によって解決された複雑な問題であり、ホイールを再作成する必要はなく、UUID を使用するだけであることを認識してください。
- Twitter Snowflakeなど、ネットワーク サービスとして実行される一元化された一意の ID ジェネレーターの使用を検討してください。