MySQL UPSERT 가이드: INSERT ON DUPLICATE KEY UPDATE 사용 방법 및 예시

1. UPSERT란 무엇인가?

개요

“UPSERT”는 INSERTUPDATE를 결합한 데이터베이스 작업을 가리킵니다. 즉, 데이터가 이미 존재하지 않으면 삽입하고, 존재하면 업데이트합니다. 이 기능은 데이터 일관성을 유지하면서 효율적인 작업을 가능하게 합니다.

MySQL에서는 INSERT ... ON DUPLICATE KEY UPDATE 구문이 이 기능을 제공합니다. 이를 통해 중복 키 오류를 피하고 중복 데이터 상황에서 기존 레코드를 업데이트할 수 있습니다.

사용 사례

  • 고객 관리 시스템 : 존재하지 않으면 새로운 고객 데이터를 삽입하거나, 변경 시 기존 고객 정보를 업데이트합니다.
  • 재고 관리 : 기존 제품의 재고 수를 업데이트하면서 새로운 제품을 추가합니다.

MySQL에서의 UPSERT 이점

  • 중복 키 오류 피함
  • SQL 쿼리 간소화
  • 데이터 무결성 유지

2. MySQL에서 UPSERT의 기본 사용법

MySQL에서 UPSERT 작업은 INSERT ... ON DUPLICATE KEY UPDATE 구문을 사용하여 구현됩니다. 이를 통해 중복 키가 발견되면 새로운 레코드를 삽입하는 대신 기존 레코드를 업데이트합니다.

기본 구문

INSERT INTO table_name (column1, column2)
VALUES (value1, value2)
ON DUPLICATE KEY UPDATE
column1 = value1, column2 = value2;

설명:

  1. INSERT INTO는 테이블에 데이터를 삽입하려고 시도합니다.
  2. 데이터가 이미 존재하면 ON DUPLICATE KEY UPDATE 절이 실행되어 기존 레코드를 업데이트합니다.

예시:

INSERT INTO users (user_id, name)
VALUES (1, 'Taro Tanaka')
ON DUPLICATE KEY UPDATE
name = 'Taro Tanaka';

이 예시에서 user_id = 1인 사용자가 이미 존재하면, 그들의 name이 ‘Taro Tanaka’로 업데이트됩니다. 그렇지 않으면 새로운 레코드가 삽입됩니다.

3. UPSERT의 상세 SQL 구문 및 예시

여러 열 업데이트

UPSERT를 사용할 때 특정 열만 업데이트할 수 있습니다. 이 경우 ON DUPLICATE KEY UPDATE 절에 대상 열만 지정합니다.

INSERT INTO products (product_id, name, price)
VALUES (100, 'Laptop', 50000)
ON DUPLICATE KEY UPDATE
price = VALUES(price);

여기서 product_id = 100인 제품이 이미 존재하면 price 열만 업데이트되며, name과 같은 다른 열은 변경되지 않습니다.

4. 다른 데이터베이스와의 차이점

다른 데이터베이스도 UPSERT와 유사한 기능을 제공합니다. 예를 들어, PostgreSQL과 SQLite는 INSERT ... ON CONFLICT 또는 MERGE를 동등한 기능으로 사용합니다.

PostgreSQL 예시

INSERT INTO users (user_id, name)
VALUES (1, 'Taro Tanaka')
ON CONFLICT (user_id) DO UPDATE SET
name = 'Taro Tanaka';

PostgreSQL과 SQLite에서는 중복 키 오류 발생 시 동작을 제어하기 위해 ON CONFLICT 절을 사용합니다. 반대로 MySQL은 ON DUPLICATE KEY UPDATE를 사용합니다.

MySQL의 독특함

  • MySQL은 INSERT ... ON DUPLICATE KEY UPDATE를 사용하며, 다른 데이터베이스와 다릅니다. 데이터베이스 마이그레이션 시 특별한 주의가 필요합니다.

5. 고급 UPSERT 사용법

벌크 UPSERT (한 번에 여러 레코드)

UPSERT는 한 번에 여러 레코드에 적용할 수 있으며, 데이터베이스 작업의 효율성을 크게 향상시킵니다.

INSERT INTO products (product_id, name, price)
VALUES
(100, 'Laptop', 50000),
(101, 'Smartphone', 30000)
ON DUPLICATE KEY UPDATE
price = VALUES(price);

여기서 여러 제품이 한 번에 삽입되며, 중복 키가 존재하면 price만 업데이트됩니다.

저장 프로시저를 사용한 UPSERT

저장 프로시저를 사용하여 UPSERT 작업을 간소화할 수도 있습니다. 이는 코드를 재사용 가능하게 하고, 더 읽기 쉽고 유지보수하기 쉽게 만듭니다.

6. UPSERT의 함정 및 고려사항

트랜잭션과 데드락

대규모 데이터셋에서 UPSERT를 사용할 때 데드락이 발생할 수 있습니다. MySQL의 트랜잭션 격리 수준이 REPEATABLE READ로 설정되어 있으면 갭 락이 더 발생할 가능성이 높습니다.

갭 락 피하기

  • 트랜잭션 격리 수준을 READ COMMITTED 로 변경하면 교착 상태 위험을 줄일 수 있습니다.
  • 필요할 경우 UPSERT 작업을 더 작은 쿼리로 나누는 것을 고려하십시오.

7. 결론

MySQL의 UPSERT 기능은 중복 키 오류를 방지하면서 데이터를 효율적으로 삽입하고 업데이트할 수 있는 강력한 도구입니다. 그러나 트랜잭션 설정과 잠재적인 교착 상태를 신중히 고려하는 것이 필수적입니다. 올바르게 사용하면 UPSERT는 데이터베이스 작업을 더 간단하고 효과적으로 만들 수 있습니다.