# 28강. 인덱스 구조
`체인`이라고도 불리는 인덱스는 데이터베이스 객체 중 하나이다. 이 절에서는 인덱스란 무엇이며 그 역할과 구조는 어떻게 이루어지는지 알아본다.

- 테이블에는 인덱스를 작성할 수 있다.

---

## 1. 인덱스
- 인덱스는 테이블에 붙여진 `색인`이라 할 수 있다.
- 인덱스의 역할은 `검색속도의 향상`이다.
- 여기서 `검색`이란 `SELECT` 명령에 `WHERE` 구로 조건을 지정하고 그에 일치하는 행을 찾는 일련의 과정을 말한다.
- 검색은 탐색이라고도 불린다.
- 테이블에 인덱스가 지정되어 있으면 효율적으로 검색할 수 있으므로 `WHERE`로 조건이 지정된 `SELECT` 명령의 처리 속도가 향상된다.
- 책 안에 있는 특정한 부분을 찾고 싶은 경우, 본문을 처음부터 읽어나가기보다 목차나 색인을 참고해서 찾는 편이 효율적이다.
- 인덱스가 바로 이런 역할을 한다.
- 인덱스의 구조도 목차나 색인과 비슷하다. 목차나 색인에 제목-키워드별 페이지 번호가 적혀있듯, 데이터베이스의 인덱스에는 검색 시에 쓰이는 키워드와 대응하는 데이터 행의 장소가 저장되어 있다.
- 인덱스는 테이블과는 별개로 독립된 데이터베이스 객체로 작성된다. 하지만 인덱스만으로는 아무런 의미가 없다.
- 목차밖에 없는 책은 본 적이 없는 것처럼, 인덱스는 테이블에 의존하는 객체라 할 수 있다.
- 대부분의 데이터베이스에서는 테이블을 삭제하면 인덱스도 같이 삭제된다.

---

## 2. 검색에 사용하는 알고리즘
- 대량의 데이터를 효율적으로 검색하는 방법에 관해서는 예전부터 여러 가지로 연구되어 왔다.
- 데이터 탐색이라든가 검색 알고리즘 등이 그에 해당한다.
- 데이터베이스의 인덱스에 쓰이는 대표적인 검색 알고리즘으로는 `이진 트리(binary tree)`가 있으며, 그 다음으로 `해시`가 유명하다.
- 여기서는 이진 트리의 구조를 간단히 설명한다.
- 이진 트리는 정확히 말하면 탐색 방법이라기보다 데이터 구조에 가깝다.
- 탐색 방법으로 말하자면 `이진탐색(binary search)`이 된다. 이때 이진탐색에서 검색하기 쉬운 구조로 한 것이 이진 트리이다.

### 풀 테이블 스캔(full table scan)
- 인덱스가 지정되지 않은 테이블을 검색할 때는 풀 테이블 스캔이라 불리는 검색 방법을 사용한다.
- 처리방법은 단순한데, 테이블에 저장된 모든 값을 처음부터 차례로 조사해나가는 것이다.
- 아주 단순한 검색방법으로, 행이 1,000건 있다면 최대 1,000번 값을 비교한다.

### 이진 탐색(binary search)
- 이진 탐색은 차례로 나열된 집합에 대해 유효한 검색 방법이다.
- 처음부터 순서대로 조사하는 것이 아니고 집합을 반으로 나누어 조사하는 검색방법이다.
- 차례로 나열된 수치의 집합에서 '30'을 검색한다고 가정하자.
- 열 이름을 no라고 하고 `WHERE no = 30`과 같은 조건을 지정한 상태라고 하자.
    - `1, 2, 3, 5, 10, 11, 19, 20, 23, 30, 31, 32, 38, 40, 100`
- 이 집합에 15개의 수치 데이터가 있다고 가정하고 여기서 30의 위치를 찾으려 할 때, 이진 탐색에서는 집합의 가운데에서부터 조사하기 시작한다. 현재 가운데 값은 20이다.
- 지금 검색하려고 하는 30이라는 값은 20보다 크다. 수치는 정렬되어 있으므로 가운데를 기준으로 오른쪽에 있을 것이다. 그 오른쪽 부분에서 다시 가운데를 기준으로 잡아 조사한다.
- 오른쪽의 가운데 값은 32이다. 30 < 32 이므로 이번에는 왼쪽에 원하는 수치가 있을 것이다.
- 마침내 30을 찾게 되는데, 이번 경우에는 총 세 번 비교해 목표를 찾을 수 있었다.
- 만약 풀 테이블 스캔으로 했다면 열 번 비교해야 했겠지만, 이진 탐색이라면 3회로 끝나기 때문에 더 효율적이다.
- 지금 사례는 데이터수가 15개에 불과해 풀 테이블 스캔이나 이진 탐색이나 크게 차이가 없을 수 있다.
- 하지만 실제 데이터베이스에는 수만, 수천만 건의 행이 있다.
- 풀 테이블 스캔을 한다면 데이터 수에 비례해 비교횟수도 늘어난다.
- 그에 비해 이진 탐색은 데이터 수가 배가 되어도 비교 횟수는 1회밖에 늘어나지 않는다. 이런 점에서 이진 탐색이 우위에 있는 것이다.

##### 대량의 데이터를 검색할 때는 이진 탐색이 빠르다!

### 이진 트리(binary tree)
- 이진 탐색은 고속으로 검색할 수 있는 탐색 방법이지만 데이터가 미리 정렬되어 있어야 한다.
- 하지만 테이블 내의 행을 언제나 정렬된 상태로 두는 것은 힘든 작업이다.
- 일반적으로는 테이블에 인덱스를 작성하면 테이블 데이터와 별개로 인덱스용 데이터가 저장장치에 만들어진다. 이때 이진 트리라는 데이터 구조로 작성된다.
- 이진 트리의 구조는 다음과 같다(이진 탐색의 예로 사용했던 집합을 그대로 이진 트리로 해보았다).

![이진 트리](https://user-images.githubusercontent.com/68052095/102471914-19165500-4099-11eb-804f-f21e7fbedf2f.png)

- 트리는 `노드(node)`라는 요소로 구성되며 각 노드는 두 개의 가지로 나뉜다.
- 노드의 왼쪽 가지는 작은 값으로, 오른쪽 가지는 큰 값으로 나뉘어져 있다.
- 두 개의 가지로 분기하는 구조라서 `이진 트리`라 불리는 것이다.
- 검색은 이진 트리의 가지를 더듬어 가면서 행해진다.
- 10이라는 값을 검색한다고 가정해보자.
- 이진 탐색에서는 가운데 값부터 검색하기 시작했지만 이진 트리의 경우에는 트리의 루트 노드부터 시작한다.
- 루트 노드는 트리의 맨 위에 있다. 20이라는 값으로 된 루트 노드부터 검색을 시작한다.
- 검색의 진행 방법은 이진 탐색과 거의 비슷하다. 원하는 수치와 비교해서 더 크면 오른쪽 가지를, 작으면 왼쪽의 가지를 조사해 나간다.
- 이진 탐색의 경우는 오른쪽의 가운데, 왼쪽의 가운데 값을 계산해야 하지만, 이진 트리에서는 구조 자체가 검색하기 쉬우므로 가지를 따라 이동하기만 하면 된다.
- 20 > 10 이기 때문에 우선은 왼쪽 가지로 이동한다.
- 다음은 5이다. 5 < 10 이므로 이번에는 오른쪽 가지로 이동한다.
- 11 > 10 이므로 이번에는 왼쪽으로 간다.
- 마침내 10을 찾았다.

---

## 3. 유일성
- 이진 트리의 구조를 살피다 보면, 같은 값을 가지는 노드가 여러 개 있을 때의 결과에 대한 의문이 생길 수 있다.
- 사실 이진 트리에서는 집합 내에 중복하는 값을 가질 수 없다.
- 즉, 노드의 가지는 큰 쪽과 작은 쪽의 두 가지로 나뉘며, 같은 값을 허용하기 위해서는 '같은'이라는 제 3의 가지를 가질 필요가 있다.
- 하지만, 이진 트리에서 '같은 값을 가지는 노드를 여러 개 만들 수 없다'라는 특성은 키에 대하여 유일성을 가지게 할 경우에만 유용하다.
- 그래서 기본키 제약은 이진 트리로 인덱스를 작성하는 데이터베이스가 많은 것 같다.

##### 이진 트리에는 중복하는 값을 등록할 수 없다!

---