CHHB stroy

[DB] 데이터베이스 키(KEY) 종류 정리 본문

DB

[DB] 데이터베이스 키(KEY) 종류 정리

CHHB 2025. 9. 23. 11:17

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로 참조

선택 기준:

  1. 단순성: 속성 개수가 적을수록 좋음
  2. 안정성: 값이 자주 변하지 않을수록 좋음
  3. 의미성: 비즈니스적으로 의미 있는 속성

예시:

-- 학생 테이블
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 권장 사항

  1. 단순한 인조키 사용 권장

    CREATE TABLE Customer (
        id INT AUTO_INCREMENT PRIMARY KEY,  -- 권장
        customer_code VARCHAR(20) UNIQUE,   -- 비즈니스키는 별도 관리
        name VARCHAR(50)
    );
  2. 복합키는 최소한으로 사용

    -- 권장하지 않음
    PRIMARY KEY (customer_name, phone, address)
    
    -- 권장
    id INT AUTO_INCREMENT PRIMARY KEY
  3. Foreign 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의 핵심 포인트

  1. Super Key → 모든 가능한 식별자 조합
  2. Candidate Key → 최소한의 속성으로 구성된 식별자
  3. Primary Key → 선택된 메인 식별자 (NOT NULL, UNIQUE)
  4. Alternate Key → 선택받지 못한 후보키들
  5. Composite Key → 여러 속성을 결합한 키
  6. Foreign Key → 다른 테이블을 참조하는 키

설계 원칙

  • 단순함이 최고: 가능하면 단일 컬럼의 인조키 사용
  • 안정성 우선: 자주 변하지 않는 값을 키로 선택
  • 무결성 보장: Foreign Key 제약조건 적극 활용
  • 성능 고려: 적절한 인덱스 설계