Notice
Recent Posts
Recent Comments
Link
CHHB stroy
[DB] 데이터베이스 키(KEY) 종류 정리 본문
1. KEY(키)란 무엇인가?
KEY는 데이터베이스 테이블에서 레코드(행)를 유일하게 식별하거나 구분하는 데 사용되는 속성(컬럼) 또는 속성들의 집합입니다.
KEY의 기본 목적
- 데이터의 유일성(Uniqueness) 보장
- 레코드 간의 관계(Relationship) 설정
- 데이터 무결성(Integrity) 유지
- 효율적인 검색과 정렬 수행
2. KEY의 종류별 상세 설명
2.1 Super Key (슈퍼키)
정의: 테이블에서 각 레코드를 유일하게 식별할 수 있는 속성들의 집합
특징:
- 레코드를 구분할 수 있는 모든 가능한 속성 조합
- 최소성을 고려하지 않음 (불필요한 속성이 포함되어도 됨)
- 모든 다른 키들의 상위 개념
예시:
학생 테이블: [학번, 이름, 주민번호, 전화번호, 학과]
슈퍼키 예시:
- {학번}
- {주민번호}
- {학번, 이름}
- {학번, 주민번호}
- {학번, 이름, 전화번호}
- {주민번호, 학과}
- {학번, 이름, 주민번호, 전화번호, 학과} (모든 속성)2.2 Candidate Key (후보키)
정의: 슈퍼키 중에서 최소성을 만족하는 키 (더 이상 줄일 수 없는 최소한의 속성 집합)
특징:
- 유일성: 테이블의 모든 레코드를 유일하게 식별
- 최소성: 키를 구성하는 속성 중 하나라도 제거하면 유일성이 깨짐
- Primary Key의 후보가 되는 키들
예시:
학생 테이블: [학번, 이름, 주민번호, 전화번호, 학과]
후보키:
- {학번} ✓ (최소성 O, 유일성 O)
- {주민번호} ✓ (최소성 O, 유일성 O)
- {학번, 이름} ✗ (이름 제거해도 학번만으로 식별 가능 → 최소성 위배)2.3 Primary Key (기본키/주키)
정의: 후보키 중에서 선택된 메인 식별자
특징:
- NULL 값을 가질 수 없음
- 중복 값을 가질 수 없음
- 테이블당 단 하나만 존재
- 물리적으로 인덱스가 자동 생성됨
- 다른 테이블에서 Foreign Key로 참조됨
선택 기준:
- 단순성: 속성 개수가 적을수록 좋음
- 안정성: 값이 자주 변하지 않을수록 좋음
- 의미성: 비즈니스적으로 의미 있는 속성
예시:
-- 학생 테이블
CREATE TABLE Student (
student_id VARCHAR(10) PRIMARY KEY, -- 기본키
name VARCHAR(50) NOT NULL,
ssn CHAR(13) UNIQUE, -- 후보키였지만 선택받지 못함
phone VARCHAR(15),
department VARCHAR(30)
);
2.4 Alternate Key (대체키)
정의: 후보키 중에서 Primary Key로 선택받지 못한 나머지 키들
특징:
- Primary Key의 대안이 될 수 있는 키
- UNIQUE 제약조건으로 구현됨
- NULL 값 허용 가능 (UNIQUE 제약조건 특성)
예시:
-- 위 학생 테이블에서
-- student_id: Primary Key
-- ssn: Alternate Key (UNIQUE 제약조건으로 구현)
INSERT INTO Student VALUES ('2023001', '김철수', '9901011234567', '010-1234-5678', 'CS');
-- ssn에 같은 값 입력 시도하면 오류 발생
2.5 Composite Key (복합키)
정의: 둘 이상의 속성을 결합하여 만든 키
사용 상황:
- 단일 속성으로는 유일성을 보장할 수 없을 때
- 다대다(M:N) 관계의 중간 테이블에서 자주 사용
예시:
-- 수강 테이블 (학생과 과목의 다대다 관계)
CREATE TABLE Enrollment (
student_id VARCHAR(10),
course_id VARCHAR(10),
semester VARCHAR(10),
grade CHAR(2),
PRIMARY KEY (student_id, course_id, semester) -- 복합키
);
-- 같은 학생이 같은 학기에 같은 과목을 중복 수강할 수 없음
2.6 Foreign Key (외래키/참조키)
정의: 다른 테이블의 Primary Key를 참조하는 키
목적:
- 테이블 간의 관계 설정
- 참조 무결성(Referential Integrity) 유지
제약조건:
- 참조되는 테이블의 Primary Key 값만 가질 수 있음
- NULL 값 허용 가능
- 참조되는 레코드가 삭제될 때의 동작 정의 필요
예시:
-- 부서 테이블
CREATE TABLE Department (
dept_id VARCHAR(10) PRIMARY KEY,
dept_name VARCHAR(50)
);
-- 직원 테이블
CREATE TABLE Employee (
emp_id VARCHAR(10) PRIMARY KEY,
emp_name VARCHAR(50),
dept_id VARCHAR(10),
FOREIGN KEY (dept_id) REFERENCES Department(dept_id)
ON DELETE SET NULL
ON UPDATE CASCADE
);
Foreign Key 옵션:
- ON DELETE CASCADE: 참조되는 레코드 삭제 시 참조하는 레코드도 삭제
- ON DELETE SET NULL: 참조되는 레코드 삭제 시 Foreign Key를 NULL로 설정
- ON DELETE RESTRICT: 참조하는 레코드가 있으면 삭제 불가
- ON UPDATE CASCADE: 참조되는 키 값 변경 시 참조하는 키 값도 자동 변경
3. 실제 사례로 보는 KEY 활용
3.1 온라인 쇼핑몰 데이터베이스
-- 고객 테이블
CREATE TABLE Customer (
customer_id INT AUTO_INCREMENT PRIMARY KEY, -- 기본키 (인조키)
email VARCHAR(100) UNIQUE, -- 대체키
phone VARCHAR(15) UNIQUE, -- 대체키
name VARCHAR(50),
address TEXT
);
-- 상품 테이블
CREATE TABLE Product (
product_id VARCHAR(20) PRIMARY KEY, -- 기본키
product_name VARCHAR(100),
category_id INT,
price DECIMAL(10,2),
FOREIGN KEY (category_id) REFERENCES Category(category_id)
);
-- 주문 테이블
CREATE TABLE Orders (
order_id VARCHAR(20) PRIMARY KEY, -- 기본키
customer_id INT,
order_date DATETIME,
total_amount DECIMAL(12,2),
FOREIGN KEY (customer_id) REFERENCES Customer(customer_id)
);
-- 주문상세 테이블
CREATE TABLE OrderDetail (
order_id VARCHAR(20),
product_id VARCHAR(20),
quantity INT,
unit_price DECIMAL(10,2),
PRIMARY KEY (order_id, product_id), -- 복합키
FOREIGN KEY (order_id) REFERENCES Orders(order_id),
FOREIGN KEY (product_id) REFERENCES Product(product_id)
);
3.2 학교 관리 시스템
-- 학생 테이블
CREATE TABLE Student (
student_id VARCHAR(10) PRIMARY KEY, -- 기본키
ssn CHAR(13) UNIQUE, -- 대체키
name VARCHAR(50),
birth_date DATE,
department_id VARCHAR(10),
FOREIGN KEY (department_id) REFERENCES Department(department_id)
);
-- 과목 테이블
CREATE TABLE Course (
course_id VARCHAR(10) PRIMARY KEY, -- 기본키
course_name VARCHAR(100),
credits INT,
department_id VARCHAR(10),
FOREIGN KEY (department_id) REFERENCES Department(department_id)
);
-- 수강신청 테이블
CREATE TABLE Enrollment (
student_id VARCHAR(10),
course_id VARCHAR(10),
year INT,
semester INT,
grade CHAR(2),
PRIMARY KEY (student_id, course_id, year, semester), -- 복합키
FOREIGN KEY (student_id) REFERENCES Student(student_id),
FOREIGN KEY (course_id) REFERENCES Course(course_id)
);
4. KEY 설계 시 고려사항
4.1 Primary Key 선택 기준
자연키 vs 인조키:
자연키 (Natural Key):
- 비즈니스적으로 의미 있는 실제 데이터
- 예: 주민번호, 사원번호, 제품코드
- 장점: 의미가 명확, 다른 시스템과 연동 용이
- 단점: 변경 가능성, 복잡성, 개인정보 보호 문제
인조키 (Surrogate Key):
- 시스템에서 인위적으로 생성한 키
- 예: AUTO_INCREMENT, SEQUENCE, UUID
- 장점: 안정성, 단순성, 성능 우수
- 단점: 비즈니스적 의미 없음, 추가 저장공간 필요
4.2 권장 사항
단순한 인조키 사용 권장
CREATE TABLE Customer ( id INT AUTO_INCREMENT PRIMARY KEY, -- 권장 customer_code VARCHAR(20) UNIQUE, -- 비즈니스키는 별도 관리 name VARCHAR(50) );복합키는 최소한으로 사용
-- 권장하지 않음 PRIMARY KEY (customer_name, phone, address) -- 권장 id INT AUTO_INCREMENT PRIMARY KEYForeign Key 제약조건 적극 활용
FOREIGN KEY (customer_id) REFERENCES Customer(id) ON DELETE RESTRICT -- 데이터 무결성 보장 ON UPDATE CASCADE
5. KEY와 성능
5.1 인덱스와의 관계
- Primary Key: 자동으로 Clustered Index 생성
- Foreign Key: 성능을 위해 별도 인덱스 생성 권장
- Unique Key: 자동으로 Unique Index 생성
5.2 성능 최적화 팁
-- Foreign Key에 인덱스 생성
CREATE INDEX idx_employee_dept_id ON Employee(dept_id);
-- 복합 인덱스 활용
CREATE INDEX idx_enrollment_student_semester
ON Enrollment(student_id, year, semester);
-- 쿼리 성능 향상
SELECT * FROM Employee WHERE dept_id = 'CS001'; -- 인덱스 활용
6. 흔한 실수와 해결방법
6.1 잘못된 Primary Key 선택
-- 잘못된 예: 변경 가능한 값을 Primary Key로 사용
CREATE TABLE Employee (
emp_name VARCHAR(50) PRIMARY KEY, -- ❌ 동명이인 가능
department VARCHAR(30)
);
-- 올바른 예
CREATE TABLE Employee (
emp_id INT AUTO_INCREMENT PRIMARY KEY, -- ✅
emp_name VARCHAR(50),
department VARCHAR(30)
);
6.2 Foreign Key 제약조건 누락
-- 문제가 될 수 있는 설계
CREATE TABLE Order_Item (
order_id INT,
product_id INT,
quantity INT
-- Foreign Key 제약조건 없음 → 참조 무결성 위험
);
-- 개선된 설계
CREATE TABLE Order_Item (
order_id INT,
product_id INT,
quantity INT,
FOREIGN KEY (order_id) REFERENCES Orders(order_id),
FOREIGN KEY (product_id) REFERENCES Product(product_id)
);
6.3 복합키 오남용
-- 너무 복잡한 복합키
CREATE TABLE Transaction (
customer_name VARCHAR(50),
product_name VARCHAR(100),
transaction_date DATETIME,
store_location VARCHAR(100),
amount DECIMAL(10,2),
PRIMARY KEY (customer_name, product_name, transaction_date, store_location)
);
-- 개선: 단순한 인조키 사용
CREATE TABLE Transaction (
transaction_id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT,
product_id INT,
transaction_date DATETIME,
store_id INT,
amount DECIMAL(10,2),
FOREIGN KEY (customer_id) REFERENCES Customer(customer_id),
FOREIGN KEY (product_id) REFERENCES Product(product_id),
FOREIGN KEY (store_id) REFERENCES Store(store_id)
);
7. 정리
KEY의 핵심 포인트
- Super Key → 모든 가능한 식별자 조합
- Candidate Key → 최소한의 속성으로 구성된 식별자
- Primary Key → 선택된 메인 식별자 (NOT NULL, UNIQUE)
- Alternate Key → 선택받지 못한 후보키들
- Composite Key → 여러 속성을 결합한 키
- Foreign Key → 다른 테이블을 참조하는 키
설계 원칙
- 단순함이 최고: 가능하면 단일 컬럼의 인조키 사용
- 안정성 우선: 자주 변하지 않는 값을 키로 선택
- 무결성 보장: Foreign Key 제약조건 적극 활용
- 성능 고려: 적절한 인덱스 설계
'DB' 카테고리의 다른 글
| MSSQL 인덱스의 INCLUDE, 이거 모르면 인덱스를 반만 쓰는 거다 (0) | 2026.05.19 |
|---|---|
| PostgreSQL, 왜 다들 Postgres 쓰라고 하는지 이제 알겠다 (0) | 2026.05.12 |
| SQL Server PIVOT과 UNPIVOT 완벽 정리 (0) | 2026.05.11 |
| [DB] 트랜잭션 완전 정리 (0) | 2025.09.23 |