참조무결성으로 관계형 데이터의 연결을 지키는 방법
참조무결성의 기본 키·외래 키 관계와 CASCADE, SET NULL, RESTRICT 옵션을 통해 관계형 데이터베이스의 일관성을 관리하는 방법
2026-08-14 · 최초 발행 2025-08-10
테이블 사이의 연결이 깨지는 순간
관계형 데이터베이스에서 참조무결성(Referential Integrity)은 테이블 사이에 맺은 관계가 유효하게 남아 있도록 보장하는 규칙이다. 기본 키(Primary Key)와 외래 키(Foreign Key)의 관계로 구현하며, 데이터 품질과 신뢰성을 지키는 핵심 무결성 제약조건에 속한다.
이 제약이 없으면 부모 레코드가 사라진 뒤에도 자식 레코드가 남는 고아 레코드(Orphaned Records), 서로 맞지 않는 불일치 데이터(Inconsistent Data)가 생길 수 있다. 참조무결성은 이런 상태가 데이터베이스에 들어오거나 유지되지 않도록 막는다.
기본 키와 외래 키가 맡는 역할
기본 키는 테이블 안의 각 레코드를 고유하게 식별하는 필드 또는 필드 조합이다. 중복 값을 가질 수 없고 NULL도 허용하지 않으므로, 레코드의 고유성을 보장하는 기준점이 된다.
CREATE TABLE Departments (
DeptID INT PRIMARY KEY,
DeptName VARCHAR(50) NOT NULL
);
외래 키는 다른 테이블의 기본 키를 참조하는 필드다. 자식 테이블과 부모 테이블을 연결하며, 외래 키에는 부모 테이블의 기본 키에 존재하는 값만 들어갈 수 있다.
CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(100) NOT NULL,
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
);
삽입·삭제·갱신에서 적용되는 규칙
자식 테이블에 레코드를 추가할 때 외래 키 값은 부모 테이블 기본 키 중 하나이거나 NULL이어야 한다. 예를 들어 직원 테이블에 직원을 등록할 때, 해당 부서 ID는 부서 테이블에 존재해야 한다.
부모 레코드를 삭제할 때는 이를 참조하는 자식 레코드를 어떻게 다룰지 결정해야 한다. 부모의 기본 키가 갱신되는 경우도 마찬가지다. 삭제와 갱신에는 CASCADE, SET NULL, SET DEFAULT, RESTRICT 또는 NO ACTION 같은 옵션을 적용할 수 있다.
변경을 자식 레코드에 전파하는 CASCADE
CASCADE는 부모 테이블에서 발생한 삭제나 갱신을 자식 테이블로 자동 전파한다. 부모 레코드를 삭제하면 이를 참조하던 자식 레코드도 함께 삭제되고, 부모 키가 바뀌면 자식의 외래 키도 자동으로 갱신된다.
CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(100) NOT NULL,
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
ON DELETE CASCADE
ON UPDATE CASCADE
);
관계는 남기고 참조 값만 비우는 SET NULL
SET NULL은 부모 레코드가 삭제되거나 갱신될 때 자식 테이블의 외래 키 값을 NULL로 바꾼다. 이 방식을 쓰려면 외래 키 필드가 NULL을 허용해야 한다.
CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(100) NOT NULL,
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
ON DELETE SET NULL
ON UPDATE SET NULL
);
기본값으로 참조를 대체하는 SET DEFAULT
SET DEFAULT는 부모 레코드의 삭제 또는 갱신 시 자식 테이블 외래 키에 정의된 기본값을 설정한다. 따라서 외래 키 필드에는 DEFAULT 제약조건이 있어야 한다.
CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(100) NOT NULL,
DeptID INT DEFAULT 1,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
ON DELETE SET DEFAULT
ON UPDATE SET DEFAULT
);
참조 중인 데이터가 있으면 거부하는 RESTRICT
RESTRICT 또는 NO ACTION은 부모 레코드를 삭제하거나 갱신하려 할 때 이를 참조하는 자식 레코드가 있으면 작업을 거부한다. 참조무결성을 유지하는 방식 가운데 가장 엄격하다.
CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(100) NOT NULL,
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
부서와 직원 테이블의 참조 관계
주문 이력과 조직 정보에 적용하는 방식
전자상거래에서는 주문 테이블이 고객 테이블을 참조한다. 고객이 삭제되더라도 주문 내역은 남겨야 한다. 주문 상세 테이블은 제품 테이블을 참조하며, 제품이 삭제되면 주문 상세의 참조 값은 NULL로 처리한다.
-- 고객 테이블
CREATE TABLE Customers (
CustomerID INT PRIMARY KEY,
CustomerName VARCHAR(100) NOT NULL
);
-- 주문 테이블
CREATE TABLE Orders (
OrderID INT PRIMARY KEY,
OrderDate DATE NOT NULL,
CustomerID INT,
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID)
ON DELETE SET NULL -- 고객이 삭제되어도 주문은 보존
);
-- 제품 테이블
CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(100) NOT NULL
);
-- 주문 상세 테이블
CREATE TABLE OrderDetails (
OrderDetailID INT PRIMARY KEY,
OrderID INT,
ProductID INT,
Quantity INT NOT NULL,
FOREIGN KEY (OrderID) REFERENCES Orders(OrderID)
ON DELETE CASCADE, -- 주문이 삭제되면 상세 정보도 삭제
FOREIGN KEY (ProductID) REFERENCES Products(ProductID)
ON DELETE SET NULL -- 제품이 삭제되면 NULL 처리
);
인사관리 시스템에서는 직원이 특정 부서에 소속된다. 부서가 해체되면 직원의 부서 정보는 NULL로 둘 수 있다. 직원이 퇴사하면 담당 프로젝트의 배정 정보에서 자동으로 제외하는 구조도 설계할 수 있다.
-- 부서 테이블
CREATE TABLE Departments (
DeptID INT PRIMARY KEY,
DeptName VARCHAR(50) NOT NULL
);
-- 직원 테이블
CREATE TABLE Employees (
EmpID INT PRIMARY KEY,
EmpName VARCHAR(100) NOT NULL,
DeptID INT,
FOREIGN KEY (DeptID) REFERENCES Departments(DeptID)
ON DELETE SET NULL -- 부서가 해체되면 소속 정보는 NULL
);
-- 프로젝트 테이블
CREATE TABLE Projects (
ProjectID INT PRIMARY KEY,
ProjectName VARCHAR(100) NOT NULL
);
-- 프로젝트 배정 테이블
CREATE TABLE ProjectAssignments (
AssignmentID INT PRIMARY KEY,
ProjectID INT,
EmpID INT,
FOREIGN KEY (ProjectID) REFERENCES Projects(ProjectID)
ON DELETE CASCADE, -- 프로젝트가 취소되면 배정 정보도 삭제
FOREIGN KEY (EmpID) REFERENCES Employees(EmpID)
ON DELETE CASCADE -- 직원이 퇴사하면 배정 정보도 삭제
);
제약조건을 운영할 때 확인할 점
참조무결성 제약조건은 삽입·삭제·갱신 시 추가 검증을 요구한다. 특히 CASCADE를 적용한 상태에서 자식 레코드가 많으면 성능 저하가 생길 수 있으므로, 대규모 시스템에서는 데이터 일관성과 성능 사이의 균형을 검토해야 한다.
테이블 A가 테이블 B를 참조하고 B가 다시 A를 참조하는 순환 참조도 발생할 수 있다. CASCADE와 함께 쓰면 무한 루프 가능성이 있으므로 데이터베이스 설계와 옵션 선택을 신중히 해야 한다.
여러 데이터베이스에 걸친 참조무결성은 구현하기 어렵고, DBMS마다 구현 방식도 다를 수 있다. 분산 환경에서는 애플리케이션 레벨의 무결성 검사를 병행하는 방식을 고려할 수 있다.
테이블 관계는 ER 다이어그램으로 명확히 모델링하고, 외래 키 필드에는 인덱스를 만들어 참조 검사 성능을 높인다. 여러 테이블에 걸친 변경은 트랜잭션으로 묶어 처리하며, 참조무결성 위반 여부를 확인하는 스크립트도 주기적으로 실행한다. 데이터베이스 제약조건에 더해 애플리케이션 로직에서도 무결성을 검증해야 한다.