[Oracle] 25.무결성 제약조건(1)


무결성 제약조건의 종류



데이터 무결성 제약 조건(Data Integrity Constraint Rule)이란 테이블에 부적절한 자료가 입력되는 것을 방지하기 위해서

테이블을 생성할 때 각 컬럼에 대해서 정의하는 여러 가지 규칙을 말합니다.

제약조건의 종류는 다음과 같습니다.


image



제약조건 확인



테이블에 정의된 제약조건들은 데이터 딕셔너리에 저장됩니다~

제약조건을 확인하기 위해서는 제약조건 딕셔너리에서 조회합니다.


SELECT
    *
FROM
    user_constraints; --제약조건 테이블




image



속성 중 CONSTRAINT_TYPE은 제약조건 타입이며, 다음과 같은 것들이 있습니다.


image



제약조건 테이블 user_constraints에는 컬럼명이 나와있지 않기에 제약조건이 걸린 컬럼명을 조회하려면

user_cons_columns 테이블을 이용합니다.


SELECT
    *
FROM
    user_cons_columns;




image




  • HR 계정의 외래키 제약조건, 참조하는 테이블 명, 외래키, 참조되는 테이블의 기본키 정보 조회




SELECT
    user_constraints.constraint_name "제약조건 명",
    user_constraints.table_name "테이블 명",
    column_name "외래키",
    r_constraint_name "참조되는 기본키"
FROM
    user_constraints,
    user_cons_columns
WHERE
    user_constraints.constraint_name LIKE '%FK'
    AND user_constraints.constraint_name = user_cons_columns.constraint_name;




image



속성레벨에서 제약조건 주기



제약조건은 테이블 생성 시에 주거나 ALTER를 이용해서 추가해줄 수 있습니다.

테이블 생성 시 줄 때 속성레벨에서 제약조건을 줄 수 있고, 테이블 레벨에서도 제약조건을 줄 수 있습니다.

일단, 테이블 생성시 속성레벨에서 제약조건을 주는 방법을 알아보겠습니다.


NOT NULL 제약조건




CREATE TABLE EMP02(
    EMPNO NUMBER(4) NOT NULL,
    ENAME VARCHAR2(10) NOT NULL,
    JOB VARCHAR2(9),
    DEPTNO NUMBER(2)
);



EMP02 테이블의 EMPNO과 ENAME 속성은 NULL이 오면 안 됩니다.

따라서 다음과 같은 INSERT 문은 오류를 발생시킵니다.


INSERT INTO EMP02 VALUES (NULL,'구경민','개발',2);  -- 데이터 삽입불가 NOT NULL 조건 위배




image



UNIQUE 제약 조건




CREATE TABLE EMP03(
    EMPNO NUMBER(4) UNIQUE, --제약조건 명을 지정하지 않아서 시스템이 알아서 이름을 짓는다.
    ENAME VARCHAR2(10) NOT NULL,
    JOB VARCHAR2(9),
    DEPTNO NUMBER(2)
);




UNIQUE 제약조건이 걸린 속성의 값들은 중복되면 안됩니다.

따라서 다음과 같은 INSERT 문은 오류를 발생시킵니다.


INSERT INTO EMP03 VALUES(2000,'구경민',NULL,NULL);
INSERT INTO EMP03 VALUES(2000,'김',NULL,NULL); -- 데이터 삽입불가 UNIQUE 조건 위배




image



오류 내용을 보시면 제약조건명을 정의해주지 않아서 시스템이 자동적으로 SYS_C007426 이라고 제약조건 명을 정해주었습니다.

하지만, 저렇게 제약조건 명을 지정해주지 않으면 나중에 오류가 발생했을 때 어떤 부분때문에 오류가 발생하는지 알기 쉽지 않습니다.

따라서 다음과 같이 제약조건 명을 지정해주는 것이 좋습니다.


// 제약조건 명

테이블명_칼럼명_제약조건타입 (u,c,pk,fk)




CREATE TABLE EMP01(
    EMPNO NUMBER(4) CONSTRAINT EMP01_EMPNO_UK UNIQUE, --제약조건 명 EMP01_EMPNO_UK
    ENAME VARCHAR2(10) CONSTRAINT EMP01_ENAME_NN NOT NULL, --제약조건 명 EMP01_ENAME_NN
    JOB VARCHAR2(9),
    DEPTNO NUMBER(2)
);



만약 데이터 삽입 시 오류가 나면 지정한 제약조건 명이 나타나기에 오류가 어디서 발생했는지 금방 파악 가능합니다!




image



기본키 제약조건



테이블에서 행을 유일하게 식별할 수 있는 키를 기본키라고 합니다!

기본키는 NULL이면 안되고, 유일한 값이어야 합니다!

기본키 제약조건은 다음과 같이 걸 수 있습니다.


CREATE TABLE DEPT01(
    DEPTNO NUMBER(2) CONSTRAINT DEPT01_DEPTNO_PK PRIMARY KEY, --기본키 제약조건
    DNAME VARCHAR(14),
    LOC VARCHAR2(10)
);



외래키 제약조건




외래키 제약조건은 참조 무결성을 위한 것입니다.

다른 테이블의 기본키를 참조하는 속성을 외래키라고 하는데,

외래키는 참조하는 테이블에서 존재하는 값이어야합니다.

만약 다음과 같은 테이블 EMP01과 DEPT01이 있다고 합시다.


CREATE TABLE DEPT01(
    DEPTNO NUMBER(2) CONSTRAINT DEPT01_DEPTNO_PK PRIMARY KEY,
    DNAME VARCHAR(14),
    LOC VARCHAR2(10)
);

INSERT INTO DEPT01 VALUES (10,'Marketing','Seoul');

CREATE TABLE EMP01(
    EMPNO NUMBER(4) CONSTRAINT EMP01_EMPNO_PK PRIMARY KEY,
    ENAME VARCHAR2(10) CONSTRAINT EMP01_ENAME_NN NOT NULL,
    JOB VARCHAR2(9),
    DEPTNO NUMBER(2) CONSTRAINT EMP01_DEPTNO_FK REFERENCES DEPT01(DEPTNO)
);

INSERT INTO EMP01 VALUES (01,'KOO','사장',10); 



image



현재 EMP01 테이블의 DEPTNO 속성은 외래키이며, DEPT01 테이블의 기본키 DEPTNO를 참조하고 있습니다.

이 때, 다음과 같은 INSERT 문은 오류를 발생시킵니다.


INSERT INTO EMP01 VALUES(02,'LEE','대리',20); --외래키 제약조건 위배:DEPT01에 DEPTNO가 20인 행 존재 X




image



check 제약 조건



check 제약조건은 다음과 같이 정의합니다.


CREATE TABLE EMP01(
    EMPNO NUMBER(4) CONSTRAINT EMP01_EMPNO_PK PRIMARY KEY,
    ENAME VARCHAR2(10) CONSTRAINT EMP01_ENAME_NN NOT NULL,
    JOB VARCHAR2(9),
    DEPTNO NUMBER(2) CONSTRAINT EMP01_DEPTNO_FK REFERENCES DEPT01(DEPTNO),
    SAL NUMBER(7,2) CONSTRAINT EMP01_SAL_CK CHECK(SAL BETWEEN 500 AND 5000), --check 제약조건
    GENDER VARCHAR2(1) CONSTRAINT EMP01_GENDER_CK CHECK(GENDER IN('M','F')) --check 제약조건
);



속성 SAL에는 500부터 5000까지의 입력값이 올 수 있기에 다음과 같은 INSERT문은 오류를 발생시킵니다.


INSERT INTO EMP01 VALUES(02,'KOO','사장',10,10000,'M'); --CHECK 제약조건 위반




image



DEFAULT



속성 값에 DEFAULT 값이 올 경우, 다른 값으로 채우도록 미리 설정할 수 있습니다.


CREATE TABLE DEPT01(
    DEPTNO NUMBER(2) CONSTRAINT DEPT01_DEPTNO_PK PRIMARY KEY,
    DNAME VARCHAR(14),
    LOC VARCHAR2(10) DEFAULT 'SEOUL' -- LOC에 값이 안들어오면 seoul을 넣는다.
);




INSERT INTO DEPT01(DEPTNO,DNAME) VALUES(50,'회계부'); --DEFALUT가 적용되려면, 속성을 지정해주어야한다.
INSERT INTO DEPT01 VALUES(60,'회계부',DEFAULT); -- 아니면 DEFAULT 삽입




image