기본적인 정의는 정의는 목차라는 뜻이다. 즉 무언가를 찾을 때 편하게 찾기 위해 인덱스를 사용해 찾는 것처럼 찾고 싶은 내용에 대해 이를 주요 내용이나 페이지를 함께 써놓은 것들을 말한다. DB에서도 마찬가지로 어떤 데이터를 찾을 때 사용하는 목차와 비슷한 느낌으로 사용된다.
인덱스란 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조이다. 쉽게 생각하면 목차(index)라고 생각하면 된다. 책에서 원하는 내용을 찾을 때 목차를 보고 찾으면 더 빠르게 찾는 것처럼 위치를 추가적인 공간을 통해 쉽게 찾을 수 있게하는 자료구조이다.
간단하게 읽는 것은 빨라지지만 갱신(삽입, 삭제, 수정 update)에 대해서는 느려지는 Trade-off 관계에 있다.
삽입이나 수정시에는 해당 인덱스를 다시 정렬해야하고, update와 달리 delete는 기존 인덱스를 삭제하지 않고 '사용하지 않음'처리를 해주기 때문에 update와 delete가 빈번하게 발생하면 실제 데이터에 비해 인덱스가 10배이상 많은 상황도 가능하다.
인덱스의 자료구조에는 해시 테이블과 B+-트리가 있는데 해시 테이블은 (Key,Value)로 데이터를 저장하는 자료구조 중 하나로 빠른 데이터 검색이 필요할 때 유용하다. Key값을 이용해 고유한 index를 생성하여 index에 저장된 값을 꺼내오는 구조이다.
해시 테이블 기반의 DB 인덱스는 (데이터=컬럽의 값, 데이터의 위치)를 (Key, Value)로 사용하여 컬럼의 값으로 생성된 해시를 통해 인덱스를 구현하였다. 해시 테이블의 시간 복잡도는 O(1)이며 매우 빠른 검색을 지원한다.
하지만 DB 인덱스에서 해시 테이블이 사용되는 경우는 제한적인데, 그러한 이유는 해시가 (=) 등호 연산에만 특화되었기 때문이다. 해시 함수는 값이 1이라도 달라지면 완전히 다른 해시 값을 생성하는데, 이러한 특성에 의해 부등호 연산(<,>)이 자주 사용되는 데이터베이스 검색을 위해서는 해시 테이블이 적합하지 않다.
B+Tree는 DB의 인덱스를 위해 자식 노드가 2개 이상인 B-Tree를 개선 시킨 자료구조이다.
데이터베이스의 인덱스 컬럼은 부등호를 이용한 순차 검색 연산이 자주 발생될 수 있다. 이러한 이유로 BTree의 리프노드들을 LinkedList로 연결하여 순차검색을 용이하게 하는 등 BTree를 인덱스에 맞게 최적화 하였따. (몰론 Best Case에 대해 리프노드까지 가지않아도 탐색 가능한 BTree와 달리 무조건 리프노드까지 가야하는 단점이 있다.)
그래서 B+Tree는 O(log2nlog2n)의 시간복잡도를 갖지만 해시테이블보다 인덱싱에 더욱 접합한 자료구조가 되었다.
B+Tree는 즉 리프노드가 실제 데이터이고 이를 링크드 리스트로 연결해 찾은 값을 순서대로 보기 쉽지만 무조건 리프노드까지 가야함.
클러스터형 인덱스는 실제로 트리의 leaf node에 데이터가 정렬되어 있다. 따라서 하나의 테이블에는 하나의 클러스터형 인덱스를 가질 수 있다. (primary key 설정시 자동으로 클러스터형 인덱스 생성)
비클러스터형 인덱스는 실제 정렬된 데이터를 가지는 것이 아니라 leaf node에 해당 데이터의 링크를 가지고 있는 구조이다.
클러스터형 인덱스는 행 데이터를열로 정렬하고, 루트페이지를 만든다. 그리고 클러스터형 인덱스는 루트페이지와 리프 페이지로 구성되며, 리프 페이지는 데이터 그 자체이다. 즉 인덱스가 정렬되며 각 인덱스의 행이 고유하게 페이지로 구성된다. PRIMARY KEY 조건을 사용하면 고유 인덱스가 자동으로 생성되는데 기본적으로 클러스터형 인덱스가 생성된다. 따로 설정을 해야 비클러스터형이된다.
비클러스터형 인덱스는 데이터 페이지를 건들지 않고, 별도의 장소에 인덱스 페이지를 생선한다. 인덱스 페이지의 리프 페이지에 인덱스로 구성한 열을 정렬한 후 위치 포인터를 생성한다. RID 구조 : 파일식별자 + 페이지번호 + 페이지내의 행 번호로 구성된다. 즉 루트페이지에 인덱스로 구성한 열을 정렬하고 데이터 위치 포인터를 생선한다. 그리고 데이터 위치 포인터로 리프 노드를 가리키면 그 안에 페이지 번호 + #오프셋이 기록되어 바로 데이터 위치를 가리킨다. 그리고 이 데이터 위치 포인터는 데이터가 위치한 고유한 값이 된다. 즉 루트노드 -> 인덱스 페이지 -> 데이터 페이지로 인덱스 페이지를 거치게 된다.