Primary Key와 Unique Index로 데이터 무결성 설계하기
Primary Key와 Unique Index의 차이, NULL 처리와 외래 키 참조, 성능 영향 및 데이터베이스 설계 시 고려할 기준을 정리한다.
2026-08-14 · 최초 발행 2025-08-10
레코드 식별과 중복 방지는 같은 문제가 아니다
테이블의 데이터를 신뢰하려면 각 행을 분명히 구분할 수 있어야 하고, 업무적으로 중복될 수 없는 값도 막아야 한다. Primary Key와 Unique Index는 이 두 요구를 맡는 대표적인 장치다. 둘 다 중복을 허용하지 않지만, 레코드를 식별하는 기준인지 특정 데이터의 유일성을 보장하는 장치인지에 따라 설계 의도가 달라진다.
Primary Key는 테이블의 식별 기준이다
Primary Key(기본 키)는 테이블 안의 각 레코드를 고유하게 구분하는 하나의 필드 또는 여러 필드의 조합이다. 중복 값과 NULL 값을 허용하지 않으며, 테이블마다 하나만 둘 수 있다. DBMS는 Primary Key에 자동으로 인덱스를 만들고, 다른 테이블이 Foreign Key로 관계를 맺을 때 기준점으로 사용한다.
단일 컬럼뿐 아니라 여러 컬럼을 묶어 기본 키를 정의할 수도 있다.
-- 단일 필드 Primary Key
CREATE TABLE Employees (
EmployeeID INT PRIMARY KEY,
FirstName VARCHAR(50),
LastName VARCHAR(50),
Email VARCHAR(100)
);
-- 복합 Primary Key
CREATE TABLE OrderItems (
OrderID INT,
ProductID INT,
Quantity INT,
PRIMARY KEY (OrderID, ProductID)
);
Unique Index는 업무상 유일해야 하는 값을 지킨다
Unique Index는 지정한 컬럼 또는 컬럼 조합에 같은 값이 반복되지 않도록 만드는 인덱스다. 하나의 테이블에 여러 개를 둘 수 있고, 일반 인덱스처럼 조회 성능을 돕는 기능도 수행한다.
Primary Key와 달리 NULL을 허용할 수 있지만, 그 방식은 DBMS에 따라 다르다. 따라서 NULL을 포함하는 컬럼에 적용할 때는 해당 DBMS의 처리 방식을 함께 확인해야 한다.
-- 단일 컬럼 Unique Index
CREATE TABLE Users (
UserID INT PRIMARY KEY,
Username VARCHAR(50),
Email VARCHAR(100),
UNIQUE INDEX idx_username (Username),
UNIQUE INDEX idx_email (Email)
);
-- 복합 컬럼 Unique Index
CREATE TABLE Reservations (
ReservationID INT PRIMARY KEY,
RoomNumber INT,
ReservationDate DATE,
UNIQUE INDEX idx_room_date (RoomNumber, ReservationDate)
);
제약의 차이를 설계 의도로 구분하기
| 구분 | Primary Key | Unique Index |
|---|---|---|
| 유일성 | 필수 | 필수 |
| NULL 값 | 허용하지 않음 | 허용 가능(DBMS에 따라 다름) |
| 테이블당 개수 | 테이블당 1개만 가능 | 여러 개 가능 |
| 외래 키 참조 | 가능 | 가능하지만 권장되지 않음 |
| 클러스터링 | 기본적으로 클러스터형 인덱스(특히 MS SQL Server) | 기본적으로 비클러스터형 인덱스 |
| 목적 | 레코드 식별 및 무결성 보장 | 데이터 무결성 및 검색 성능 향상 |
Primary Key는 테이블 자체의 정체성을 정의한다. 반면 Unique Index는 사용자명, 이메일, 제품 코드처럼 업무 규칙상 중복을 허용할 수 없는 값을 보호하는 데 적합하다.
회원과 재고 데이터에서의 역할
회원 관리에서는 사용자를 가리키는 식별자와 중복을 막아야 하는 로그인 정보가 분리된다.
UserID는 사용자를 식별하는 Primary Key다. Username과 Email은 중복을 막기 위해 Unique Index로 두며, UserProfiles는 UserID를 Foreign Key로 사용해 Users와 연결한다.
재고 관리에서도 제품 식별자와 업무용 제품 코드를 구분할 수 있다.
ProductID는 제품을 식별하는 Primary Key이고, 제품 코드인 SKU는 Unique Index로 중복을 차단한다. InventoryTransactions는 ProductID를 Foreign Key로 사용해 재고 변동을 추적한다.
인덱스 선택이 성능에 미치는 영향
Primary Key는 테이블 접근의 주요 경로가 되며, 클러스터형 인덱스로 구현될 경우 물리적 데이터 정렬에도 영향을 준다. 따라서 짧고 불변하는 값이 효율적이며, INT, BIGINT 타입이 예가 될 수 있다.
Unique Index는 조회 쿼리 최적화에 도움이 된다. 다만 INSERT, UPDATE 시에는 추가 검증이 필요하므로 약간의 오버헤드가 생긴다. 필요 이상으로 많은 Unique Index를 만들면 데이터 수정 성능이 떨어질 수 있다.
자연키와 대리키를 고르는 기준
기본 키 후보에는 업무 의미를 가진 자연키와 시스템이 생성하는 대리키가 있다.
자연키는 주민등록번호나 사업자번호처럼 업무상 의미가 있는 값이다. 별도 조인 없이 식별할 수 있고 의미를 바로 알 수 있다는 장점이 있지만, 변경 가능성·복잡성·길이 문제가 생길 수 있다.
대리키는 자동 증가 정수처럼 시스템이 만든 인공적인 값이다. 단순하고 불변하며 성능 최적화에 유리하지만, 업무적 의미가 없고 식별을 위해 추가 조회가 필요할 수 있다.
Unique Index를 설계할 때는 먼저 업무적으로 중복을 허용하지 않는 필드를 식별한다. 복합 컬럼 인덱스라면 필드 순서를 검토하고, 인덱스 크기와 성능 사이의 균형도 고려해야 한다.
Oracle과 MySQL에서의 선언 방식
Oracle에서는 기본 키, 고유 인덱스, 고유 제약조건을 다음과 같이 정의할 수 있다.
-- Primary Key 생성
CREATE TABLE Customers (
CustomerID NUMBER PRIMARY KEY,
CustomerName VARCHAR2(100) NOT NULL,
Email VARCHAR2(100)
);
-- Unique Index 생성
CREATE UNIQUE INDEX idx_customer_email ON Customers(Email);
-- 제약조건 형태로 Unique 제약 추가
ALTER TABLE Customers ADD CONSTRAINT uk_customer_email UNIQUE (Email);
MySQL에서도 기본 키와 고유 인덱스, 고유 키 제약조건을 선언할 수 있다.
-- Primary Key 생성
CREATE TABLE Products (
ProductID INT AUTO_INCREMENT PRIMARY KEY,
ProductCode VARCHAR(20) NOT NULL,
ProductName VARCHAR(100) NOT NULL
);
-- Unique Index 생성
CREATE UNIQUE INDEX idx_product_code ON Products(ProductCode);
-- 테이블 생성 시 제약조건 추가
CREATE TABLE Suppliers (
SupplierID INT AUTO_INCREMENT PRIMARY KEY,
SupplierName VARCHAR(100) NOT NULL,
TaxID VARCHAR(20),
UNIQUE KEY uk_tax_id (TaxID)
);
충돌과 성능 저하를 운영에서 다루는 방법
Unique 제약조건 위반은 삽입 또는 업데이트 실패로 이어진다. 이 경우 MERGE 또는 UPSERT 구문을 사용하거나, 애플리케이션에서 사전 검증하는 방법을 고려할 수 있다.
많은 Unique Index가 DML 작업을 느리게 한다면 불필요한 인덱스를 제거하고 복합 인덱스를 최적화한다. NULL 값 처리에서 문제가 생길 경우에는 DBMS별 처리 방식을 이해하고 NOT NULL 제약조건을 활용한다.
운영 단계에서는 인덱스 통계를 정기적으로 갱신하고, 단편화를 모니터링해 재구성한다. 쿼리 실행 계획으로 인덱스 사용 패턴을 살피고, 불필요하거나 중복된 인덱스도 식별해 제거한다.
Primary Key는 데이터 행의 식별자이고, Unique Index는 업무 규칙에 따른 유일성을 보장하는 장치다. 초기 설계부터 두 역할을 분리해 두면 데이터 품질과 시스템 성능을 함께 다루기 쉬워진다.