키 (Key), 인덱스 (Index)

2025. 5. 27. 13:30·Backend/DB
목차
  1. Key의 종류
  2. 1. Primary Key (기본 키)
  3. 2. 후보 키 (Candidate Key)
  4. 3. 대체 키 (Alternative Key)
  5. 4. 외래 키 (Foreign Key)
  6. 5. 복합 키 (Composite Key)
  7. 6. 슈퍼 키 (Super Key)
  8. 인덱스 (Index)
  9. 예시
  10. 인덱스 구조
  11. 클러스터형 인덱스 (Clustered Index)
  12. 보조 인덱스 (Secondary Index)
  13. 예시
  14. 인덱스 종류
  15. B-Tree?, B+Tree란?
  16. B-Tree
  17. 왜 B-Tree는 빠른가?
  18. B+Tree
728x90

KEY 는 DB에서 레코드를 고유하게 식별하는 데 사용되는 속성 또는 속성들의 집합을 의미

Key의 종류

이름 설명
슈퍼 키 (Super Key) 유일성을 만족하는 키, ex) 학번 + 이름, 주민번
복합 키 (Composite Key) 2개 이상의 속성을 사용한 키
후보 키 (Candidate Key) 유일성과 최소성을 만족하는 키, 기본키가 될 수 있는 후보이므로 후보 키라고 불림
기본 키 (Primary Key) 후보 키에서 선택된 키, NULL값과 중복 허용 X
대체 키 (Surrogate Key) 후보 키 중에서 기본 키로 선택되지 않은 키
외래 키 (Foreign Key) 어떤 테이블 간의 기본 키를 참조하는 속성
테이블 간의 관계를 나타내기 위해 사용

예시) 학생 테이블 

학생ID  이름 이메일 학번 반 번호
1 철수 chulsoo@gmail.com 20231001 3 12
2 영희 younghee@gmail.com 20231002 3 7
3 민수 minsoo@gmail.com 20231003 4 1

1. Primary Key (기본 키)

  • 학생ID는 각 학생을 유일하게 구별할 수 있음
  • 학생ID는 중복될 수 없고 절대 NULL 값을 가질 수 없음
  • 테이블 마다 기본 키는 하나만 설정 가능

= 학생ID가 Primary Key


2. 후보 키 (Candidate Key)

  • 학생ID, 이메일, 학번 모두 각각 학생을 유일하게 식별 가능
  • 따라서 위 3개의 속성은 모두 후보 키가 됨

3. 대체 키 (Alternative Key)

후보 키 중에서 Primary Key가 아닌 것들, 즉 email과 학번이 대체 키


4. 외래 키 (Foreign Key)

성적 테이블

성적ID 학생ID 과목 점수
1 1 수학 90
2 2 영어 85
3 1 과학 88
  • 성적 테이블의 학생ID = 학생 테이블의 학생ID
  • 따라서 성적.학생ID는 학생.학생ID를 참조하는 외래 키임
  • 이를 통해 두 테이블간 관계 설정

5. 복합 키 (Composite Key)

만일 성적 테이블에서 학생ID와 과목이 함께 하나의 PK라면 두 속성을 합쳐서 레코드 구분 가능

즉, 한 학생이 같은 과목 성적을 여러번 기록할 수 없도록 보장


6. 슈퍼 키 (Super Key)

  • 학생 id +email로 유일하게 학생을 식별할 수 있음
  • 유일성을 보장하지만 불필요한 속성이 포함된 경우라 후보 키가 아님

👉 유일성을 만족하는 모든 키 조합이 슈퍼 키


인덱스 (Index)

데이터베이스에서 검색 속도를 빠르게 하기 위해 사용하는 자료 구조

책의 목차나 색인과 같은 역할을 함

-- email 컬럼에 인덱스 생성
CREATE INDEX idx_email ON Users(email);

-- 복합 인덱스 (이름 + 나이)
CREATE INDEX idx_name_age ON Users(name, age);

예시

Users 테이블에 수만 명의 사용자가 있고, email을 기준으로 특정 사용자를 검색한다고 가정

SELECT * FROM Users WHERE email = 'chulsoo@gmail.com';
  • 인덱스가 없으면?
    → 데이터베이스는 전체 테이블을 처음부터 끝까지 하나씩 확인 (Full Table Scan)
    → 느림
  • 인덱스가 있으면?
    → 이메일 컬럼에 인덱스를 생성해두면
    → 마치 책에서 이름순 색인을 찾듯이, 빠르게 해당 이메일 위치로 이동

언제 인덱스를 써야 할까?

  • WHERE 절에 자주 쓰이는 컬럼
  • JOIN 조건에 자주 사용되는 컬럼
  • 정렬(ORDER BY), 그룹(GROUP BY)에 자주 사용되는 컬럼
  • 고유한 값을 자주 검색하는 컬럼 (ex. email, user_id 등)
📌 인덱스 주의 사항
데이터 추가, 수정, 삭제 시 인덱스도 같이 갱신 -> 쓰기 성능 저하
인덱스는 별도의 저장 공간 必
너무 많은 인덱스 사용은 성능 저하와 관리의 복잡성 유발

성능에 영향을 주는 요소

요소  설명
선택도(Selectivity) 해당 컬럼이 얼마나 고유한 값을 가지는가 (고유할수록 성능에 유리)
인덱스 컬럼 순서 복합 인덱스의 경우 조건 순서가 맞지 않으면 미사용
데이터 분포도 너무 같은 값이 많으면 인덱스 효율 ↓
쿼리 형태 LIKE '%abc'처럼 앞이 와일드카드면 인덱스 무효
  • 자주 검색하는 컬럼에 인덱스 부여
  • 조건이 자주 조합되는 컬럼은 복합 인덱스
  • 쓰기 많은 테이블에는 최소한의 인덱스만 유지
  • EXPLAIN을 통해 쿼리 실행 계획을 확인하세요!

인덱스 구조

클러스터형 인덱스 (Clustered Index)

  • 인덱스가 실제 데이터 자체를 정렬해서 저장 (ex. 영어 사전)
  • 테이블 당 1개만 가능 (MySQL은 기본 키에 자동 생성)
  • 데이터 = 인덱스 이므로 디스크 접근을 최소화하여 읽기가 빠름
ex) PRIMARY KEY 인덱스

보조 인덱스 (Secondary Index)

  • 인덱스는 별도로 존재하고, 실제 데이터 위치만 참조
  • 여러 개 생성 가능
  • 읽기 시 추가로 데이터 위치를 따라 가야 함
  • 인덱스 = PK + Row ID 
ex) UNIQUE, 일반 B-Tree 인덱스

예시

  • PRIMARY KEY를 만들면 그 컬럼이 Clustered Index가 됨
  • 나머지 인덱스 (UNIQUE, 일반 INDEX)는 전부 보조 인덱스
CREATE TABLE Users (
  id INT PRIMARY KEY,          -- 클러스터형 인덱스 (기본키)
  email VARCHAR(255),
  name VARCHAR(100),
  INDEX idx_email(email)       -- 보조 인덱스
);

인덱스 종류

종류 설명 사용 예시
B-Tree 인덱스 기본 인덱스. 범위 검색, 정렬에 강함.
대부분의 RDB에서 기본 제공
숫자, 문 자열, 날짜 등 범용 컬럼
B+Tree 인덱스 데이터는 오직 리프 노드에만 저장, 리프 노드끼리 연결됨  ""
Hash 인덱스 해시 테이블 기반. 정확한 값 검색(=)에 빠름. 범위 검색 불가 메모리 기반 NoSQL(DB), Redis 등
Unique 인덱스 중복을 허용하지 않는 인덱스. 고유한 값만 허용 주민번호, 이메일, ID 등
Full-Text 인덱스 텍스트 검색 전용 인덱스. 단어 기준 검색, 유사 검색 등에 사용 게시판, 블로그 검색
Spatial 인덱스 공간(지리 정보, 좌표 등)을 효율적으로 검색하기 위한 인덱스 지도, 위치 기반 서비스
복합 인덱스 여러 컬럼을 묶어 하나의 인덱스로 생성.
조건이 복합적인 쿼리에 유리
WHERE name='홍길동' AND age=30
비트맵 인덱스 값이 적은(저카디널리티) 컬럼에 효과적. 0/1 비트 배열로 관리 성별, 상태값(예/아니오 등)
Clustered 인덱스 인덱스가 데이터 자체를 정렬한 형태
(MySQL InnoDB에서 기본 PK 인덱스)
PK(기본키)에 자동 생성
Non-clustered 인덱스 데이터와는 분리되어 별도로 인덱스만 존재하는 형태 서브 키, 조회 전용 컬럼

B-Tree?, B+Tree란?

MySQL의 DB engine인 InnoDB는 B+Tree로 이루어져 있는데, 이는 B-Tree의 확장 개념임

B-Tree

B-tree의 핵심은 데이터가 정렬된 상태로 유지되어 있음

가장 상단의 노드를 루트 노드, 중간을 브랜치 노드, 맨 아래는 리프 노드라고 칭한다.

B-tree는 Binary search tree와 유사하지만, 한 노드 당 자식 노드가 2개 이상 가능하다. 

key 값을 이용해 찾고자 하는 데이터를 트리 구조를 이용해 찾는 것이다.


왜 B-Tree는 빠른가?

B-tree의 장점 한 가지는 '어떤 값에 대해서도 같은 시간에 결과를 얻을 수 있다'인데, 이를 '균일성'이라고 함

위의 예시에서 리프노드에 있는 값을 찾는 시간은 동일할 것이다.
(트리 높이가 다른 경우, 차이는 있겠지만 O(logN)이라는 시간 복잡도를 가짐)

B-Tree는 균형 트리

균형 트리란 루트 노드부터 리프 노드까지의 거리가 일정한 트리 구조 의미
👉 트리 중에서 특시 성능이 안정화 됨

그러나 B-Tree는 처음 생성 당시는 균형트리지만, 테이블 갱신의 반복을 통해 서서히 균형이 깨지고 성능이 악화됨

어느 정도 자동으로 균형을 회복할 수 있지만,
갱신 빈도가 잦은 테이블에 작성되는 인덱스 같은 경우인덱스 재구성을 통해 트리의 균형을 되찾는 작업 必

풀 스캔이 테이블 크기에 비례하는 형태로 실행 시간이 늘어가는 데 반해
인덱스를 사용하면 실행 시간 저하는 보통 완만한 곡선을 그림


B+Tree

B-Tree의 확장 개념, B-Tree는 Internal 또는 Branch 노드에 key와 data를 담을 수 있음

하지만, B+Tree의 경우, 브랜치 노드에 key만 담아두고, data는 담지 않음
= 오직 리프 노드에만 key와 data를 저장하고, 리프 노드끼리 연결 리스트로 연결 되어 있음

출처: https://blog.jcole.us/2013/01/10/btree-index-structures-in-innodb

InnoDB에서 B+tree는 단순하게 설명한 B+tree보다 더 복잡하게 구현돼 보임

  • 같은 레벨의 노드들끼리는 Double Linked List를 사용
  • 자식 노드로는 Single Linked List로 연결되어있다.

key의 범위마다 찾아가야할 페이지 넘버(포인터)가 있는데, 해당 페이지 넘버를 통해 곧바로 다음 노드로 넘어간다.

리프 노드에 다다랐을 때 디스크에 존재하는 데이터의 주소값을 구할 수 있고, Linked List를 통해 탐색도 가능하다. 

항목  B-Tree  B+Tree
데이터 저장 위치 모든 노드(내부/리프)에 데이터 저장 가능 데이터는 오직 리프(Leaf) 노드에만 저장
리프 노드 연결 연결 안 됨 리프 노드끼리 연결 리스트로 연결 (범위 탐색에 유리)
범위 조회 비효율적 효율적 (리프 노드만 따라가면 됨)
사용성 일반 트리 검색용 DB 인덱스에 최적화됨 (범위 검색, 정렬 등 빠름)

 

728x90
  1. Key의 종류
  2. 1. Primary Key (기본 키)
  3. 2. 후보 키 (Candidate Key)
  4. 3. 대체 키 (Alternative Key)
  5. 4. 외래 키 (Foreign Key)
  6. 5. 복합 키 (Composite Key)
  7. 6. 슈퍼 키 (Super Key)
  8. 인덱스 (Index)
  9. 예시
  10. 인덱스 구조
  11. 클러스터형 인덱스 (Clustered Index)
  12. 보조 인덱스 (Secondary Index)
  13. 예시
  14. 인덱스 종류
  15. B-Tree?, B+Tree란?
  16. B-Tree
  17. 왜 B-Tree는 빠른가?
  18. B+Tree
'Backend/DB' 카테고리의 다른 글
  • DB 정규화, 역정규화, 이상현상
  • 스키마 3계층
  • RDB와 NoSQL 비교
  • SQL 기초
0woy
0woy
Algorithm, CS, Web 등 배운 내용을 기록합니다.
  • 0woy
    0woy dev
    0woy
  • 전체
    오늘
    어제
  • 🌐 LANGUAGE
    • 분류 전체보기 (80)
      • Backend (21)
        • JAVA (7)
        • DB (11)
        • Spring (1)
        • Spring Security (2)
      • Computer Science (22)
        • 네트워크 (9)
        • 운영체제 (5)
        • 보안 (7)
      • Frontend (15)
        • HTML5 (1)
        • CSS (1)
        • JS (4)
        • Vue 3 (9)
      • PS (16)
        • LeetCode (2)
        • Baekjoon (1)
        • Programmers (1)
        • 알고리즘 (12)
      • Dev Trivia (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    shortestpath
    공개키
    비밀키
    Spring
    가용성
    tcp
    트리
    java
    DP
    대칭키
    security
    BFS
    Filter
    set
    https
    Vue3
    JS
    CA
    Props
    속성
    function
    leetcode
    RDB
    JDBC
    그래프
    dfs
    Graph
    PreparedStatement
    javascript
    select
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
0woy
키 (Key), 인덱스 (Index)

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.