Home 복합키 업데이와 중복 키 오류
Post
Cancel

복합키 업데이와 중복 키 오류

글을 작성하게 된 계기


회사에서 복합키를 가진 테이블을 업데이트 하던 중, 아래와 같은 오류가 발생했습니다. 이 과정에서 알게 된 내용을 정리하기 위해 글을 작성하게 되었습니다.

1
ERROR 1062 (23000): Duplicate entry '1-200' for key '{TABLE}'





1. 문제 상황 재현


예를 들어, 다음과 같은 복합키를 가진 테이블이 있다고 가정해보겠습니다.

1
2
3
4
5
6
7
CREATE TABLE order_items (
    order_id INT NOT NULL COMMENT '주문 ID',
    product_id INT NOT NULL COMMENT '상품 ID',
    quantity INT NOT NULL DEFAULT 1 COMMENT '주문 수량',
    price INT NOT NULL COMMENT '상품 개당 가격',
    PRIMARY KEY (order_id, product_id)
);



필요한 데이터를 INSERT 하고요.

1
2
3
4
INSERT INTO order_items (order_id, product_id, quantity, price)
VALUES (1, 100, 2, 5000),
       (1, 101, 1, 3000),
       (2, 200, 5, 1000);



이후 복합키를 업데이트 하려고 시도하니 다음과 같은 오류가 발생했습니다. 왜 이런 문제가 발생했을까요?

1
2
3
4
mysql> UPDATE order_items
    -> SET product_id = 100
    -> WHERE order_id = 1 AND product_id = 101;
ERROR 1062 (23000): Duplicate entry '1-100' for key 'order_items.PRIMARY'







2. 복합키의 정의


복합키는 고유한 식별키가 없을 때, 하나의 속성으로는 기본키를 만들 수 없을 때 두 컬럼을 복합키로 만들어 유일성을 보장해주는 방식입니다. 즉, 하나의 키가 유일성을 보장하지 못할 때, 두 개 이상의 키를 조합하여 유일성을 보장하는 것입니다.

In database design, a composite key is a candidate key that consists of two or more attributes, (table columns) that together uniquely identify an entity occurrence (table row).



만약 다음과 같이 동일한 복합키가 두 개 생기게 되면 고유한 값을 알 수 없겠죠?

1
2
3
4
5
6
7
+----------+------------+----------+-------+
| order_id | product_id | quantity | price |
+----------+------------+----------+-------+
|        1 |        100 |        2 |  5000 |
|        1 |        100 |        1 |  3000 |  -> 업데이트 후 중복 발생
|        2 |        200 |        5 |  1000 |
+----------+------------+----------+-------+







3. 해결 방법


복합키가 걸린 상태에서 UPDATE를 사용해 키 값을 변경하려 하면, 기존에 존재하는 조합과 중복되어 에러가 발생하게 됩니다. 이 경우에는 직접적으로 UPDATE를 수행하는 것이 아니라, 먼저 기존 데이터를 삭제 한 후 새로운 값을 삽입 하는 방식으로 처리해야 합니다.

1
2
DELETE FROM order_items
WHERE order_id = 1 AND product_id = 101;
1
2
INSERT INTO order_items (order_id, product_id, quantity, price)
VALUES (1, 100, 1, 3000);




이처럼 DELETE → INSERT 순서로 처리하면, 중복 키 오류를 피할 수 있습니다. 다만, 이런 방식은 근본적인 해결책이라기보다는 임시적인 조치에 가깝고, 복합키 자체를 변경할 필요가 없는 데이터 모델링이 더 바람직합니다. 복합키는 두 컬럼의 조합이 변하지 않는 고유한 식별자 이기 때문에 복합키를 직접 수정하거나 삭제 후 다시 삽입해야 하는 상황이 자주 발생한다면, 이는 해당 조합이 식별자로서 적합하지 않다는 신호일 수 있기 때문입니다.

즉, 복합키는 변경을 염두에 두는 키가 아니라, 관계를 명확히 고정하기 위한 키 이기 때문이죠.



자주 변경될 가능성이 있는 값으로 복합키를 구성하기 보다 별도의 surrogate key(AUTO_INCREMENT PK) 를 두고, 복합키는 단순히 UNIQUE로 유지하는 것이 더 유연하고 관리하기 좋습니다.

A surrogate key (or synthetic key, pseudokey, entity identifier, factless key, or technical key in a database is a unique identifier for either an entity in the modeled world or an object in the database.







4. 정리


복합키를 업데이트 하려다 발생한 중복 키 오류로 장애를 낼 뻔 했습니다. 다행히 한 Row만 업데이트 된 후, 에러로 인해 변경이 없었는데요, 복합키를 업데이트할 때, 정말 조심해야 한다는 것을 깨달았습니다. 변경된 Row로 인한 사이드 이펙트를 파악한다고 야근하게 됐네요. 단순히 용어/개념(이)가 무엇이다 보다 해당 키를 왜 사용하고, 어떤 점을 주의해야 할 지 참말로 잘 이해하겠습니다. 🙇


This post is licensed under CC BY 4.0 by the author.

글로벌 락이 없는 레디스의 노드 재분배: REBALANCING

대량 배치 작업 전, 백업의 중요성과 적절한 방법