ZeroBase/CS

ENUM과 SET

Red_Horse 2025. 9. 16. 07:55

ENUM - 단일 선택 타입

 

ENUM은 열에 할당할 수 있는 값의 리스트를 정의하고, 이 리스트 중 하나만 선택하는 단일 선택만이 가능한 타입입니다.

 

내부 저장 방식

값들은 내부적으로 숫자로 저장되지만, 사용자에게는 문자열로 표시됩니다.

-- ENUM 정의 예시
CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    status ENUM('active', 'inactive', 'pending')
);

-- 내부 매핑:
-- 'active'   → 1
-- 'inactive' → 2  
-- 'pending'  → 3
-- (0은 빈 값 또는 잘못된 값에 할당됨)
 
 
 

기본 사용법

-- 정상적인 삽입
INSERT INTO products (name, status) VALUES 
('상품A', 'active'),
('상품B', 'inactive'),
('상품C', 'pending');

-- 에러 발생하는 경우
INSERT INTO products (name, status) VALUES 
('상품D', 'deleted'); -- Error: 정의되지 않은 값

-- 숫자로 직접 삽입 가능 (권장하지 않음)
INSERT INTO products (name, status) VALUES 
('상품E', 1); -- 'active'와 동일
 
 
 

조회 및 정렬

-- 문자열로 조회
SELECT * FROM products WHERE status = 'active';

-- 내부 숫자값으로 정렬 (정의 순서대로)
SELECT * FROM products ORDER BY status;
-- 결과: active(1) → inactive(2) → pending(3) 순서

-- ENUM 값의 숫자 확인
SELECT name, status, status+0 AS status_number 
FROM products;

 

SET - 다중 선택 타입

 

SET은 ENUM과 비슷하지만, 하나의 열에 여러 값을 저장할 수 있다는 점이 다르며, 비트 단위 연산을 할 수 있고 한 번에 여러 개의 조합으로 선택이 가능합니다.

 

내부 저장 방식과 제한

  • 64개의 요소를 넣을 수 있음
  • 비트마스크로 내부 저장
  • 각 요소는 2의 거듭제곱 값을 가짐

 

다중 값 저장

-- 여러 값 동시 저장
INSERT INTO users (name, skills) VALUES 
('개발자A', 'Java,Python'),           -- 1 + 2 = 3
('개발자B', 'JavaScript,C#,Go'),      -- 4 + 8 + 16 = 28
('개발자C', 'Python,JavaScript,Rust'); -- 2 + 4 + 32 = 38

-- 단일 값도 가능
INSERT INTO users (name, skills) VALUES 
('개발자D', 'Java');                  -- 1

-- 빈 값도 가능
INSERT INTO users (name, skills) VALUES 
('개발자E', '');                      -- 0
 

 

SET 조회 및 비트 연산

-- 특정 스킬을 가진 사용자 찾기
SELECT * FROM users WHERE FIND_IN_SET('Python', skills);

-- 여러 스킬 중 하나라도 가진 사용자
SELECT * FROM users WHERE skills & 3; -- Java(1) 또는 Python(2)

-- 특정 스킬 조합을 모두 가진 사용자
SELECT * FROM users WHERE (skills & 6) = 6; -- Python(2) AND JavaScript(4)

-- 비트 연산 예시
SELECT name, skills, skills+0 AS skills_number 
FROM users;
-- 개발자A: Java,Python → 3
-- 개발자B: JavaScript,C#,Go → 28

 

ENUM vs SET

특성 ENUM SET
선택 개수 단일 선택 다중 선택
최대 요소 65,535개 64개
저장 방식 순서 번호 비트마스크
연산 순서 비교 비트 연산

 

-- ENUM 사용 사례: 상태, 등급, 카테고리
CREATE TABLE orders (
    id INT PRIMARY KEY,
    status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled'),
    priority ENUM('low', 'medium', 'high', 'urgent')
);

-- SET 사용 사례: 권한, 태그, 다중 선택 옵션
CREATE TABLE user_permissions (
    user_id INT PRIMARY KEY,
    permissions SET('read', 'write', 'delete', 'admin', 'moderator')
);

CREATE TABLE articles (
    id INT PRIMARY KEY,
    title VARCHAR(200),
    tags SET('tech', 'programming', 'database', 'web', 'mobile', 'ai')
);
 

 

장점

  • 공간적 이점
  • ENUM의 공간 효율성
-- 일반적인 VARCHAR 방식
CREATE TABLE products_varchar (
    status VARCHAR(20) -- 'active', 'inactive', 'pending'
);
-- 각 행마다 최대 20바이트 사용

-- ENUM 방식  
CREATE TABLE products_enum (
    status ENUM('active', 'inactive', 'pending')
);
-- 각 행마다 1바이트만 사용 (3개 값이므로)

-- 공간 절약: 95% 감소 (20바이트 → 1바이트)
 
 
  • SET의 공간 효율성
-- 일반적인 별도 테이블 방식
CREATE TABLE user_skills_normalized (
    user_id INT,
    skill VARCHAR(50),
    PRIMARY KEY(user_id, skill)
);
-- 스킬 하나당 54바이트 (INT 4 + VARCHAR 50)

-- SET 방식
CREATE TABLE users_set (
    id INT,
    skills SET('Java', 'Python', 'JavaScript', 'C#', 'Go', 'Rust')
);
-- 최대 8바이트로 64개 스킬 표현 가능
 
 

단점

  • 스키마 수정의 복잡성
-- 새로운 값 추가가 필요한 경우
-- 기존 ENUM: ('active', 'inactive', 'pending')

-- 새 상태 'archived' 추가하려면 ALTER 필요
ALTER TABLE products 
MODIFY COLUMN status ENUM('active', 'inactive', 'pending', 'archived');

-- 문제점:
-- 1. 테이블 잠금 발생 (대용량 테이블에서 위험)
-- 2. 애플리케이션 코드와 DB 스키마 동기화 필요
-- 3. 배포 시 순서 의존성 발생
 
  • 애플리케이션 수정에 따른 데이터베이스 변경
// C# 애플리케이션 코드 예시
public enum ProductStatus
{
    Active,
    Inactive, 
    Pending,
    Archived // 새로 추가된 상태
}

// 새 enum 값 추가 시:
// 1. C# 코드 수정
// 2. 데이터베이스 스키마 수정 필요
// 3. 기존 데이터 마이그레이션 고려
// 4. 배포 순서 조정 필요
 
 
 
  • 이식성 문제
-- MySQL ENUM/SET은 표준 SQL이 아님
-- PostgreSQL 등 다른 DB로 이전 시 문제 발생

-- 대안: CHECK 제약조건 (표준 SQL)
CREATE TABLE products (
    id INT PRIMARY KEY,
    status VARCHAR(20) CHECK (status IN ('active', 'inactive', 'pending'))
);
 
 
 

'ZeroBase > CS' 카테고리의 다른 글

ERD(Entity Relation Diagram)  (3) 2025.09.21
데이터베이스 관계와 키(Key)  (1) 2025.09.16
힙(Heap)  (0) 2025.09.15
해시테이블(HashTable)  (0) 2025.09.13
Map과 Set  (0) 2025.09.13