# 0. 들어가며
조합 키(Composite Key)는 하나의 열(Column) 대신 두 개 이상의 열을 조합하여 기본 키(Primary Key)로 사용하는 방식입니다. 예를 들어, 학생 번호 + 수업 코드 같은 조합을 활용하면, 각 학생이 여러 개의 수업을 듣더라도 중복되지 않는 유일한 키를 만들 수 있습니다.
# 1. 조합 키(Composite Key)의 개념과 활용 사례
조합 키(Composite Key)는 두 개 이상의 컬럼을 결합하여 유일한 키를 만드는 방식입니다. 기존의 단일 Primary Key(예: id)와 다르게, 여러 개의 컬럼을 묶어 Primary Key를 설정할 수 있습니다.
📌 예제 코드 (MySQL)
CREATE TABLE student_courses (
student_id INT, -- 학생 ID
course_id INT, -- 수업 ID
semester VARCHAR(10),-- 학기 정보
PRIMARY KEY (student_id, course_id, semester) -- 조합 키
);
- 각 학생이 여러 개의 수업을 들을 수 있으므로, student_id만으로는 유일한 값이 될 수 없습니다. 반대로, 같은 수업을 여러 학생이 들을 수도 있으므로 course_id도 유일하지 않기에 student_id + course_id + semester를 조합하여 고유한 식별자로 만들 수 있습니다.
📌 활용 사례
✔ 주문 상세 내역 (Order Details)
- 하나의 주문(order_id)에는 여러 개의 상품이 포함될 수 있음
- 같은 상품(product_id)이 여러 번 주문될 수도 있음
- order_id + product_id를 조합 키로 설정
✔ 출석 기록 (Attendance Records)
- 학생(student_id)이 특정 날짜(date)에 출석했는지 기록
- student_id + date를 조합 키로 설정
✔ 은행 계좌 거래 (Bank Transactions)
- 같은 계좌(account_id)에서 여러 거래(transaction_id) 발생
- account_id + transaction_id를 조합 키로 설정
# 2. 조합 키의 장점과 단점
장점
✔ 데이터 무결성 보장합니다.
- 조합 키를 사용하면 중복 데이터를 방지할 수 있습니
- 예를 들어, 학생이 같은 수업을 여러 번 신청하지 못하도록 제한할 수 있습니
✔ 복합 검색(Composite Query)에 유리
- 조합 키를 사용하면 WHERE 조건에서 두 개 이상의 컬럼을 조합하여 검색할 때 인덱스 검색이 최적화될 수 있습니다.
- 예를 들어, 특정 order_id 내에서 product_id를 검색하는 경우 성능 향상됩니다.
✔ 중복된 단일 키 생성 필요 없음
- Auto Increment ID 없이도 고유한 데이터 구분이 가능합니다
단점
✔ 키 크기가 커짐 → 인덱스 크기 증가
- INT(4바이트) + INT(4바이트) + VARCHAR(10) = 최소 10바이트 이상
- 단일 INT(4바이트) Primary Key보다 더 많은 저장 공간 필요
✔ 외래 키(Foreign Key) 관계가 복잡해짐
- 다른 테이블에서 조합 키를 참조할 때, WHERE 조건이 복잡해질 수 있습니
- 예: student_courses 테이블을 참조하는 다른 테이블이 있을 때, student_id + course_id + semester를 모두 참조해야 합니다.
✔ 검색 속도 저하 가능성
- student_id 또는 course_id 하나만으로 검색하면 INDEX를 완전히 활용하지 못할 수도 있습니다
- 일부 경우에는 단일 키보다 성능이 떨어질 수도 있습니다.
# 3. 특정 상황에서 조합 키가 유리한 이유
조합 키가 적합한 경우
✔ 중복된 데이터 입력을 방지해야 할 때
- 같은 student_id가 같은 course_id를 여러 번 신청하면 안 되는 경우
- 같은 order_id에서 동일한 product_id가 중복되면 안 되는 경우
✔ 자연스러운 키(Natural Key) 사용이 가능할 때
- Auto Increment ID 대신, 이미 존재하는 데이터의 조합으로 유일성을 만들 수 있음
✔ 복합 검색(Composite Query) 최적화가 필요할 때
기존 방식(Auto Increment PK) vs. 조합 키 방식 성능 비교
# Auto Increment 방식
CREATE TABLE order_details (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
product_id INT,
quantity INT,
);
# 조합 키 방식
CREATE TABLE order_details (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id) -- 조합 키
);
- Auto > WHERE order_id = ? AND product_id = ? 검색 시, Auto Increment된 id를 기준으로 검색이 이루어지므로 최적화가 어려울 수 있습니다
- Auto > id가 연속적으로 증가하지만, order_id + product_id는 서로 다른 값이 섞여 있기 때문에 검색 최적화가 어렵습니다.
- 조합키 > PK 자체가 (order_id, product_id)로 구성되므로 WHERE order_id = ? AND product_id = ? 검색 시 인덱스를 바로 활용 가능합니
- 조합키 > 한 번의 인덱스 조회(Index Range Scan)로 바로 필요한 데이터에 접근할 수 있습니다
# 4. 해결 방법
✅ 해결 방법 1: 인덱스 순서 최적화
조합 키의 컬럼 순서가 WHERE 조건과 맞아야 성능이 좋아집니
📌 예제 상황
CREATE TABLE student_courses (
student_id INT,
course_id INT,
semester VARCHAR(10),
PRIMARY KEY (student_id, course_id, semester)
);
- WHERE student_id = ? AND course_id = ? 로 검색하면 인덱스를 효율적으로 사용할 수 있습니다
- 하지만 WHERE semester = ?로 검색하면 INDEX를 활용하지 못할 수도 있습니다
- 그러므로 자주 검색하는 컬럼을 앞쪽에 배치하면 성능이 향상됩니다
✅ 해결 방법 2: 보조 인덱스(Secondary Index) 추가
조합 키가 너무 클 경우, 보조 인덱스를 추가하여 검색 속도를 개선 가능합니다.
📌 예제 상황
CREATE INDEX idx_course ON student_courses (course_id);
- 이렇게 하면 WHERE course_id = ? 검색 시 인덱스를 활용할 수 있습니다
✅ 해결 방법 3: 해싱(HASHING)된 조합 키 사용
조합 키가 너무 길면, 해시(Hash)를 사용하여 짧은 고유 값 생성 가능합니다.
📌 예제 상황
CREATE TABLE student_courses (
id CHAR(32) PRIMARY KEY, -- 해시된 조합 키
student_id INT,
course_id INT,
semester VARCHAR(10)
);
- 이렇게 하면 조합 키 크기를 줄이고, 검색 성능을 최적화할 수 있습니
# 6. 결론
✅ 중복을 방지해야 할 때 (예: 주문 내역, 출석 기록 등) 사용 하는 것이 좋습니다.
✅ 자연스러운 키를 사용할 수 있을 때 (Auto Increment 없이도 유일성을 보장 가능) 사용하는 것이 좋습니다.
✅ 복합 검색(Composite Query)이 많은 경우 성능 최적화가 가능합니다
🔹 PostgreSQL Composite Key 인덱스 공식 문서
📌 https://www.postgresql.org/docs/current/indexes-multicolumn.html
🔹 MySQL 복합 인덱스 최적화 공식 문서
📌 https://dev.mysql.com/doc/refman/8.0/en/multiple-column-indexes.html
🔹 MongoDB 복합 키 인덱싱 설명
📌 https://www.mongodb.com/docs/manual/core/index-compound/
'dev zone > database' 카테고리의 다른 글
[Primary Key 생성 전략] #6. 유니크 정렬 숫자 (Snowflake, TSID 등) (1) | 2025.02.11 |
---|---|
[Primary Key 생성 전략] #5. 유니크 정렬 문자열 (정렬 가능한 랜덤 ID) (0) | 2025.02.11 |
[Primary Key 생성 전략] #3. UUID (전역적으로 유니크한 식별자) (0) | 2025.02.09 |
[Primary Key 생성 전략] #2. DB Auto Increment (자동 증가 번호) (1) | 2025.02.09 |
[Primary Key 생성 전략] #1. Primary Key 생성 전략 왜 중요한가? (1) | 2025.02.09 |