upsert에서 onConflict가 꼭 필요할까?
upsert에서 onConflict가 꼭 필요할까?
데이터베이스 작업을 할 때 자주 마주치는 패턴 중 하나가 "upsert"입니다. 이는 "update" 또는 "insert"의 합성어로, 레코드가 이미 존재하면 업데이트하고, 존재하지 않으면 삽입하는 작업을 말합니다. 이러한 작업에서 onConflict
구문의 필요성에 대해 살펴보겠습니다.
upsert와 onConflict의 관계
많은 현대 데이터베이스 시스템(PostgreSQL, SQLite 등)에서 upsert 작업은 INSERT ... ON CONFLICT
구문을 통해 이루어집니다. 이 구문에서 onConflict
는 중복 키가 발생했을 때 어떤 동작을 수행할지 지정합니다.
INSERT INTO users (id, name, email)
VALUES (1, '김철수', 'kim@example.com')
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
email = EXCLUDED.email;
onConflict는 항상 필요한가?
결론부터 말하자면, upsert 작업에서 onConflict
구문은 대부분의 경우 필요합니다. 하지만 몇 가지 상황에서는 다른 대안을 고려할 수 있습니다:
데이터베이스 시스템에 따른 차이: MySQL의 경우
INSERT ... ON DUPLICATE KEY UPDATE
구문을 사용합니다.ORM 추상화: Sequelize, Prisma, TypeORM 등의 ORM은 내부적으로 적절한 upsert 구문을 생성해주므로, 직접
onConflict
를 지정하지 않아도 됩니다.애플리케이션 로직으로 대체: 먼저 SELECT로 확인 후 존재 여부에 따라 INSERT 또는 UPDATE를 수행할 수 있습니다. 그러나 이 방식은 동시성 문제가 발생할 수 있습니다.
onConflict를 사용하는 이유
- 원자성 보장: 단일 트랜잭션으로 처리되어 동시성 문제를 방지합니다.
- 코드 간결성: SELECT 후 조건부 INSERT/UPDATE보다 더 간결한 코드를 작성할 수 있습니다.
- 성능 향상: 여러 쿼리 대신 하나의 쿼리만 실행하므로 일반적으로 성능이 더 좋습니다.
결론
upsert 작업에서 onConflict
또는 이와 유사한 구문은 대부분의 상황에서 권장됩니다. 특히 동시성이 중요한 환경에서는 더욱 그렇습니다. 다만 사용하는 데이터베이스 시스템이나 ORM에 따라 구체적인 구문은 달라질 수 있으므로, 해당 기술 스택의 문서를 참고하는 것이 좋습니다.