うーん...ここで私のCSの知識が私を失望させます。一意の参照番号を生成するアルゴリズムを書きたいです。
セキュリティ上のリスクがあるため、連番は使用したくありません。また、英数字を使用したいと考えています。ref にも最小長と最大長があります。(長すぎる GUID は使用できません)
理想的には、ref が以前に使用されたかどうかを確認するために永続化レイヤーにクエリを実行したくありません。
どのような戦略を採用できますか?
うーん...ここで私のCSの知識が私を失望させます。一意の参照番号を生成するアルゴリズムを書きたいです。
セキュリティ上のリスクがあるため、連番は使用したくありません。また、英数字を使用したいと考えています。ref にも最小長と最大長があります。(長すぎる GUID は使用できません)
理想的には、ref が以前に使用されたかどうかを確認するために永続化レイヤーにクエリを実行したくありません。
どのような戦略を採用できますか?
この番号が人間によって参照される場合は、ソリューションで次のガイドラインに従うことをお勧めします。
データベースと同期して次の番号を確認できず、GUID や比較的長いランダム文字列を使用できない場合は、ID に何らかのローカル値を含める必要があります。
たとえば、すべてのクライアントが既知のネットワーク上にある場合、各クライアントの IP アドレス D ブロックで各番号を終了できます。
または、クライアントがログインする必要があり、各ユーザーが一度に 1 回しかログインできない場合は、番号のどこかにユーザー ID を含めることができます。
セキュリティ リスクが心配な場合は、暗号的に安全な乱数ジェネレーターが必要です。必要なバイト数 (つまり、数値の長さ) を指定できる必要があります。
ここで暗闇の中で突き刺していますが...一意であるが16バイト未満のランダムな値が必要です。あなたの最善の策は、まだわずか16バイトのGUIDです....英数字を使用したいので...いくつかのオプション。
GUID を使用してエンコードします base64 は 7QDBkvCA1+B9K/U0vrQx1A のように見えますが、これは 22 バイトであり、ネイティブ Guid よりも長いですが、典型的な文字列表現よりも短いです。
こちらのテキスト エンコーディングを参照してください: http://en.wikipedia.org/wiki/Globally_Unique_Identifier
もう 1 つのオプションは、Guid をハッシュすることですが、一意性の一部が失われるため、一意でないアイテムに対する許容レベルはどのくらいですか?
==========
テーブルに挿入するプロセスが 1 つあると仮定すると、HiLo アルゴリズムを使用して、毎回 DB にアクセスする必要がないと確信できます。最後の高値をメモリに保存するだけです...プロセスが起動したら、データベースにアクセスして、中断した場所を見つけます。ハイ/ローアルゴリズムとは何ですか?
私はまだGuidが最善の策だと言います....16バイトは悪くなく、思いつくほとんどの英数字ソリューションと同じくらい小さくなります。
1つの方法は、数値のより小さなサブセットに基づいて数値を生成することです。たとえば、バイナリシーケンスを使用して、ゲーデル数に基づいて生成できます。たとえば、5z、3y、2xで000を111にマッピングすると、0、2、3、6、5、10、15、30になります。
もちろん、これは過度に単純化されています。ただし、「ソルト」番号を繰り返して参照番号を生成することにより、参照番号を追跡する必要がまったくなくなります。もちろん、衝突を考慮に入れる必要がないと合理的に確信していました。
アプリケーション/環境で可能であれば、疑似乱数で生成された数値の一部として時間を追加することを検討しましたか?
つまり、microtime()+ rand(10000,99999)
私はこれを本番システムで成功させてきました。
これを文字列としてメモリに入れるか、値をXORするか、類似したものにします。それで:
UIDをNバイトに縮小すると、UIDの衝突の可能性が高くなることに注意してください。
最初のリストのすべての入力データは、多数のコンピューターのクラスターがある場合に、ハッシュの一意のベースを確実に取得するためのものです。それらの一部は省略できますが、UIDを生成するコンピューターごとに異なるものが含まれていることを確認する必要があります。
GUID を必要なサイズに切り捨てます。
数値を生成している場合は、それらがランダムで巨大でない限り、とにかく使用されているかどうかを確認することをお勧めします.