web-dev-qa-db-ja.com

2人のユーザーが同じユーザー名で同時に登録するのを防ぐ方法は?

何百万ものユーザーが同時に登録しているため、登録をシリアル化できません。並列登録を行う必要があります。

データベースにユーザー名「user1」が含まれていないとしましょう。 2人のユーザーが「user1」で同時に登録しようとすると、それが受け入れられます。しかし、後で問題が発生します。これは起こらないはずです。

論理的な解決策を探しています。特に何もない。これを解決するためのアイデア。

11
Addzy K

データベースにユーザー名「user1」が含まれていないとしましょう。 2人のユーザーが「user1」で同時に登録しようとすると、それが受け入れられます。

なぜそれを受け入れるのですか?一意の制約を適用する、ユーザー名を主キーとして使用する、またはトランザクション内でアプリケーションコードのチェックインを実行するのは簡単です。

これを防ぐには、データベーストランザクションを使用してデータベースを使用できる必要があります。そうしないと、アプリケーションはデータベースデータの不変条件を維持できません。

スケーリングに関しては、データベースはすでに必要なテクノロジーを発明しています。たとえば、必要な一貫性の種類に応じたさまざまなロックモード、複数のデータベースサーバー用の分散データベースなどです。

15
DeadMG

これには標準的な解決策があります。登録を行う複数のワーカーを作成します。各リクエストにはユーザー名に適用されるハッシュがあり、ハッシュはどのワーカーがリクエストを処理するかを決定します。この方法では、同じユーザー名に対する2つのリクエストを同時に処理することはできません。

この種のリクエストでは、データストアとしてallデータベースではなく、リスクなどの分散キーバリューストアを検討してください。

7
Michael Shaw

それは問題ですか?

ログインにユーザー名(ユーザーの電子メールではない)が使用されている場合、2人のユーザーが一意でないユーザー名で登録を完了することは許可されません。

ユーザー名が認証に使用されていない場合は、バックグラウンドプロセスを使用して、(たとえば、タイムスタンプに基づいて)ダブルを識別してフラグを付け、ユーザーに次のログオン時にユーザー名を変更させることができます。

はい問題です

ご質問のとおり、ユーザー名は一意のIDであると想定しています。次のアプローチを使用できます。

  1. Before:登録プロセスでは、新しいユーザーが自分の名前の可用性を確認する必要がある手順を予測します。その際、利用可能なアカウント名を一時的なステータスと登録の完了を許可するセッションIDで予約してください。
  2. 同時:gnasher729 応答のより一般的で柔軟なバリアントは、単純なハッシュ関数(シンボルテーブルの管理に使用)、一意の登録サーバーi(i = h(username) modulo number_of_servers))にIDを割り当て、制限された/セグメント化されたスコープの一意性を処理します
  3. After:登録の最後、ユーザーがクリックしたとき register フィールドを一意として定義できる場合は、トランザクションデータベースにリクエストを送信します。エラーが発生したら、不幸なユーザーに「おっと、問題がありました」というメッセージを送信し、別のIDを選択するように依頼します。
  4. Asynchronous:ユーザーを登録します。変更されていない単一のレコードであることを確認するために、直後にユーザーレコードを再度読み取ります。それが問題である場合は、変更するようにユーザーに依頼する(それほど非同期ではない)か、問題が発生したことをメールで送信する(非同期ですが、ユーザーの観点から迷惑です)か、登録を許可してメールを要求します(明確にするため)。ログイン手順の一部としてユーザー名を変更するように強制します。
2
Christophe

ユーザーの一意の識別子と考えるものを再考します。各ユーザーは既に一意のメールアドレスを持っているので、その問題はすでに解決されています。もちろん、これは、「マイクナキス」のように、複数のユーザーが同じ名前を登録できることを意味します。それで問題はありますか?本気ですか?フェイスブックなどでは問題ありません。 「マイク・ナキス」と呼ばれる複数のFacebookユーザーが存在します。 Facebookのログインページを見てください。「メールまたは電話」と「パスワード」の入力を求められます。

1
Mike Nakis

何百万ものユーザーが同時に登録する場合、26 x 26の登録サーバーを使用します。1つはaaで始まるユーザー用、もう1つはabで始まるユーザー用などです。その結果、各サーバーに同時に登録するユーザーは数千人に過ぎません。それでも対応できない場合は、26 x 26 x 26サーバーを使用してください。

0
gnasher729