있으면 update 없으면 insert > 십년전오늘

십년전오늘

10년전 추억의 책장을 넘기며

있으면 update 없으면 insert 정보

있으면 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]'");


댓글 전체

엥...무슨 말씀인지 도통...ㅋㅋ

후자가 시간이 더 걸리지 않나요?

어차피 있느냐 없느냐 퀴리 날려야하고 있으면 삭제, 없으면 삽입....

삭제가 빠르냐, 수정이 빠르냐 문제인데요...쩝

제가 문제의 핵심을 잘못 파악했나요? ㅠ
지금 보니까 제가 읽어도 무슨 소린지 도통 모르겠네요;;
저는 있느냐 없느냐 확인할 필요 없이 where문으로 삭제 쿼리를 날리고 그냥 삽입을 하는 것을 말했습니다.
mb_id 가 a 테이블의 키값이라면, update 했을때, update 된 row count 가 0인 경우에 insert 처리를 해주면 됩니다.
mysql_query() 함수에서 update, insert, delete 쿼리의 리턴값은 적용된 행 개수입니다.

그러나 일반적인 경우는 select 해서 값이 존재하는지 체크한 다음에 update/insert 로 분기해야겠죠.
select 쿼리에서 키값을 조건절에 넣은 경우는 속도나 비용이 매우 적습니다. 그런 이유로 select 로 오버헤드가 크게 발생하지 않습니다. 비용이 가장 큰것은 insert, delete 와 인덱스컬럼을 update 해준 경우입니다.
저라면 코드를 좀더 풀어서...
$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번방식을 추천합니다.
update할 때 매치되는 row가 있어도 update되지 않은 경우는
mysql_affected_rows()를 쓰기 애매한 경우ㄱㅏ 있습니다.
http://kr.php.net/manual/en/function.mysql-affected-rows.php
그래서 1번을 쓰나 봅니다.
저는 mysql에서 on duplicate key update를 씁니다.
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랑 테스트를 해본적이 있었는데 이게 더 좋다고 결론을 내린 글을 본적이 있죠.
2는 우선 제외

==============

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번이 좋겠죠.
속도상으로는 당연히 upate 하나로 처리하는게 빠를겁니다.

다만 2번의 경우도 분명 필요할때가 있긴하죠.
저도 전에 작업할때 delete 후 insert 시켜주는 경우가 있었는데, 뭔가를 재등록할때였습니다.
재등록한게 젤 위로 가도록할때요.
인덱스값외에 순서를 정하는 number를 따로두는방법도 있지만...
그때 당시엔 DB열어서 컬럼하나 새로 만들기가 귀찮아서 그냥 delete후 insert를 시킨 기억이..
근데 또 delete로 인해 그 테이블과 join되는 다른 테이블에도 영향을 미치게된다면
그만큼 코딩량이 늘어날테니까...
그냥 number컬럼 만들어서 update로 처리하는게 무조건 나을것 같네요.
그게 정석인것 같습니다.
전체 130,530
십년전오늘 내용 검색

회원로그인

진행중 포인트경매

  1. 참여69 회 시작24.04.19 15:40 종료24.04.26 15:40
(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT