테이블의 해당 열에 사용자가 원치 않은 데이터가 입력, 수정, 삭제되는 것을 방지하기 위한 조건
제약조건은 추가/삭제는 가능하나 수정 불가
제약조건 활성화또는 비활성화 가능
1. 제약조건 종류
제약조건
의미
NULL 허용
중복 허용
테이블당 개수
복합키
NOT NULL
NULL 값 입력 불가
❌
⭕
제한 없음
❌
UNIQUE
중복 값 불가
⭕
❌
제한 없음
⭕
PRIMARY KEY
NOT NULL과 UNIQUE 합친 것
❌
❌
1개
⭕
FOREIGN KEY
다른 테이블의 PK 또는 UNIQUE 컬럼 참조
⭕
⭕
제한 없음
⭕
CHECK
특정 조건을 만족하는 값만 허용
⭕
⭕
제한 없음
❌
1) NOT NULL
NULL 값 입력 불가
열 레벨만 가능(단, MODIFY절 사용해 NOT NULL 추가 가능)
ename VARCHAR2(20) NOT NULL
-- 기존 컬럼에 NOT NULL 추가
ALTER TABLE emp MODIFY ename NOT NULL;
⚠️MODIFY로 NOT NULL을 추가할 때 기존 데이터 중 NULL이 하나라도 있으면 오류 발생. - 반드시 NULL 데이터를 먼저 정리하고 제약조건을 걸어야 함.
2) UNIQUE
중복 값 불가
NULL은 허용 (NULL은 값이 없어 비교 자체가 불가능하여 여러 개 가능)
-- 열 레벨
email VARCHAR2(100) UNIQUE
-- 테이블 레벨
CONSTRAINT emp_uk UNIQUE (email)
3) PRIMARY KEY
NOT NULL과 UNIQUE 합친 것
테이블당 1개만 가능, 복합키 가능
-- 열 레벨
empno NUMBER(4) PRIMARY KEY
-- 테이블 레벨 (복합키)
CONSTRAINT emp_pk PRIMARY KEY (empno, deptno)
4) FOREIGN KEY
다른 테이블의 PK 또는 UNIQUE 컬럼 참조
참조 무결성 보장
-- 열 레벨
deptno NUMBER REFERENCES dept(deptno)
-- 테이블 레벨
CONSTRAINT emp_fk FOREIGN KEY (deptno) REFERENCES dept(deptno)
⚠️ 부모 테이블의 행을 삭제할 때 자식 테이블에 참조 중인 행이 있으면 오류 발생. - ON DELETE CASCADE나 ON DELETE SET NULL 옵션으로 처리 가능
CONSTRAINT emp_fk FOREIGN KEY (deptno) REFERENCES dept(deptno)
ON DELETE CASCADE -- 부모 삭제 시 자식도 같이 삭제
ON DELETE SET NULL -- 부모 삭제 시 자식 컬럼을 NULL로
5) CHECK
특정 조건을 만족하는 값만 허용
-- 열 레벨
salary NUMBER CHECK (salary > 0)
-- 테이블 레벨
CONSTRAINT emp_ck CHECK (salary BETWEEN 1000 AND 99999)
⚠️ CHECK 조건에서 NULL은 통과됨. NULL을 막으려면 NOT NULL을 따로 걸어야 함
CHECK 조건에 사용할 수 없는 것
구분
예시
이유
Pseudo 컬럼
CURRVAL, NEXTVAL, LEVEL, ROWNUM
행마다 고정된 값이 아님
날짜/환경 함수
SYSDATE, UID, USER, USERENV
실행 시점마다 값이 바뀜
다른 행 참조
서브쿼리
CHECK는 현재 행만 검사 가능
6) DEFAULT (엄밀히는 제약조건 아니지만 같이 씀)
값을 입력하지 않았을 때 자동으로 들어갈 기본값
hire_date DATE DEFAULT SYSDATE
2. 제약조건 정의
구분
열 레벨
테이블 레벨
위치
컬럼 옆
컬럼 선언 끝난 후
제약조건 이름 지정
가능하지만 생략 많이 함
⭕ CONSTRAINT로 명시
복합키
❌ 불가
⭕ 가능
NOT NULL
⭕ 열 레벨만 가능
❌ 불가
1) 열 레벨 (Column Level)에서 정의
컬럼 정의할 때 바로 옆에 붙이는 방식
-- 이름 지정 안하는 경우 : 자동으로 SYS_C007382 같은 이름 붙여버림
CREATE TABLE emp (
empno NUMBER(4) PRIMARY KEY, -- 열 레벨
ename VARCHAR2(20) NOT NULL, -- 열 레벨
salary NUMBER CHECK (salary > 0), -- 열 레벨
deptno NUMBER(2) REFERENCES dept(deptno) -- 열 레벨
);
-- 이름 지정하는 경우 : CONSTRAINT 제약조건명
CREATE TABLE emp (
empno NUMBER(4) CONSTRAINT emp_empno_pk PRIMARY KEY,
ename VARCHAR2(20) CONSTRAINT emp_ename_nn NOT NULL,
salary NUMBER CONSTRAINT emp_salary_ck CHECK (salary > 0)
);
-- 제약조건 목록 조회
SELECT constraint_name, constraint_type, status
FROM user_constraints
WHERE table_name = 'EMP';
-- 제약조건이 걸린 컬럼까지 조회
SELECT c.constraint_name, c.constraint_type, cc.column_name
FROM user_constraints c
JOIN user_cons_columns cc ON c.constraint_name = cc.constraint_name
WHERE c.table_name = 'EMP';
constraint_type 값
의미
P
PRIMARY KEY
U
UNIQUE
R
FOREIGN KEY (Referential)
C
CHECK / NOT NULL
⚠️ NOT NULL과 CHECK 둘 다 C로 표시됨. 구분하려면 search_condition 컬럼 확인
4. 제약조건 추가/삭제
제약조건은 추가/삭제는 가능하나 수정은 불가
수정이 필요하면 삭제 후 다시 추가해야 함
-- 추가
ALTER TABLE emp ADD CONSTRAINT emp_pk PRIMARY KEY (empno);
-- 삭제
ALTER TABLE emp DROP CONSTRAINT emp_pk;
-- PK는 이름 없이도 삭제 가능
ALTER TABLE emp DROP PRIMARY KEY;
5. 제약조건 활성화/비활성화 : Oracle 전용
제약조건을 삭제하지 않고 일시적으로 끄거나 켤 수 있음
대량 데이터 INSERT 시 성능 향상 목적으로 주로 사용
옵션
기존 데이터 변경
신규 데이터 삽입
기존 데이터 조회
ENABLE VALIDATE
⭕
⭕
⭕
ENABLE NOVALIDATE
⭕
⭕
⭕
DISABLE NOVALIDATE
⭕
⭕
⭕
DISABLE VALIDATE
❌
❌
⭕
1) 비활성화
ALTER TABLE 테이블명
DISABLE [NOVALIDATE | VALIDATE]
CONSTRAINT 제약조건명
구분
설명
DISABLE NOVALIDATE
해당 열의 제약조건만 비활성화(기본값
DISABLE VALIDATE
해당 테이블 읽기만 가능(테이블에 대한 INSERT/UPDATE/DELETE 모두 불가)
-- 기본 비활성화
ALTER TABLE emp DISABLE CONSTRAINT emp_pk;
-- CASCADE : 참조 중인 자식 FK도 함께 비활성화
ALTER TABLE dept DISABLE CONSTRAINT dept_pk CASCADE;
2) 활성화
ALTER TABLE 테이블명
ENABLE [NOVALIDATE | VALIDATE]
CONSTRAINT 제약조건명;
구분
기존 데이터 검증
이후 데이터 검증
ENABLE VALIDATE (기본값)
⭕
⭕
ENABLE NOVALIDATE
❌
⭕
-- 기본 활성화 (기존 데이터도 전부 검증)
ALTER TABLE emp ENABLE CONSTRAINT emp_pk;
-- 기존 데이터는 무시, 이후 데이터만 검증
ALTER TABLE emp ENABLE NOVALIDATE CONSTRAINT emp_pk;
⚠️ ENABLE 시 기존 데이터가 제약조건을 위반하면 오류 발생. - 활성화 전에 데이터 정합성 확인 필요