MySQL 8.0.13 버전 이상일 경우에만 가능하다.
필자는 프로젝트를 진행할때 주로 MySQL을 활용해 서비스를 구축한다. 하지만 늘 걱정됐던 부분 중 하나는 실수로 Primary key 없이 테이블을 생성했을때 발생하는 성능 이슈였다. 실제로 성능이슈가 발생한 적은 없었지만, 최근 프로젝트에서 백엔드 파트를 다른 팀원에게 인수인계하고 있기에 이러한 부분이 더욱 고민이 되었다.
특히 우리가 사용하는 MySQL은 기본적으로 테이블을 생성할 때 Primary Key가 없더라도 테이블이 생성된다. 때문에 이를 미리 방지해 주고자 시스템 변수를 활용한 경험을 공유하고자 한다.
MySQL은 다양한 시스템 변수를 제공하여 사용자가 서버의 동작을 제어하고 설정할 수 있도록 한다. 8.0.13 이상 버전부터 새로운 시스템 변수들이 추가 되었는데 필자가 사용할 시스템 변수는 그중 하나인 sql_require_primary_key
이다. 이러한 시스템 변수들은 세션 또는 전역 수준에서 설정이 가능하다.
세션 변수 vs. 전역 변수
MySQL의 시스템 변수는 크게 세션 변수와 전역 변수로 나뉜다. 세션 변수는 현재 세션에만 적용되는 변수로, 세션이 종료되면 해당 변수의 값은 초기화된다. 반면에 전역 변수는 MySQL 서버 전체에 영향을 미치는 변수로, 서버가 실행 중일 때 어디서든지 적용된다.
여기서 주의해야할 점은 글로벌 변수의 변경된 값은 새로운 세션에만 적용되고 기존 세션에는 영향을 미치지 않는다. 또한, 일부 시스템 변수는 변경을 적용하려면 MySQL 서버를 다시 시작해야 할 수도 있다.
글로벌 변수 변경하기
우선 서버에 적용되어있는 sql_require_primary_key
시스템 변수의 상태를 확인해보자
show global variables like 'sql_require_primary_key';
해당 변수는 앞서 말했듯 기본적으로 OFF로 구성되어있기에 이를 활성화 시켜준다.
set global sql_require_primary_key=ON;
해당 시스템 변수를 활성화 시켰다면 테이블을 생성해 확인한다.
CREATE TABLE test_db.report (
report_id int(10) NOT NULL,
description varchar(1000) DEFAULT NULL
) ENGINE=InnoDB
테이블을 생성하면 아마 테이블이 그냥 생성될 것이다. 분명 활성화시켰는데 무엇이 문제인가... 싶겠지만 글로벌 변수의 변경된 값은 새로운 세션에만 적용된다. 때문에 현재 세션에서는 변경이 일어나지 않아 아직 적용되지 않은 모습을 보여준다.
다행히 해당 변수는 세션 수준에서 변경을 할 수 있기에 MySQL 서버를 다시 시작해야할 필요 없이 세션 변수의 값을 변경하면 된다.
세션 변수 변경하기
세션 변수의 상태를 보면 OFF로 구성된 것을 확인할 수 있다.
SHOW VARIABLES LIKE 'sql_require_primary_key'
이를 활성화 시키고
SET SESSION sql_require_primary_key = on;
다시 이전에 실패한 테이블 생성 쿼리를 실행시킨다.
CREATE TABLE test_db.report (
report_id int(10) NOT NULL,
description varchar(1000) DEFAULT NULL
) ENGINE=InnoDB
성공적으로 제어된 모습을 확인 할 수 있다.
해당 변수는 테이블 생성 외에 기존에 존재하는 Primary키를 삭제하는 동작같은 경우에도 적용된다.