VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
CHECK 제약 조건을 적용합니다. 이전 버전에서는 구문은 받아들였지만 조용히 무시했습니다 — PostgreSQL에서 마이그레이션하는 많은 개발자를 놀라게 한 동작입니다.
CHECK 제약 조건 정의
CHECK 제약 조건은 컬럼과 함께 인라인으로 추가하거나 테이블 수준 제약 조건으로 추가합니다:
적용
MySQL은INSERT와 UPDATE에서 CHECK 제약 조건을 적용합니다. 위반 시 ERROR 3819 (HY000): Check constraint 'name' is violated.를 반환합니다:
CHECK 제약 조건은 DELETE에서는 평가되지 않습니다. 또한 제약 조건 자체가 기존 테이블에 추가될 때 다시 평가되지도 않습니다 — 제약 조건을 위반하는 기존 데이터가 있는 테이블에 제약 조건을 추가하면 즉시 실패합니다.
제약 조건 추가와 제거
기존 테이블에 제약 조건을 추가합니다:적용 비활성화
특정 제약 조건을 삭제하지 않고 비활성화합니다:NOT ENFORCED는 검증을 일시적으로 우회해야 하는 데이터 마이그레이션 중에 유용합니다. 마이그레이션이 완료되면 적용을 다시 활성화하세요.
CHECK 대 트리거 대 애플리케이션 검증
단순하고 자체 완결적인 규칙에는
CHECK를 사용하세요: 유효 범위, 허용 값, 음이 아닌 숫자, 날짜 순서. 규칙이 다른 테이블의 쿼리를 필요로 할 때는 트리거를 사용하세요. 외부 상태와 관련된 규칙(속도 제한, 가용성 검사)에는 애플리케이션 검증을 사용하세요.
자주 묻는 질문
CHECK 제약 조건은 모든 스토리지 엔진에서 동작하나요?
예. 일부 MySQL 기능과 달리CHECK 제약 조건은 InnoDB, MyISAM, 기타 스토리지 엔진에서 동작합니다. 다만 MyISAM 테이블은 구문적으로 유효한 제약 조건을 정의할 수 있지만 이 스토리지 엔진에는 롤백이 없으므로, MyISAM에서 제약 조건 실패는 부분적인 데이터를 남길 수 있습니다. InnoDB는 완전한 롤백으로 위반을 깔끔하게 처리합니다.
CHECK 제약 조건이 다른 테이블을 참조할 수 있나요?
아니요.CHECK 표현식은 현재 테이블의 현재 행으로 제한됩니다. 서브쿼리, 저장 함수, 다른 테이블 참조는 CHECK 표현식에서 허용되지 않습니다. 테이블 간 검증에는 트리거를 사용하세요.
CHECK 제약 조건은 항상 MySQL에 있었나요?
이전 MySQL 버전에서도 구문은 받아들였지만 제약 조건은 조용히 무시되었습니다. 이전 스키마에서 마이그레이션하는 경우, 기존CHECK 절이 유효하고 적용하려는 규칙을 담고 있는지 확인하세요.
문제 해결
참고
- MySQL의 정규화 — CHECK 제약 조건이 보완하는 스키마 설계
- MySQL 트리거 — 복잡한 검증을 위한 CHECK 제약 조건의 대안
- MySQL의 NULL — CHECK 제약 조건과 NULL은 분명하지 않은 방식으로 상호 작용합니다