2016-07-13 3 views
1

저는 MySQL에 익숙하지 않습니다. 많은 포스트 토크 트랜잭션과 테이블 잠금을 읽었습니다. 여기에서 그리고 인터넷을 통해 발견되었으므로, 제 질문은 중복해서는 안됩니다.사용자 등록을위한 MySQL 트랜잭션 VS 테이블 잠금

주로 사용자 등록 및 세션을 위해 쿼리를 최적화하려고합니다. 웹 응용 프로그램은 PHP/MySQL (i)로 작성되었으며 InnoDB 엔진을 사용하고 있습니다.

사용자 세션을 저장하는 데 $ _SESSIONS을 사용하지 않지만 쿠키로 유지되는 사용자 세션에 대한 정보를 저장하는 DB 테이블을 사용합니다. 이 방법을 사용하려면 각 사용자 페이지 요청에 대해 DB의 사용자 세션을 확인해야합니다. 또한 세션 선택 쿼리의 '사용자'테이블에 가입하여 매번 새로운 사용자 정보를 가져옵니다. 사용자보다가 같은 시간에 같은 이름/이메일을 등록하려고 할 때 코드 품질 및 보안이 문제를 방지하기 위해, 성능 : 사용자 등록 쿼리에

내가 어떤 방법이 더 좋다 모르겠습니다.

사용자 테이블 :

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

사용자 이름 또는 이메일이 이미 난 이미 촬영 된 한 알 필요가 촬영되기 때문에 쿼리가 실패합니다.

방법 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; 
} 

방법 A를 사용하여 내 관심사입니다 : 기록 된 다른 어떻게되는지 사용자가 자신의 세션을 탐색하려고 할 때 (많은 경우 가정) '세션 검사'가 사용자 테이블에 참여 함을 기억하십시오. whe n 새로운 사용자가 등록 중이며 그의 쿼리가 사용자 테이블을 잠그고 있습니까? 지지? 시간 초과? 또는 성능을 손상시키지 않을 정도로 쿼리 (선택 및 삽입)가 충분합니까?

방법 B은 교착 상태를 생성 할 가능성이 높습니까?

어떻게해야합니까? 이 방법 중 하나를 선택 하시겠습니까? 믹스 해? 모든 것을 삭제하고 다시 시작 하시겠습니까?

감사합니다. 고맙습니다.

+0

및 이메일. 그렇다면 중복을 전혀 가질 수 없으며 데이터베이스가이를 처리합니다. 트랜잭션은 중복 값을 차단하지 않고 잠금이 작동하지만 테이블이 잠겨있는 동안 성능에 좋지 않은 문제가 발생할 수 있습니다. 고유 인덱스는 중복 행을 방지하고 예외로 포착 될 수 있습니다. –

+0

답변 해 주셔서 감사합니다. 게시물 초기에 언급 된대로 사용자 이름 및 이메일 열에 고유 색인을 설정하도록 이미 제공했습니다. 내 의심하지만 만약 내가 단지 삽입 및 사용자가 이미 사용자 이름과 이메일을 사용하여 내가 이미 그 첫 번째 중복 키가 발생했기 때문에 mysql 오류가 발생했기 때문에 둘 다 찍은 그에게 말할 수없는 테이블에 설정, 그래서이 경우에는 내가 할 수있다 이메일이 이미 사용되었는지도 모릅니다. 사용자가 다른 삽입물을 사용해 이메일을 가져 왔음을 알게합니다. "문제"에 직면 할 수있는 방법을 알고 있습니까? 고마워요! – cicciopast

+0

쿼리를 수행하여 데이터베이스에 이미 존재하는지 확인하십시오. 그러면 사용 중이라고 말할 수 있습니다. 고유 인덱스는 중복이 없는지 확인하기위한 것입니다. 아무것도. 당신은 더 많은 사용자에게 친숙하게하고 오류를 잡기 위해 데이터베이스 인덱스에 의존하지 않도록 미리 확인해야합니다. 그들은 안전망입니다. –

답변