MySQL - 외래 키 제약 조건으로 업데이트가 되지 않는 행 강제 업데이트 하기 (외래 키 제약 조건 비활성화)

반응형

개요

A테이블id컬럼을 참조하는 B테이블이 있다.

여기서 A테이블id컬럼 값을 변경하려고 할 때,

데이터 일관성을 유지해야하기 때문에 참조 무결성의 제약 조건으로 업데이트를 할 수 없다.

하지만 가끔 잘못 넣은 값을 다른 값으로 업데이트해주어야 할 때가 있는데,

FK 때문에 참조 관계로 엮여있어서 계속 오류가 발생하여 값을 업데이트하지 못한다.

발생되는 오류는 다음과 같다.

Error Code: 1451.
Cannot delete or update a parent row:
	a foreign key constraint fails
    (`database`.`FK table`, CONSTRAINT `FK Name` FOREIGN KEY (`id`)
    REFERENCES `table` (`id`))

 

ON UPDATE CASCADE를 사용하는 방법이 있지만...

테이블을 변경했다가 다시 되돌리는 건 사실 너무 귀찮고,

일회성으로 잠깐 빠르게 수정하고 싶다.

 

외래 키 제약 조건 활성화 / 비활성화 하기

특정 컬럼의 값이 외래 키 제약 조건에 걸려 값을 업데이트하지 못할 때

외래 키 제약 조건을 잠깐 비활성화 했다가 값을 업데이트 후,

다시 외래 키 제약 조건을 활성화 하면 된다.

 

  • 외래 키 제약 조건 비활성화 쿼리
SET FOREIGN_KEY_CHECKS = 0;

 

  • 외래 키 제약 조건 활성화 쿼리
SET FOREIGN_KEY_CHECKS = 1;

 

이 기능의 장점으로는 필요한 작업을 신속하게 수행할 수 있다는 것인데,

외래 키 제약 조건을 비활성화하면 데이터 무결성이 손상될 수 있으므로

상황에 따라 반드시 필요한 경우에만 비활성화하고 작업이 완료되면 즉시 다시 활성화하는 것이 좋다.

또한, 다중 사용자 환경에서 이 설정을 변경하면 다른 사용자가 수행하는 작업에도 영향을 미칠 수 있으므로 주의하여야 한다.

 

외래 키 제약 조건이 걸린 행 업데이트 예시

예시를 위한 샘플 테이블

설명을 위해 간소화 하였다.

 

product 테이블

  • product_id, int, PK
  • name, varchar(255)

product_image 테이블

  • image_id, int, PK
  • url, varchar(255)
  • product_id, int, FK ( product(product_id) )

 

예시를 위한 샘플 데이터

product 테이블

  product_id name
1행 999 아이템1

 

product_image 테이블

  image_id url product_id
1행 123 https:~~ 999

 

시나리오

외래 키로 참조하는 product_id의 값이 999이지만, 1로 변경하고 싶다.

하지만 외래 키 제약 조건으로 인해서 업데이트가 불가능한 상황이다.

 

작성 쿼리

-- 외래 키 제약 조건 비활성화
SET FOREIGN_KEY_CHECKS = 0;

-- product 테이블 강제 업데이트
update product
set product_id = 1;

-- product_image 테이블 강제 업데이트
update product_image
set product_id = 1;

-- 외래 키 제약 조건 활성화
SET FOREIGN_KEY_CHECKS = 1;

 

변경 전 / 후 값 비교

  • 변경 전: product_id 999

외래 키 걸려 있는 행을 강제 업데이트 하기 전의 예시 이미지
외래 키 걸려 있는 행을 강제 업데이트 하기 전의 예시 이미지

 

  • 변경 후: product_id 1

외래 키 걸려 있는 행을 강제 업데이트 한 후의 예시 이미지
외래 키 걸려 있는 행을 강제 업데이트 한 후의 예시 이미지

반응형