[Real MySQL] 04. InnoDB, 외래 키 체크 설정

김학성·2023년 5월 12일
0

Real MySQL

목록 보기
2/6
post-thumbnail

이 포스팅은 Real MySQL의 04장을 읽고 개인적으로 학습하고 이해한 내용입니다. 틀린 부분이 있다면 언제든 지적 부탁드립니다.

개요

테이블 설계 시 부모 테이블과 자식 테이블을 외래 키로 관계를 맺을 수 있도록 InnoDB 스토리지 엔진에서 지원하고 있습니다.

외래 키로 관계를 맺게 되면 데이터베이스 운영 시 데이터를 적재하거나 삭제할 때 도움이 될 수 있는데요.

그렇지만 직접 테이블에 데이터를 갱신하거나 삭제하는 경우 종속 관계에 있는 테이블을 명확히 파악하지 못한 경우 작업에 실패할 수 있으며, 종속 관계 테이블 모두 잠금 상태가 되어 의도치 않게 데드락이 발생할 수도 있습니다.

그래서 개발 환경의 데이터베이스에서는 운영의 가이드를 위해 외래 키를 지정하는 편이지만 서비스 중인 데이터베이스에서는 설정하지 않는 편이 많다고 하는데요.

MySQL에서는 이렇게 외래 키를 통한 관계 체크를 수동으로 해제할 수 있는 시스템 변수를 가지고 있습니다.

외래 키 관계 체크 시스템 변수

// 외래 키 관계 체크 유무를 설정하기 위한 시스템 변수
foreign_key_checks

해당 시스템 변수를 통해 외래 키 관계를 일시적으로 해제할 수 있는데요.
아래와 같이 설정하게 되면 외래 키 체크 작업을 멈출거나 다시 재개할 수 있습니다.

// 외래 키 체크 작업 비활성화
SET foreign_key_checks = OFF

// 외래 키 체크 작업 활성화
SET foreign_key_checks = ON

해당 시스템 변수는 현재 세션에만 해당되는 범위에 적용되기 때문에, 작업이 끝난 경우 시스템 변수를 다시 활성화 하거나 세션을 종료해야합니다.

주의할 점

기존 외래 키 관계를 가지고 있는 종속 테이블이 체크 비활성화인 상태에서 데이터를 변경한경우에는 체크를 활성화하거나 세션을 종료하기 전 데이터의 일광성을 맞춰줘야 합니다.

예를 들어 학생과 선생님 테이블이 있고 두 테이블은 외래 키로 종속된 관계를 유지하고 있으며, 부모 테이블인 선생님 테이블에서 데이터가 삭제되는 경우 자식 테이블에서 삭제되는 옵션을 지정해두었습니다. (ON DELETE CASCADE)


여기서 시스템 변수를 비활성화 합니다.

SET foreign_key_checks = OFF

그리고 아래와 같이 선생님 데이터 삭제했습니다.

DELETE FROM `real-mysql`.TEACHERS_TB WHERE id = 1;

기존 외래 키 설정으로 인하면 선생님 id가 1인 학생도 삭제가 되어야하지만 체크를 진행하지 않아 데이터가 남아있는 모습을 볼 수 있습니다.

이렇게 외래 키 체크 과정을 생략할 수 있는 시스템 변수이지만, 위와 같이 진행한경우 꼭 데이터의 일관성을 맞춰주기 위해 학생 데이터도 삭제하고 나서 세션을 종료하거나 시스템 변수를 활성화해야 합니다.

궁금한 점

실제 서비스 중인 데이터베이스 서버를 많이 경험해본 것은 아니지만, 외래 키가 도리어 불편하게 느껴지는 이유가 뭘지 궁금하다고 느껴지는데요. 부모 자식간 종속 관계 테이블의 레코드를 일관성을 유지하기 위한 가이드로 좋다고 생각이 드는데, 성능적으로 여러 테이블이 잠금으로 인하여 데드락의 걸릴 위험이 큰 것이 이유일지 리서치를 더 해볼 예정입니다.

profile
경험과 성장을 기록하는 개발자입니다

0개의 댓글