MySQL INSERT ... ON DUPLICATE KEY UPDATE – 중복 데이터 처리의 장점과 단점
데이터베이스를 사용하다 보면 이미 존재하는 데이터인지 확인한 후 INSERT 또는 UPDATE를 해야 하는 상황을 자주 만나게 됩니다.
이때 매우 유용한 문법이 바로 INSERT ... ON DUPLICATE KEY UPDATE입니다.
즉, 쿼리 한번으로 해결 된다는 의미 인데 아무곳에서나 사용 가능한것은 아니고 키 중복이 발생하는 부분에서만 사용 하는 것입니다.
그렇기 때문에 unique의 특성을 모르시는 분은 사용 하면 안되겠지요.
● 장점
- 쿼리 수 감소: SELECT → INSERT/UPDATE 두 번 쿼리 날릴 필요 없음
- 동시성 문제 감소: SELECT 후 INSERT 방식보다 Race Condition 발생 가능성 낮음
- 코드 가독성 향상
- 성능상 이점: 단순 중복 처리 시 IF EXISTS 패턴보다 효율적인 경우가 많음
-- 테이블 생성
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
-- 초기 데이터 1건 입력 (id=5인 사용자 미리 생성)
INSERT INTO users (id, name, email) VALUES (5, '영희', 'younghee@email.com');
<?php
try {
$pdo = new PDO($dsn, $user, $pass, $options);
// 2. 소문자 a로 시작하는 데이터 배열
$aUserData = [
['id' => 5, 'name' => '철수', 'email' => 'chulsu@email.com'],
['id' => 6, 'name' => '민수', 'email' => 'minsu@email.com'] // 6은 없으므로 INSERT 됨
];
// 3. Prepared Statement 준비
$sql = "INSERT INTO users (id, name, email)
VALUES (:id, :name, :email)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email)";
$stmt = $pdo->prepare($sql);
// 4. 반복문으로 실행
foreach ($aUserData as $row) {
$stmt->execute([
':id' => $row['id'],
':name' => $row['name'],
':email' => $row['email']
]);
echo "ID {$row['id']} 처리 완료 (Insert or Update)<br>";
}
} catch (\PDOException $e) {
echo "에러 발생: " . $e->getMessage();
}
● 단점
- 의도치 않은 UPDATE 발생 가능 - 중복 키가 생기면 무조건 UPDATE
- 영향받은 row 수가 헷갈림
- 애플리케이션 로직에서 오해 가능
- 복잡한 조건 처리에 한계: 비즈니스 로직이 복잡하면 서비스 단에서 처리하는 게 맞음.
