Welcome! Everything is fine.

[DB] 데이터 무결성과 제약 조건 종류 본문

DB

[DB] 데이터 무결성과 제약 조건 종류

개발곰발 2026. 4. 11.
728x90
인프런 <김영한의 실전 데이터베이스 - 기본편> 강의를 토대로 정리한 내용입니다.

 


- 목차 -

1. 데이터 무결성

2. 기본 제약 조건

   1) NOT NULL

   2) UNIQUE

   3) PRIMARY KEY

   4) DEFAULT

3. 외래 키 제약 조건

   1) 규칙

   2) ON DELETE / ON UPDATE 옵션

4. CHECK 제약 조건

데이터 무결성

  • 데이터 무결성(Data Integrity) : 데이터의 정확성, 일관성, 유효성을 유지하는 성질
  • 제약 조건(Constraints) : 데이터 무결성을 강제하기 위해 테이블의 특정 컬럼에 설정하는 규칙

GIGO (Garbage In, Garbage Out) : 쓰레기가 들어가면 쓰레기가 나온다. 초기 데이터의 신뢰도가 결과물의 신뢰도를 결정한다.

 

잘못된 데이터는 잘못된 비즈니스 결정, 시스템 오류, 데이터 불일치 등 심각한 문제를 야기한다. 그래서 데이터베이스는 데이터를 지키는 '최후의 보루' 역할을 해야 한다. 1차 검증은 애플리케이션에서 하더라도, 데이터베이스에 유효한 값만 입력되도록 강제하기 위해 제약 조건(Constraints) 이 필요하다. 제약 조건에는 기본 제약 조건, 외래 키 제약 조건, CHECK 제약 조건이 있다.

기본 제약 조건

제약조건 역할 특징
NOT NULL NULL 값 방지 필수 정보 누락을 원천 차단
UNIQUE 중복 값 방지 모든 값이 테이블 내에서 고유해야 함
PRIMARY KEY 행의 고유 식별자 NOT NULL + UNIQUE, 테이블당 1개만 설정 가능
DEFAULT 기본값 설정 값을 입력하지 않았을 때 자동으로 채워질 값 지정

NOT NULL : NULL 값 방지

  • NOT NULL은 해당 컬럼에 NULL 값이 저장되는 것을 허용하지 않는다. 필요한 정보가 누락되는 것을 막는다.
email VARCHAR(255) NOT NULL

UNIQUE : 중복 값 방지

  • UNIQUE는 해당 컬럼에 들어가는 모든 값은 테이블 내에서 반드시 고유해야 한다. 중복 데이터가 쌓이는 것을 막는다.
email VARCHAR(255) UNIQUE

PRIMARY KEY (기본 키) : 행의 대표 식별자

  • 테이블의 각 행을 고유하게 식별하는 단 하나의 대표키다. NOT NULL + UNIQUE 특징을 모두 가지며, 테이블당 하나만 설정할 수 있다. 기본 키를 기준으로 데이터가 저장되고 검색되므로 성능에도 매우 중요한 역할을 한다.
user_id BIGINT PRIMARY KEY

 

여러 컬럼을 묶어 복합 기본 키로 지정할 수도 있다.

CREATE TABLE order_items (
  order_id INT,
  item_id  INT,
  quantity INT,
  PRIMARY KEY (order_id, item_id)
);

DEFAULT : 기본 값 설정

  • DEFAULT는 특정 컬럼에 값을 명시적으로 입력하지 않았을 경우, 자동으로 설정될 기본값을 지정한다.
status VARCHAR(50) DEFAULT 'PENDING'

외래 키 제약 조건 (Foreign Key)

외래 키 제약 조건은 참조 무결성을 강제하는 제약 조건이다.

  • 참조 무결성(Referential Integrity) : 두 테이블의 관계가 항상 유효하고 일관된 상태를 유지해야 한다는 원칙,

규칙

외래 키 제약 조건은 두 가지 중요한 규칙을 통해 우리의 데이터를 보호한다.

  1. 자식 테이블: 부모 테이블에 존재하지 않는 id 값을 자식 테이블의 FK 컬럼에 넣으려는 시도를 막는다.
  2. 부모 테이블: 자식 테이블에서 참조하고 있는 행을 부모 테이블에서 함부로 삭제/변경하지 못하게 막는다.
CREATE TABLE orders (
  id      INT PRIMARY KEY,
  user_id INT,
  FOREIGN KEY (user_id) REFERENCES users(id)
);

ON DELETE / ON UPDATE 옵션

외래 키의 ON DELETE와 ON UPDATE 에서 별도의 참조 동작을 지정하지 않으면, 기본적으로 부모 데이터의 삭제나 수정을 제한 한다. 지정할 수 있는 참조 동작은 다음과 같다.

옵션 동작
RESTRICT (기본값) 자식 테이블에 참조하는 행이 있으면 부모 행을 삭제/수정할 수 없다
CASCADE 부모 행이 삭제/수정되면 자식 행도 함께 자동으로 삭제/수정된다
SET NULL 부모 행이 삭제/수정되면 자식의 FK 컬럼 값을 NULL로 설정한다
SET DEFAULT 부모 행이 삭제/수정되면 자식의 FK 컬럼 값을 기본값으로 변경한다
NO ACTION 즉각 체크하지 않고, 트랜잭션 종료 시 무결성을 검사한다
💡 CASCADE는 의도치 않은 대량 삭제 위험이 있다. 실무에서는 애플리케이션 계층에서 명시적으로 처리하는 방식을 선호하기도 한다.

CHECK 제약 조건

CHECK는 컬럼에 들어올 값의 범위나 조건을 직접 지정하며, 조건식이 참(true) 일 때만 입력을 허용한다. 데이터의 '내용'과 '비즈니스 규칙'을 DB 레벨에서 강제하기 위해 사용한다.

CREATE TABLE products (
  id            INT PRIMARY KEY,
  name          VARCHAR(100) NOT NULL,
  price         INT CHECK (price >= 0),
  discount_rate INT CHECK (discount_rate BETWEEN 0 AND 100)
);

 

컬럼 간 비교 조건도 표현할 수 있다.

CREATE TABLE employees (
  id         INT PRIMARY KEY,
  hire_date  DATE,
  birth_date DATE,
  CHECK (hire_date > birth_date)
);

⚠️ MySQL 주의사항: MySQL 8.0 이전 버전에서는 CHECK 제약 조건을 파싱은 하지만 실제로 강제하지 않는다. MySQL 8.0+, PostgreSQL, Oracle 등에서는 정상적으로 동작한다.

💡 최근에는 유연성과 테스트 편의성을 위해 애플리케이션 코드에서 검증을 처리하는 추세다. DB의 CHECK 제약 조건은 핵심 데이터의 '최후 방어선'으로만 신중하게 사용한다.