있으면 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]'");
여기서 기존에 있는지를 확인하기 위해 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문으로 삭제 쿼리를 날리고 그냥 삽입을 하는 것을 말했습니다.
저는 있느냐 없느냐 확인할 필요 없이 where문으로 삭제 쿼리를 날리고 그냥 삽입을 하는 것을 말했습니다.
부하가 젤 많이 걸리는건 UPDATE라고 들은거같은데.
앞선 자료가 필요없다면 삭제하시는것도 괜찮겠죠
앞선 자료가 필요없다면 삭제하시는것도 괜찮겠죠
삭제가 많아지면 overhead가 많이 쌓일텐데, 그게 또 문제되지 않을까 궁금합니다
좋은 방법 같진 않다능~~
mb_id 가 a 테이블의 키값이라면, update 했을때, update 된 row count 가 0인 경우에 insert 처리를 해주면 됩니다.
mysql_query() 함수에서 update, insert, delete 쿼리의 리턴값은 적용된 행 개수입니다.
그러나 일반적인 경우는 select 해서 값이 존재하는지 체크한 다음에 update/insert 로 분기해야겠죠.
select 쿼리에서 키값을 조건절에 넣은 경우는 속도나 비용이 매우 적습니다. 그런 이유로 select 로 오버헤드가 크게 발생하지 않습니다. 비용이 가장 큰것은 insert, delete 와 인덱스컬럼을 update 해준 경우입니다.
mysql_query() 함수에서 update, insert, delete 쿼리의 리턴값은 적용된 행 개수입니다.
그러나 일반적인 경우는 select 해서 값이 존재하는지 체크한 다음에 update/insert 로 분기해야겠죠.
select 쿼리에서 키값을 조건절에 넣은 경우는 속도나 비용이 매우 적습니다. 그런 이유로 select 로 오버헤드가 크게 발생하지 않습니다. 비용이 가장 큰것은 insert, delete 와 인덱스컬럼을 update 해준 경우입니다.
리턴값이 affected_rows인줄은 모르고 있었네요!
코드3번과 같이 하는 방법이 맞는지 확인 부탁드릴게요.^^
코드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번방식을 추천합니다.
$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_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랑 테스트를 해본적이 있었는데 이게 더 좋다고 결론을 내린 글을 본적이 있죠.
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랑 테스트를 해본적이 있었는데 이게 더 좋다고 결론을 내린 글을 본적이 있죠.
replace는 delete+insert로 된다고 하네요.
그리고,
기존 자료가 있으면 업데이트해야지 insert하면 원 의도와는 다르지 않을까요?
그리고,
기존 자료가 있으면 업데이트해야지 insert하면 원 의도와는 다르지 않을까요?
위 쿼리는 기존 자료가 있으면 업데이트하고 없다면 insert합니다. : )
원 의도에 맞게 기능이 있는 경우지요.
원 의도에 맞게 기능이 있는 경우지요.
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번이 좋겠죠.
==============
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로 처리하는게 무조건 나을것 같네요.
그게 정석인것 같습니다.
다만 2번의 경우도 분명 필요할때가 있긴하죠.
저도 전에 작업할때 delete 후 insert 시켜주는 경우가 있었는데, 뭔가를 재등록할때였습니다.
재등록한게 젤 위로 가도록할때요.
인덱스값외에 순서를 정하는 number를 따로두는방법도 있지만...
그때 당시엔 DB열어서 컬럼하나 새로 만들기가 귀찮아서 그냥 delete후 insert를 시킨 기억이..
근데 또 delete로 인해 그 테이블과 join되는 다른 테이블에도 영향을 미치게된다면
그만큼 코딩량이 늘어날테니까...
그냥 number컬럼 만들어서 update로 처리하는게 무조건 나을것 같네요.
그게 정석인것 같습니다.