본문 바로가기
DataBase/Oracle

DDL/CONSTRAINT) UNIQUE 제약 조건 (제약 조건 작성법, constraint_name)

by 박채니 2022. 4. 26.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


CONSTRAINT

- 제약 조건

테이블의 컬럼에 대해서 데이터 무결성을 지키기 위해 설정하는 조건

※ 데이터 무결성이란?

데이터가 일관되고, 정확하게 유지 되는 것

not null을 제외하고 constraint_name을 반드시 지정 및 table_level로 작성

 

① not null (C) : 해당 컬럼에 null 값을 허용하지 않음

② unique (U) : 레코드 별로 해당 컬럼에 중복을 허용하지 않음

③ primary key (P) : 식별자 컬럼을 지정, 레코드를 구별하기 위한 고유 값을 가진 컬럼 → 테이블 당 하나만 허용 / null 허용 X

④ foreign key (R) : 외래키. 부모 테이블의 특정 컬럼 값만 사용 가능하도록 제약

⑤ check (C) : 해당 컬럼의 값의 범위/목록을 제한 (도메인을 설정하는 제약 조건)

 


UNIQUE

- 레코드 별로 해당 컬럼에 중복 허용 X


제약 조건 작성법

1) 테이블 레벨 - 컬럼 작성과 동일한 레벨에 작성

2) 컬럼 레벨 - 컬럼 설정 시 옆에 작성

-- drop table member_2;
create table member_2(
    id varchar2(20) primary key,
    password varchar2(20) not null,
    name varchar2(50) not null,
--    email varchar2(150) constraint uq_member_2_email unique,    -- 컬럼레벨
    email varchar2(150),
    reg_date date default sysdate,
    constraint uq_member_2_email unique(email)  -- 테이블 레벨
);

컬럼 설정 시 옆에 작성한 방법이 컬럼 레벨 / 컬럼 작성과 동일한 레벨에 작성하는 테이블 레벨 두가지 방식이 있습니다.

 

not null 제약 조건을 제외한 나머지 제약 조건들은 모두 테이블 레벨로 작성하는 것을 권장한다고 합니다.

또한, constraint_name을 지정해주어 오류가 발생하였을 때 직관적으로 확인할 수 있도록 해줍니다.

(constraint uq_member_2_email unique(email))에서 uq_member_2_email이 constraint_name입니다.

 

insert into
    member_2(id, password, name, email)
values ('honggd', '1234', '홍길동', 'honggd@gmail.com');

insert into
    member_2(id, password, name, email)
values ('hgd', '1234', '홍길똥', 'honggd@gmail.com'); 
--ORA-00001: unique constraint (KH.UQ_MEMBER_2_EMAIL) violated

'홍길동'과 '홍길똥'이 사용하는 이메일이 같다고 가정했을 때, 회원 입력을 하니 '홍길똥'에 오류 메세지가 출력되는 것을 확인할 수 있습니다.

"ORA-00001: unique constraint (KH.UQ_MEMBER_2_EMAIL) violated"

uq_member_2_email에 대해서 중복 되는 이메일이 있기 때문에 uq 제약 조건 위반이라는 메세지입니다.

 

그렇다면 null 값은 중복 체크가 될까?

insert into
    member_2(id, password, name, email)
values ('sinsa', '1234', '신사임당', null);

insert into
    member_2(id, password, name, email)
values ('hgd', '1234', '홍가당', null);

오라클은 복수의 null 값 허용 및 null 값은 동등 비교가 불가하므로 중복 체크가 안됩니다.

(MSSQL은 null 값을 하나만 허용)

 

만약 null 값 또한 허용하고 싶지 않다면 not null 제약 조건을 추가해주면 됩니다.

-- drop table member_2;
create table member_2(
    id varchar2(20) primary key,
    password varchar2(20) not null,
    name varchar2(50) not null,
    email varchar2(150) not null,
    reg_date date default sysdate,
    constraint uq_member_2_email unique(email)  -- 테이블 레벨
);

 

insert into
    member_2(id, password, name, email)
values ('sinsa', '1234', '신사임당', null);
-- ORA-01400: cannot insert NULL into ("KH"."MEMBER_2"."EMAIL")

 

☞ constraint_name을 설정하는 이유

-- drop table member_2;
create table member_2(
    id varchar2(20) primary key,
    password varchar2(20) not null,
    name varchar2(50) not null,
    email varchar2(150) unique,
    reg_date date default sysdate
);

 

insert into
    member_2(id, password, name, email)
values ('honggd', '1234', '홍길동', 'honggd@gmail.com');

insert into
    member_2(id, password, name, email)
values ('hgd', '1234', '홍길똥', 'honggd@gmail.com'); 
-- ORA-00001: unique constraint (KH.SYS_C007637) violated

SYS_C007637에 대해서 unique 제약 조건 위반이라고 하는데 SYS_C007637이 어떤 컬럼을 가리키는 지 알 수 없습니다.

 

select * from user_cons_columns where constraint_name = 'SYS_C007637';

어떤 컬럼을 가리키는 지 확인하기 위해 또 다른 테이블을 조회해야하는 번거로움이 있습니다.

따라서 constraint_name을 설정해주는 습관을 갖는 게 좋습니다!