580. 도메인 무결성 (Domain Integrity)과 CHECK 제약 조건
⚠️ 이 문서는 데이터베이스 테이블에 쓰레기 데이터(Garbage)가 들어오는 것을 막기 위해 단순히 데이터의 타입(INT, VARCHAR)을 지정하는 것을 넘어, **"나이 컬럼에는 0부터 150까지만 들어와야 한다"거나 "이메일 컬럼에는 반드시 '@' 기호가 포함되어야 한다"처럼 특정 컬럼이 가질 수 있는 값의 합법적 범위(Domain)를 정규 표현식(Regex)과
CHECK구문으로 엄격하게 통제하는 '도메인 무결성'**을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 테이블의 특정 컬럼(칸)에 들어올 수 있는 데이터의 **'조건과 범위'**를 데이터베이스 엔진 단에서 원천 봉쇄하는 물리적 방어막이다.
- 가치: 백엔드 개발자(Java/Python)가 소스코드에
if (age < 0)이라는 유효성 검사(Validation) 로직을 빼먹었더라도, 데이터베이스 자체가 에러를 뿜으며 쓰레기 데이터의 삽입을 막아주어 100% 무결한 데이터 품질을 보장한다.- 기술 체계: 컬럼을 만들 때
NOT NULL(빈칸 방지),DEFAULT(기본값 세팅), 그리고 개발자가 맘대로 수식을 짤 수 있는CHECK제약 조건을 써서 강력한 룰을 DB 스키마에 박아버린다.
Ⅰ. 도메인 무결성의 개념과 3대 기초 방어막
데이터 타입만으로는 쓰레기 데이터를 막을 수 없다.
- 데이터 타입(Type)의 한계:
성별컬럼을VARCHAR(10)으로 만들었다.- 개발자가 실수로 성별 칸에
'남','M','Male', 심지어'외계인'이라고 제멋대로 글자를 쑤셔 넣어도 DB는 문자열이기만 하면 다 받아준다. 나중에 "남자 고객 수 구하기" 통계를 낼 때 데이터가 다 쪼개져서 망한다.
- 도메인 무결성 (Domain Integrity)의 정의:
- "이 컬럼(성별)이 가질 수 있는 허용 가능한 값의 집합(Domain)은 오직
'M'과'F'딱 두 개뿐이다!"라고 DB에 헌법을 세우는 것이다.
- "이 컬럼(성별)이 가질 수 있는 허용 가능한 값의 집합(Domain)은 오직
- 기초 제약 조건:
NOT NULL: "고객 이름은 절대로 빈칸일 수 없다." (필수 입력 강제)DEFAULT: 사용자가 가입 날짜를 안 적고 보내면, DB가 눈치껏DEFAULT SYSDATE룰을 발동해 오늘 날짜를 알아서 채워준다.
📢 섹션 요약 비유: 회원가입 폼을 만들 때, '전화번호' 칸에 [숫자만 입력 가능]하도록 키보드 설정을 막아놓는 것(데이터 타입)만으로는 부족합니다. 손님이 숫자 '000-0000-0000'이라고 가짜 번호를 칠 수 있으니까요. 도메인 무결성은 "반드시 010으로 시작하는 11자리 숫자만 통과시킨다!"라는 깐깐한 정규식(문법 검사기)을 달아놔서, 쓰레기 데이터가 서류철(DB)에 철해지는 꼴을 문지기가 원천 차단하는 기술입니다.
Ⅱ. CHECK 제약 조건: DBA의 커스텀 방어 무기
내가 만든 공식에 맞지 않는 데이터는 모두 뱉어낸다.
- CHECK 구문의 활용:
- DBA는 테이블을 생성(
CREATE TABLE)하거나 수정할 때, 컬럼 옆에CHECK라는 마법의 키워드를 붙여 수식을 적는다. - 예:
나이 INT CHECK (나이 >= 0 AND 나이 <= 150) - 누군가
INSERT INTO 직원 (나이) VALUES (-5)를 날리면, DB 엔진은 가차 없이 **"CHECK 제약 조건 위반 에러"**를 뿜으며 쿼리를 튕겨낸다.
- DBA는 테이블을 생성(
- IN 연산자를 이용한 목록 통제:
- 성별이나 혈액형처럼 몇 가지 값만 고정된 경우(Enum 성격)에 강력하다.
- 예:
혈액형 VARCHAR(2) CHECK (혈액형 IN ('A', 'B', 'O', 'AB'))
- 조건부 로직 통제:
- 두 컬럼을 비교하는 룰도 짤 수 있다.
- 예: "퇴사일은 반드시 입사일보다 커야 한다." $\rightarrow$
CHECK (퇴사일 >= 입사일)
📢 섹션 요약 비유: 술집 기도(DB 문지기)에게 "미성년자 출입 금지"라는 지시를 내립니다. 기도는 신분증을 보고 나이를 계산하겠죠. CHECK 제약 조건은 사장님이 기도에게 적어준 세부 메뉴얼입니다. "나이가 0살보다 작거나 150살보다 많은 놈이 오면 가짜 신분증이니 쫓아내고(범위 체크), 혈액형이 C형이라고 적힌 외계인도 쫓아내라(IN 체크)." 이 메뉴얼 덕분에 식당 안에는 100% 정상적인 손님들만 존재하게 됩니다.
Ⅲ. 정규 표현식 (Regular Expression)과의 결합
이메일 주소의 골뱅이(@)까지 완벽하게 잡아내는 극강의 패턴 검사.
- 단순 CHECK의 한계:
이메일컬럼에 "이메일 형식만 들어와라!"라고 막고 싶은데, 크다/작다(>) 같은 수학 기호로는 이메일 텍스트 모양을 통제할 방법이 없다.
- REGEXP (정규 표현식) 함수의 등판:
- 오라클(
REGEXP_LIKE)이나 MySQL(REGEXP) 같은 최신 DB 엔진은 CHECK 구문 안에서 정규 표현식을 쓸 수 있게 해준다. - 예: 이메일 검사 룰 세팅
CHECK (REGEXP_LIKE (이메일, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$')) - 저 끔찍하게 생긴 외계어(정규식)는 **"앞에 영문/숫자가 오고, 중간에 무조건
@가 1개 있어야 하며, 뒤에.과 영어 도메인이 와야 한다"**는 완벽한 이메일 문법 공식이다.
- 오라클(
- 비즈니스 무결성의 완성:
- 이제 개발자가 바빠서 프론트엔드나 백엔드 서버에 '이메일 형식 검증 로직'을 깜빡하고 안 짰더라도, 해커가 이메일 칸에
DROP TABLE users같은 SQL 인젝션 코드를 쑤셔 넣으려 하면 DB 단의CHECK REGEXP방어막에 부딪혀 "이메일 형식 아님!"이라며 100% 차단된다. 데이터의 완벽한 성역이 구축되는 것이다.
- 이제 개발자가 바빠서 프론트엔드나 백엔드 서버에 '이메일 형식 검증 로직'을 깜빡하고 안 짰더라도, 해커가 이메일 칸에
📢 섹션 요약 비유: 단순한 CHECK 룰이 "입구에서 키 150cm 이상만 통과시켜라"라는 막대기라면, 정규 표현식(REGEXP)을 장착한 CHECK 룰은 "주민등록증의 홀로그램 위치, 글씨 폰트 두께, 잉크의 재질까지 현미경으로 0.1mm 단위로 검사하라"는 국과수 수준의 초정밀 위조지폐 감별기입니다. 이메일, 전화번호, 우편번호처럼 사람마다 쓰는 모양이 달라서 엉망이 되기 쉬운 텍스트 데이터를, 군대처럼 칼 같은 한 가지 양식으로 100% 통일시키는 기적의 필터 필터링 기술입니다.