SQL은 테이블에 데이터를 업데이트하거나 삽입하는 다양한 방법을 제공합니다:
언제 무엇을 사용해야 하는지:
INSERT를 사용합니다.UPDATE를 사용합니다.MERGE 또는 UPSERT를 사용하는 것이 좋습니다 — 이는 복잡성을 줄이고 SQL 요청 수를 줄입니다.예시 (PostgreSQL):
INSERT INTO employees(id, name, salary) VALUES (1, 'Ivan', 100000) ON CONFLICT (id) DO UPDATE SET salary = EXCLUDED.salary;
성능 및 무결성에 미치는 영향:
유니크 필드에서 UPSERT를 시도하고 동일한 트랜잭션에서 동일한 행을 삽입 및 업데이트하면 어떤 일이 발생합니까?
올바른 답변: 트랜잭션이 동일한 행을 두 번 변경하려고 하기 때문에 잠금/충돌 오류가 발생할 수 있습니다. 작업이 완료되지 않거나 DBMS에 따라 deadlock 오류로 종료됩니다.
예시:
BEGIN; INSERT INTO users(id, name) VALUES (1, 'Oleg') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name; UPDATE users SET name = 'Petr' WHERE id = 1; COMMIT;
잘못된 순서와 격리 수준에서 변경 충돌이 발생할 수 있습니다.
이야기 #1
데이터 마이그레이션 로직에서는 SELECT 후 INSERT 또는 UPDATE 조합을 사용했는데, 다른 트랜잭션이 데이터를 먼저 설정하면 "duplicate key" 오류가 발생했습니다. 이로 인해 야간 데이터 내보내기에서 잦은 실패가 발생했으며, UPSERT 로직으로 교체해야 했습니다.
이야기 #2
MySQL 프로젝트에서 ON DUPLICATE KEY UPDATE를 잘못 적용하여 복합 유니크 키를 올바르게 처리하지 않았습니다. 그 결과 일부 데이터가 업데이트되지 않고 중복이 발생했습니다. 문제는 실제 환경에서만 발견되었습니다.
이야기 #3
프로젝트에서 사용자 데이터를 동기화하기 위해 UPSERT 대신 UPDATE를 사용했습니다. 연결 오류가 발생할 경우 새로운 사용자에 대한 업데이트가 건너뛰어 일부 데이터가 손실되었습니다. 분석 후 MERGE/UPSERT를 완전히 구현했습니다.