したがって、私のアプリでは、ユーザーがA6BU31、38QV3B、R6RK7T などのランダムな英数字コードを生成できるようにする必要があります。現在、それらは 6 文字で構成されていますが、I と O は使用されていません (したがって、34^6 の可能性があります)。これらのコードは印刷され、別の用途に使用されます。
ここで、多くのユーザーが要求ごとに最大 100 個のコードを「予約」できるようにする必要があります。ユーザー A は 50 個のコードを取得したい場合、ユーザー B は 10 個のコードを生成したい場合があります。これらのコードはすべてのユーザーで一意である必要があるため、ユーザー A とユーザー B の両方がコード ABC123 を受け取ることはありません。
私の現在のアプローチ (PHP と MySQL を使用) は、このために 2 つの InnoDB テーブルを用意することです。
- 1つ(「リポジトリ」)には、事前に生成されたコードの大きなリストが含まれています(時間の経過とともに衝突の可能性が高まり、try-insert-if-fails-try-another-codeアプローチに行きたくないため)。リポジトリには、コードと自動インクリメントされた ID のみが含まれています (したがって、それらを並べ替えることができます。以下を参照してください)。
- もう 1 つのテーブルには、予約済みのキー (つまり、コード + 所有ユーザー) が保持されます。
ユーザーがN個のキーを予約したいときはいつでも、私は次のことを計画しました
BEGIN;
INSERT INTO revered_codes (code,user_id)
SELECT code FROM repository WHERE 1 ORDER BY id LIMIT N;
DELETE FROM repository WHERE 1 ORDER BY id LIMIT N;
COMMIT;
これはうまくいくはずですが、よくわかりません。WTF ソリューションを構築しているようです。
挿入後、予約したコードを選択してユーザーに表示する必要があります。トランザクションが完了した後に予約済みのコードを特定する方法がよくわからないため、これは難しい部分です。reserved_codes
もちろん、ある種のランダムなトークンを保持する別の列をテーブルに追加することもできますが、これはさらに WTFy のようです。
私のお気に入りの解決策は、テーブルINSERT
で操作を実行できるように、乱数シーケンスを使用することです。reserved_codes
では、MySQL でこのユニークでランダムなトランザクション セーフ シーケンスを実行するにはどうすればよいでしょうか? 1 つのアイデアは、テーブルに定期的な自動インクリメントを設定し、reserved_codes
その数値列からランダムなコード値を導出することでしたが、もっと良い方法があるかどうか疑問に思っていました。
更新:後でそれらを更新するために単一のコードを再度見つける必要があるため、予約済みコードのかなり小さなテーブルを持つことが有利であることを言及するのを忘れていました (reserved_codes
さらにいくつかの属性があります)。したがって、予約済みテーブルをゆっくりと大きくすることは良いことです (事前に生成されたコードで最大 100 万個以上の巨大なインデックスを作成する代わりに)。