Database

[Database] Ch08. Constraint 제약조건

OptimizerStart 2025. 5. 5. 17:01

[Database] Ch08. Constraint 제약조건

제약조건 Constraint

사용 이유

  • 데이터 보호, 데이터 무결성(integrity)을 유지하기 위해 제약 조건이 필요
  • 데이터 보호 : DB에 잘못된 데이터가 들어가는 것을 막음 ex. [ JAVA ] 캡슐화
  • if문으로 무결성을 체크함.

종류 - 5 ⭕ 암기

  1. PK = NOT NULL + UNIQUE
    • UNIQUE 여러 행이 같은 컬럼 혹은 같은 컬럼 조합에 대해 같을 값을 가지는 걸 막음. 단, NULL값을 여러 행이 가져도 됨.
  2. FK
  3. CHECK (조건)
    • 사용자 정의 조건

 

[참고 ] ORACLE Contraint -5 정리

특징

  • 데이터 사전에 제약조건 저장됨
  • 제약 조건 이름은 한 사용자에서 중복 불가

특성

무결성 integrity

  • 데이터 결함이 없음.

cf.

영속성 persistent

  • 한번 저장한 데이터가 유지되는 것. DB 쓰는 이유

일관성 consistency

  • sum이 맞음

Constraint 정의 방법

DDL 문장안에서 제약조건을 어디에, 어떻게 붙이느냐 구분

 

컬럼 레벨 제약조건

  • 컬럼 정의 바로 뒤
  • 적용 범위 : 컬럼에만 적용되는 제약조건
  • 종류 : not null

테이블 레벨 제약조건

  • 모든 컬럼 정의 이후 CREATE TABLE 구문 마지막 부분
  • 적용 범위 : 여러 컬럼에 적용 or 테이블 전체 적용

방식 -2

  1. create table 테이블명 ( 컬럼명 타입 제약조건유형, constraint [제약조건명] 제약조건유형 (컬럼1, 컬럼2,… ));
  2. alter table 테이블명 add constraint [제약조건명] 제약조건유형 (컬럼1, 컬럼2,…)

제약조건 이름 정의

- 표준 객체 명명 사용

  • 1~30바이트 범위 내의 길이
  • 비예약어여야 하며(비인용식), 식별자는 반드시 문자로 시작
  • ASCII 대문자, 숫자, 밑줄(_)만 사용
  • 일관된 패턴(네이밍 컨벤션)을 적용
제약조건 종류 권장 접두사 예시 설명
Primary Key PK_ PK_EMPLOYEES 테이블명 또는 약어를 뒤에 붙여 “PK_테이블명” 형태
Foreign Key FK_ FK_ORDERS_CUSTOMERS “FK_자식테이블_부모테이블” 형태
Unique UQ_ 또는 UK_ UQ_EMP_EMAIL / UK_ORD_NUM 단일 컬럼 또는 복합 컬럼에 “UQ_테이블_컬럼” 형태
Check CK_ CK_EMP_SALARY “CK_테이블_컬럼” 형태로 조건 의미를 덧붙이기도 함
Not Null (컬럼 레벨) (없음) 컬럼 정의 바로 뒤에 NOT NULL만 지정 Oracle은 컬럼 레벨에서만 NOT NULL 지원(별도 이름 없음)

 

 

제약조건 조회 주의사항

  • create table 테이블명 과 같이 따옴표 없이 작성한 식별자는 oracle이 내부에서 자동으로 대문자로 변환해 데이터 사전에 저장
  • 제약 조건 생성 한 것 조회 시 테이블 명 항상 대문자로 검색
    데이터 사전에 대문자로 저장된 테이블 명

--  테이블 명을 소문자로 생성해도, 검색 시 소문자로 하면 검색 안됨.
-- 실제 쿼리 결과, 데이터베이스에는 대문자로 테이블 명이 저장됨. 
-- STUDENT	UQ_DEMO_BASIC_EMAIL	U	DEMO_BASIC						ENABLED	NOT DEFERRABLE	IMMEDIATE	VALIDATED	USER NAME			25/05/05	STUDENT	UQ_DEMO_BASIC_EMAIL			1
select * from user_constraints where table_name = 'demo_basic'; -- 검색 x
select * from user_constraints where table_name = upper('demo_basic'); -- 검색 o

 

 

1. NOT NULL 제약조건

컬럼 레벨에만 정의 가능

2. UNIQUE 제약조건

컬럼 1개, 여러 개 컬럼 조합을 고유키로 지정

  • 단일컬럼 혹은 복합 컬럼의 값이 모두 null 인것 무제한 허용
  • oracle 에서는 null 끼리는 서로 다르다 간주함.
    • 여러 컬럼 조합에서 null 이 들어간 컬럼이 있으면 안됨.
    • 테이블 1개에 1개의 PK 제약조건만 정의, 여러개 불가

cf. PK 제약조건

  • 한 테이블에 여러 개 제약조건 정의 가능

cf. Unique 인덱스

  • 인덱스 생성 시 인덱스가 지정한 컬럼 값이 고유하도록 지정
  • oracle에서 기본적으로 인덱스로 지정한 컬럼에 중복 값 허용

표현 constraint [제약조건명] unique(컬럼명1, 컬럼명2..)

  • 제약조건명 생략 가능
  • 단일 컬럼은 단일 컬럼에 대한 중복 여부 확인, null 값 중복 허용
  • 복합 컬럼은 여러 컬럼 조합에 대해 고유성 확인. null 값 중복 허용

에러 형식 - 제약조건 명으로 뜸.

  • 단일 컬럼 ORA-00001: 무결성 제약 조건(STUDENT.UQ_T_MEMBERS_USERNAME)에 위배됩니다
  • 복합 컬럼 ORA-00001: 무결성 제약 조건(STUDENT.UQ_MEMBERS_IDENTITY)에 위배됩니다
create table t_members (
    -- 컬럼 레벨 제약 조건 not null 
    member_id number,
    username varchar(30) not null,
    email varchar(100) not null,
    phone varchar(20),
    first_name varchar(50) not null,
    last_name varchar(50) not null,
    date_of_birth date not null,
    
    -- 단일 unique 제약 조건 - 단일 컬럼의 값의 고유성 보장
    constraint uq_t_members_username unique(username),
    constraint uq_t_members_email unique(email),
    constraint uq_t_members_phone unique(phone), 
    -- 복합 unique 제약 조건 - 조합의 고유성 보장. 단일 컬럼의 중복들을 허용 
    constraint uq_members_identity unique(first_name, last_name, date_of_birth),
    constraint pk_t_members_member_id primary key(member_id)
    );
    
desc t_members;
-- ddl 명령어는 자동 커밋 되므로 db에 자동 반영됨. 

insert into t_members values(1, 'jdoe', 'john.doe@example.com', '010-1234-5678', 'John', 'Doe', '1985/06/15');
insert into t_members values(2, 'asmith', 'anna.smith@example.com', '010-2345-6789', 'Anna', 'Smith', '1990/11/02');
insert into t_members values(3, 'kpark', 'kim.park@example.com', null, 'Kim', 'Park', '1978/03/30');
insert into t_members values(4, 'jlee', 'jeong.lee@example.com', '010-3456-7890', 'Jeong', 'Lee', '2000/04/19');
select * from t_members;

-- unique 제약조건 데이터 삽입으로 확인
-- ORA-00001: 무결성 제약 조건(STUDENT.UQ_T_MEMBERS_USERNAME)에 위배됩니다
-- 이름이 중복이 되어 값 삽입이 불가능
insert into t_members values(5, 'jdoe', 'john2doe@gmail.com', '010-3983-0229', 'John', 'Doe', '2003/01/21');

-- 복합 unique 제약조건 확인
-- 1) 3개 컬럼 중 하나만 다른 값 가짐
insert into t_members values(5, 'jhonkim', 'john2doe@gmail.com', '010-3983-0229', 'John', 'Doe', '2003/01/21');
select * from t_members;
-- 2) 3개의 컬럼이 중복되는 경우 
-- 에러. ORA-00001: 무결성 제약 조건(STUDENT.UQ_MEMBERS_IDENTITY)에 위배됩니다
--- 복합 unique 제약조건에 위배되어 삽입 불가. 
insert into t_members values(6, 'jhonpark', 'johnoark@gmail.com', '010-4341-5512', 'John', 'Doe', '2003/01/21');

 

 

3. Foregin Key 제약조건

대상 컬럼

  • 다른 테이블의 PK
  • UNIQUE 제약 조건이 걸린 컬럼

특징

  • 참조하고자 하는 테이블(parent)이 먼저 생성되어 있어야함.
  • 타입 일치

표현 - foreign key() 유무

    • 컬럼 레벨
      컬럼명 타입 constraint [제약조건명] references parent테이블명(parent 컬럼명) )
    • 테이블 레벨
      create table 테이블명 ( 
      constraint [제약조건명] foreign key(child 컬럼명) references parent테이블명(parent컬럼명)

규칙

  • NO ACTION 에러 발생
  • CASCADE 자식 테이블의 행을 갱신 또는 삭제
  • SET NULL 자식 테이블의 행의 값을 NULL로 설정
  • SET DEFAULT 자식 테이블의 행의 값을 기본값으로 설정
  • RESTRICT 참조하는 행(parent) 갱신 또는 삭제 불가
create table t_orders(
    order_id number,
    customer_id number not null,
    constraint pk_t_orders_order_id primary key(order_id),
    constraint fk_t_orders_customer_id 
    foreign key(customer_id) references t_customer(customer_id)
    );

 

 

4. Check 제약조건

각 행이 만족해야할 조건을 정의

표현

  • 컬럼 레벨 컬럼명 데이터 타입 check( 조건식)
  • 테이블 레벨

참조 무결성 제약조건

자식 테이블에 입력하려는 값이 부모 테이블에 없는 경우 제약 조건 위반

  • 자식 테이블에서 수정/하려는 값이 부모 테이블에 없는 경우

부모 테이블에서 삭제하려는 값이 자식 테이블에서 참조하고 있는 경우 제약 조건 위반