티스토리 뷰

MySQL 에서 insert 쿼리 수행시 Key 중복이 있는 경우 해당 row를 업데이트 하기 위해서 insert ~ on duplicate key update ~ 를 사용한다.

문법

INSERT INTO tb_temp (a, b, c) VALUES(1, 2, 3)
ON DUPLICATE KEY UPDATE c = c + 1

tb_temp 테이블에 PK(unique index)가 a 라고 했을 때를 가정하자.
위 SQL은 a=1 인 row 가 이미 존재한다면 c 컬럼을 갱신한다는 의미이다.
예를 들어 위 SQL을 두 번 수행하면? c는 4가 된다.

그럼 Bulk insert 에서의 duplicate key update 쿼리는 어떻게 작성이 될까?

두 개의 insert 구문이 있다고 가정하자.
INSERT INTO tb_temp (a, b, c) VALUES(1, 2, 3)
ON DUPLICATE KEY UPDATE c = 1 + 2
INSERT INTO tb_temp (a, b, c) VALUES(4, 5, 6)
ON DUPLICATE KEY UPDATE c = 4 + 5

이를 bulk insert 쿼리로 변경하면??? 아래와 같이 생각할 수 있다.
INSERT INTO tb_temp (a, b, c) VALUES (1, 2, 3), (4, 5, 6)
ON DUPLICATE KEY UPDATE c = a + b

잘 수행될까?
(1, 3, 2) row 가 있는 상태에서 위 쿼리가 수행되면, c 값은 뭐가 될까?
INSERT INTO tb_temp (a, b, c) VALUES (1, 3, 2)
ON DUPLICATE KEY UPDATE c = a + b
INSERT INTO tb_temp (a, b, c) VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE c = a + b
3(1 + 2)일까? 4(1 + 3)일까?


답은 4가 된다.
그 이유는 a + b에서 a 와 b 는 현재 테이블에서 a = 1 row의 값들은 b = 3, c = 2 이기 때문이다.
즉, 테이블에 이미 저장되어 있는 값을 의미하기 때문이다.

Bulk insert 쿼리에서는 c가 4가 아니라 3이 되길 바랬을 것이다.
어떻게 해결할 수 있을까? VALUES(col_name) 을 활용하면 된다.
INSERT INTO tb_temp (a, b, c) VALUES (1, 3, 2)
ON DUPLICATE KEY UPDATE c = VALUES(a) + VALUES(b)
INSERT INTO tb_temp (a, b, c) VALUES (1, 2, 3)
ON DUPLICATE KEY UPDATE c = VALUES(a) + VALUES(b)



의도한 결과대로 c = 3이 된 것을 확인할 수 있다.

이제 Bulk Insert 쿼리를 다시 정리해보자.
INSERT INTO tb_temp (a, b, c) VALUES (1, 2, 3), (4, 5, 6)
ON DUPLICATE KEY UPDATE c = VALUES(a) + VALUES(b)

결론

MySQL 공식 페이지(https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html) 에서 보면 VALUES에 대해 아래와 같이 표현하고 있다.
In assignment value expressions in the ON DUPLICATE KEY UPDATE clause, you can use the VALUES(col_name) function to refer to column values from theINSERT portion of the INSERT ... ON DUPLICATE KEY UPDATE statement. In other words, VALUES(col_name) in the ON DUPLICATE KEY UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts. The VALUES()function is meaningful only in the ON DUPLICATE KEY UPDATE clause or INSERT statements and returns NULL otherwise
VALUES(col_name)의 값은 col_name에 insert 될 값을 의미하는 것이다.

참고


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함