2016-07-13 10 views
1

私はMySQLには新しく、多くのポストトークトランザクションとテーブルロックを読んでいます。私はこことネットで見つけました。私の質問は重複してはいけないと思います。ユーザ登録のMySQLトランザクションVSテーブルロック

私は主にユーザー登録とセッション用にクエリを最適化しようとしています。 WebアプリケーションはPHP/MySQL(i)で書かれており、InnoDBエンジンを使用しています。

私は$ _SESSIONSを使ってユーザーセッションを保存していませんが、私はDB上のテーブルを使用して、クッキーが有効になっているユーザーセッションに関する情報を保存しています。この方法では、各ユーザーページリクエストごとにDB上のユーザーセッションを確認する必要があります。これを行うと、セッションの選択クエリの 'users'テーブルに参加して毎回新しいユーザー情報を取得することもできます。ユーザー以上が同時に同じユーザー名/メールを登録しようとすると、コードの品質とセキュリティは、問題を回避するために、パフォーマンス:ユーザー登録クエリに

私は何の方法がために優れていることを確認していません。

ユーザーテーブル:

user_id (primary, AI) 
username (unique) 
email (unique) 
password 
field 1 
field 2 
... 

ユーザ名または電子メールはすでに私が既に取られている1知っている必要が取られているので、クエリが失敗した場合。

METHOD A:LOCKユーザーTABLE

LOCK TABLES users WRITE; 
// users provided username and email are already taken? 
SELECT COUNT(username) username, (SELECT COUNT(email) FROM users WHERE email = '[email protected]') email FROM users WHERE username = 'batman' 

$res = fetch_array; 
if($res['username'] == 0 && $res['email'] == 0){ 
    INSERT INTO users (username,email,password) VALUES ('batman','[email protected]','imtheonlytruehero') 

    if(affected_rows == 1) 
     $username = null; 
     $email= null; 
     $registration = true; 
    } 
    else { 
     $username = null; 
     $email= null; 
     $registration = false; 
    } 
} 
else { 
    $username = ($res['username'] > 0) ? false : true; 
    $email = ($res['email'] > 0) ? false : true; 
    $registration = false; 
}  
UNLOCK TABLES; 

方法B:INSERT + UPDATEとTRANSACTION

START TRANSACTION; 
INSERT INTO users (username,email,password) VALUES ('batman','0','imtheonlytruehero'); 

if(affected_rows > 0) { 
    $username = true; 
    UPDATE users SET email='[email protected]' WHERE username='batman'; 
    if(affected_rows > 0) { 
     $email = true; 
     $registration = true; 
     COMMIT; 
    } 
    else { 
     $email = false; 
     $registration = true; 
     ROLLBACK; 
    } 
} 
else { 
    $username = false; 
    $email = null; 
    $registration = false; 
    ROLLBACK; 
} 

方法を使用して私の関心は次のとおりです。他のログに記録されたがどうなりますかユーザーがセッションを確認しようとしたときに(セッションチェックがユーザーテーブルに参加することを覚えておいてください)whe n新しいユーザーが登録されていて、そのユーザーのクエリがユーザーテーブルをロックしていますか?スロー?タイムアウト?または、パフォーマンスを損なわない程度に照会(選択と挿入)するだけですか?

メソッドBはデッドロックを生成する可能性が高いですか?

私は何ができますか?この方法の1つを選んでください。それらを混ぜる?すべてを捨てて、やり直してください。

何か助けていただきありがとうございます。ありがとうございました。

+0

あなたが本当にやるべきことは、単にユーザ名に一意のインデックスを置くとされます電子メール。それで、重複を全く取ることはできず、データベースがそれを処理します。トランザクションは重複した値をブロックすることはなく、ロックはおそらく動作しますが、パフォーマンスが悪いテーブルがロックされている間は何もできない問題が発生する可能性があります。ユニークなインデックスは、重複する行を防止し、例外として捕らえることができます。 –

+0

あなたの答えをありがとう。投稿の冒頭に記載されているように、ユーザー名と電子メールの列に一意のインデックスを設定するように私はすでに指定しました。私の疑問は、私はちょうど挿入を行うと、ユーザーが両方のユーザー名と電子メールを既に使用してテーブルに設定されている場合私は、mysqlエラーが最初の重複したキーが発生したので、電子メールがすでに使用されているかどうかを知っていないため、ユーザーは電子メールを受け取ったことを知るために別の挿入を試行します。 この「問題」に直面する方法をご存知ですか?どうもありがとうございました! – cicciopast

+0

クエリーを実行して、データベースにすでに存在するかどうかを確認します。あなたはそれらが使用中であることを伝えることができます。ユニークなインデックスは重複がないことを確認するためのものです。他には何もない。エラーをキャッチするためにデータベースのインデックスに頼らず、よりユーザーフレンドリーにするために、事前にチェックする必要があります。彼らは安全網です。 –

答えて

関連する問題