있으면 update 없으면 insert
웹프로그램을 짜다 보면 제목과 같이 "기존에 자료가 있는 것이면 update, 없던 것이면 insert"를 원하는 경우가 많이 있습니다.
여기서 기존에 있는지를 확인하기 위해 select 쿼리를 한 번 날리게 되는데, 차라리 그러지 말고
"기존에 자료가 있으면 delete, 그 후에 insert" 이런 식으로 바꿔볼까 고민중입니다.
500명 정도 동시에 접속하는 환경이 될 것 같은데, 조금이라도 쿼리에 의한 로딩을 줄여주고 싶어서 사소한 곳까지 신경이 쓰이네요.
- - -
코드 1.
$row = sql_fetch("select mb_id from `a` where mb_id='$member[mb_id]'");
if($row) sql_query("update `a` set a='$a' where mb_id='$member[mb_id]'");
else sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
코드 2.
sql_query("delete from `a` where mb_id='$member[mb_id]'");
sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
코드 3. 명랑폐인님 의견 반영
if(!sql_query("update `a` set a='$a' where mb_id='$member[mb_id]'")) sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
여기서 기존에 있는지를 확인하기 위해 select 쿼리를 한 번 날리게 되는데, 차라리 그러지 말고
"기존에 자료가 있으면 delete, 그 후에 insert" 이런 식으로 바꿔볼까 고민중입니다.
500명 정도 동시에 접속하는 환경이 될 것 같은데, 조금이라도 쿼리에 의한 로딩을 줄여주고 싶어서 사소한 곳까지 신경이 쓰이네요.
- - -
코드 1.
$row = sql_fetch("select mb_id from `a` where mb_id='$member[mb_id]'");
if($row) sql_query("update `a` set a='$a' where mb_id='$member[mb_id]'");
else sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
코드 2.
sql_query("delete from `a` where mb_id='$member[mb_id]'");
sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
코드 3. 명랑폐인님 의견 반영
if(!sql_query("update `a` set a='$a' where mb_id='$member[mb_id]'")) sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
|
댓글을 작성하시려면 로그인이 필요합니다.
로그인
댓글 15개
후자가 시간이 더 걸리지 않나요?
어차피 있느냐 없느냐 퀴리 날려야하고 있으면 삭제, 없으면 삽입....
삭제가 빠르냐, 수정이 빠르냐 문제인데요...쩝
제가 문제의 핵심을 잘못 파악했나요? ㅠ
저는 있느냐 없느냐 확인할 필요 없이 where문으로 삭제 쿼리를 날리고 그냥 삽입을 하는 것을 말했습니다.
앞선 자료가 필요없다면 삭제하시는것도 괜찮겠죠
mysql_query() 함수에서 update, insert, delete 쿼리의 리턴값은 적용된 행 개수입니다.
그러나 일반적인 경우는 select 해서 값이 존재하는지 체크한 다음에 update/insert 로 분기해야겠죠.
select 쿼리에서 키값을 조건절에 넣은 경우는 속도나 비용이 매우 적습니다. 그런 이유로 select 로 오버헤드가 크게 발생하지 않습니다. 비용이 가장 큰것은 insert, delete 와 인덱스컬럼을 update 해준 경우입니다.
코드3번과 같이 하는 방법이 맞는지 확인 부탁드릴게요.^^
$acnt = sql_query("update `a` set a='$a' where mb_id='$member[mb_id]'");
if($acnt == 0) {
sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
}
와 같이 코딩할거 같네요.
그러나 일반적인 상황에서는 1번방식을 추천합니다.
mysql_affected_rows()를 쓰기 애매한 경우ㄱㅏ 있습니다.
http://kr.php.net/manual/en/function.mysql-affected-rows.php
그래서 1번을 쓰나 봅니다.
mb_id라는 컬럼이 primary key이거나 unique한 컬럼일 때.. 아래와 같이 합니다.
sql_query("insert into `a` values('$member[mb_id]','$a') on duplicate key update a = '$a'");
자세한 레퍼런스는 http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html 여기입니다.
어떤 블로그분이 replace랑 테스트를 해본적이 있었는데 이게 더 좋다고 결론을 내린 글을 본적이 있죠.
그리고,
기존 자료가 있으면 업데이트해야지 insert하면 원 의도와는 다르지 않을까요?
원 의도에 맞게 기능이 있는 경우지요.
==============
1번은 다음 처럼 수정한 것을 가지고 논합니다.
sql_query("update `a` set a='$a' where mb_id='$member[mb_id]'");
if( is_updated ) sql_query("insert into `a` set a='$a', mb_id='$member[mb_id]'");
mysql_affected_rows()의 side effect 때문에 pseudo 코드를 썼습니다.
==============
1과 3중에
우선 어느쪽이 확율이 높은지 조사해 봐야 하지 않을까요?
아주 가끔, insert가 된다면 3번이 좋고
대부분이 insert 된다면 1번이 좋겠죠.
다만 2번의 경우도 분명 필요할때가 있긴하죠.
저도 전에 작업할때 delete 후 insert 시켜주는 경우가 있었는데, 뭔가를 재등록할때였습니다.
재등록한게 젤 위로 가도록할때요.
인덱스값외에 순서를 정하는 number를 따로두는방법도 있지만...
그때 당시엔 DB열어서 컬럼하나 새로 만들기가 귀찮아서 그냥 delete후 insert를 시킨 기억이..
근데 또 delete로 인해 그 테이블과 join되는 다른 테이블에도 영향을 미치게된다면
그만큼 코딩량이 늘어날테니까...
그냥 number컬럼 만들어서 update로 처리하는게 무조건 나을것 같네요.
그게 정석인것 같습니다.