3

PHP/MySQL を使用しています。ユーザー名が既に使用されているかどうかを確認する最良の方法は何ですか?

今私がしているのは、選択ステートメントを実行して、ユーザー名が既に使用されているかどうかを確認することだけです。選択が行を返す場合、停止してエラー メッセージを表示します。選択で何も返されない場合は、新しいユーザーを挿入します。

しかし、より効率的な方法はありますか?たとえば、ユーザー名列で UNIQUE を使用してから、insert ステートメントのみを実行できます (既に使用されている場合は、insert からエラーを取得します)。

4

1 に答える 1

5

ユーザーが存在しないことを確認するSELECTと挿入するINSERTの間の短い瞬間に、他のスレッドがユーザー名を挿入するリスクがあります。これは競合状態と呼ばれます。

その可能性は低いと思われるかもしれませんが、「 100 万分の 1 は来週の火曜日」ということわざがあります。

はい、ユーザー名の UNIQUE 制約により、重複したユーザー名の INSERT を防ぐことができます。その制約を宣言します。

一部の記事では、UNIQUE 制約を設定すると、SELECT を実行する必要がなくなると説明しています。INSERTを試して競合する場合は、エラーを報告してください。

しかし、私はサイトがこの手法によって引き起こされた問題から回復するのを手伝いました。彼らのサイトでは、ユーザーが非常に迅速に新しいユーザー名を作成しようとしていたため、INSERT で多くの競合が発生していました。問題は、INSERT がキャンセルされた場合でも、MySQL がテーブルの自動インクリメント主キーをインクリメントすることでした。また、これらの自動インクリメント値は再利用されません。その結果、INSERT が成功するたびに 1000 ~ 1500 の ID 番号が失われていました。INT 主キーが 2 31 -1 に達し、テーブルに別の行を作成できなくなったときに、彼らから電話がありました。

彼らが使用した解決策は、最初に SELECT を試し、重複を報告することでした。それが安全だと思われる場合は、INSERT を試してください。ただし、競合状態が引き続き発生する可能性があるため、UNIQUE 制約との潜在的な競合を処理するコードを記述してください。

于 2012-12-01T07:48:19.713 に答える