데이터베이스에서 중복 키를 테스트하는 가장 좋은 방법
문제
이것은 정확성 질문입니다. 내 데이터베이스에 기본 키 열이있는 테이블이 있다고 가정 해 봅시다. 내 DAO 코드에는 insertrow (String Key)라는 함수가있어 키가 테이블에 존재하지 않으면 TRUE를 반환하고 키가 포함 된 새 행을 삽입합니다. 그렇지 않으면, 해당 키에 이미 행이 존재하면 False를 반환합니다. InserTrow가 키가 존재하는지 먼저 확인하는 것이 더 낫거나 더 나쁘습니까? 아니면 단일 선택된 진술을 저장하는 것이 너무 사소한 최적화를 걱정하지 않아도 되는가?
그래서 Sudo 코드에서 :
boolean insertRow(String key){
//potentially a select + insert
if(select count(*) from mytable where key = "somekey" == 0){
insert into mytable values("somekey")
return true;
}
return false;
}
또는
boolean insertRow(String key){
try{
//always just 1 insert
insert into mytable values("somekey")
return true;
} catch (DuplicateKeyException ex){}
return false;
}
해결책
인서트를 시도한 다음 오류를 잡으십시오.
그렇지 않으면, 당신은 할 수 있습니다 아직 두 개의 활성 SPID 사이에 동시 문제가 있어야합니다 (동시에 시스템의 두 웹 사용자라고 말하면).이 경우 어쨌든 오류를 포착해야합니다.
User1: Check for key "newkey"? Not in database.
User2: Check for key "newkey"? Not in database.
User1: Insert key "newkey". Success.
User2: Insert key "newkey". Duplicate Key Error.
명시 적 트랜잭션을 사용하거나 트랜잭션 분리 수준을 설정하여이를 완화 할 수 있지만, 하나의 응용 프로그램 스레드 만 항상 데이터베이스에 대해 실행되지 않는 한 두 번째 기술을 사용하는 것이 더 쉽습니다.
다른 팁
행을 삽입하고 중복 키 오류를 잡으십시오. 내 개인적인 선택
DB를 두 번 타격하는 비용에 대한 예외를 던지는 비용에 따라 이것이 더 나은 성능을 발휘할 수 있다고 생각합니다.
두 시나리오를 테스트 할 때만 확실히 알고 있습니다.
제 생각에, 이것은 예외를 사용하는 훌륭한 사례입니다 (복제본은 예외적이기 때문에) 대부분의 시간이 이미 줄이 아니라면 이미 행을하고 있습니다 (예 : 삽입하고 있지만 업데이트하십시오. "로직.) 존재하는 경우
코드의 목적이 업데이트되는 경우 SELECT를 사용하거나 INSERT ... ON DUPLICATE KEY UPDATE
절 (데이터베이스 엔진에서 지원되는 경우) 또는이 논리를 처리하는 저장된 절차를 만드십시오.
두 번째 옵션은 첫 번째 옵션이 DB의 두 배, 두 번째 옵션은 한 번만 한 번만 누르기 때문에 두 번째.
짧은 대답은 직접 테스트해야한다는 것입니다. 내 직감은 존재를 확인하기 위해 소규모 선택을하는 것이 더 나은 성능을 발휘할 것이지만, 볼륨에서 직접 확인하고 더 나은 성능을 확인해야한다는 것입니다.
일반적으로, 나는 오류가 내가하고있는 일의 예외 엔진에 완전히 확인하는 것을 좋아하지 않습니다. 다시 말해서, 내가하고있는 일이 예외를 던지기보다는 유효한 지 확인할 수 있다면 그것은 일반적으로 내가하는 일입니다.
그러나 나는 an을 사용하는 것이 좋습니다 EXISTS
쿼리보다는 count(*)
if(exists (select 1 from mytable where key = "somekey"))
return false
else
insert the row
(초록의 엔진 중립적 관점에서) MySQL에는 기본 키가 존재하지 않는 경우에만 표에 행을 삽입하는 데 사용할 수있는 키워드가 있다고 확신합니다. MySQL 별 키워드를 사용해도 괜찮다고 가정하면 이것이 최선의 방법 일 수 있습니다.
또 다른 옵션은 논리를 전적으로 SQL 문에 배치하는 것입니다.
MySQL의 또 다른 두 가지 옵션은 사용하는 것입니다
insert ignore into....
그리고
insert into .... on duplicate key update field=value
포함 on duplicate key update field=field
보다: http://dev.mysql.com/doc/refman/5.0/en/insert.html
편집 : 인서트가 효과가 있는지 여부에 대해 영향을 받은_rows를 테스트 할 수 있습니다.
이제 Martin Fowler의 책을 온라인으로 찾았으니, 그것을하는 괜찮은 방법은 키 테이블자세한 내용은 PG 222를 참조하십시오.