💡 핵심 인사이트
사용자 정의 무결성은 앞서 배운 기본키(개체 무결성), 외래키(참조 무결성), 타입(도메인 무결성) 같은 데이터베이스의 기본 수학적 룰로는 막아낼 수 없는, '특정 회사나 비즈니스의 독특한 업무 규칙(Business Rule)'을 DB에 강제하기 위해 DBA(사용자)가 직접 만들어 심어놓은 제약조건입니다.


Ⅰ. 사용자 정의 무결성의 필요성

수학적인 DB 규칙은 완벽하지만, 회사의 영업 방침을 DB가 알아서 지켜주지는 않습니다.

  • "우리 은행의 마이너스 통장은 잔고가 -5,000만 원 밑으로 내려가면 안 돼."
  • "신입사원의 월급은 기본급을 초과해서 등록될 수 없어."
  • "프로젝트 시작일은 절대 종료일보다 미래일 수 없어."

이런 업무 상식(비즈니스 로직)에 어긋나는 데이터가 입력(INSERT)되거나 수정(UPDATE)되는 것을 데이터베이스 자체에서 원천 봉쇄하기 위해 DBA가 직접 코딩하여 설정하는 것이 바로 사용자 정의 무결성입니다.


Ⅱ. 구현 방법 1: CHECK 제약조건 (CHECK Constraint)

가장 흔하고 간단하게 비즈니스 룰을 거는 방법입니다. 테이블을 생성하거나 수정할 때 컬럼에 수식(조건)을 달아버립니다.

예시 시나리오

  1. 범위 검증: 나이 컬럼에 200살이 들어오는 것을 막기.
    • CONSTRAINT chk_age CHECK (나이 >= 0 AND 나이 <= 150)
  2. 리스트(목록) 검증: 부서명 컬럼에 이상한 오타가 들어오는 것을 막기.
    • CONSTRAINT chk_dept CHECK (부서명 IN ('영업', '개발', '인사'))
  3. 컬럼 간 비교 (Table-level Check): 종료일시작일보다 앞서는 시간 역행 막기.
    • CONSTRAINT chk_date CHECK (종료일 >= 시작일)

만약 사용자가 종료일을 시작일보다 과거로 입력하려 하면, DB 엔진은 "CHECK 제약조건 위반" 에러를 뱉어내고 쿼리를 무효화(Rollback)시킵니다.


Ⅲ. 구현 방법 2: 데이터베이스 트리거 (Trigger)

CHECK 제약조건은 간단한 수학 비교만 가능합니다. "만약 A 테이블에 VIP 고객이 추가되면, B 테이블의 VIP 회원 수를 1 증가시키고, C 테이블 로그에 기록을 남겨라" 같은 복잡하고 동적인 비즈니스 룰은 CHECK로 막을 수 없습니다.

이때 사용하는 것이 **트리거(Trigger)**입니다.

  • 개념: 총의 방아쇠(Trigger)처럼, 특정 테이블에 INSERT, UPDATE, DELETE 이벤트가 발생하는 순간, **DB 내부에서 알아서 자동으로 연쇄 실행되는 숨겨진 프로시저(PL/SQL 코드)**입니다.
  • 무결성 사수 역할: 사용자가 재고보다 많은 주문을 입력하려 할 때, 삽입 직전(BEFORE INSERT)에 트리거가 몰래 깨어나 재고 테이블을 쓱 확인하고, 수량이 부족하면 트랜잭션 자체를 엎어버리는(Raise Error) 등 고도의 문지기 역할을 수행합니다.

📢 섹션 요약 비유: 기본키나 외래키 같은 무결성이 "마스크를 썼는가, 입장권이 있는가"를 검사하는 **'놀이공원 기본 입장 게이트'**라면, 사용자 정의 무결성(CHECK, Trigger)은 청룡열차를 타기 직전 안전 요원이 다가와 "키가 130cm가 넘는지(CHECK), 심장병이 없는지(Trigger 로직)" 우리 놀이공원만의 특수한 규칙을 한 번 더 깐깐하게 검사하여 안전사고(데이터 오염)를 막는 최종 방어선입니다.