본문 바로가기

TIL

"Index가 뭐에요?" 라는 질문에 깨진 기념으로

어려운 개발자 시장에서, 비 전공자 부트캠프 수료생이 들어가는 길은 바늘구멍만큼 작다..

수 많은 서류탈락, 그리고 몇 번의 면접에서 탈락을 겪으면서, 자존감이 떨어질 시점, 한 스타트업에서 스카우트 제의가 왔다.

 

응, 내가? 무슨 자격이 있어서?

 

반갑고 고마운 기분과 동시에, 그 회사 입장에서 나에게 무슨 특별한 무언가가 있다고 느꼈는지 의문이 들기도 했다.

하지만 그 기분도 잠시, 비전공자인 만큼 여때까지 보지 않았던 기술면접을 보게 되었는데, 첫 질문은 "index 가 뭐에요?" 였다. 

 

"어..음, Primary key라던지, 테이블의.. 인스턴스의 고유 id값을.. 정렬같이 한 걸로 알고 있습니다."

 

내 머릿속, 학원에서 대략 배운 것을 끄집어내서 어떻게든 문장을 만들어냈지만,

면접관은 내가 부족하다는 시그널을 계속 보냈고, 아쉽게도 좋은 소식은 받지 못하게 되었다.ㅠㅠ

 

한탄은 여기까지, 그럼, index가 무엇인지 파해쳐보고, 개념에 대해 이해를 해보도록 하자.

 

 

 

테이블을 만들면 index가 자동으로 생기지 않나요?

부끄럽지만 난 이렇게 생각을 했다. 부트캠프 과정 중에 db설계를 할 때, 항상 자동으로 만든 것이 식별자이고

그 식별자 코드는 이런 방식으로 작성을 했다. Customer라는 간단한 고객 테이블을 예시로 들자면, 이렇게...

model Customer {
  id    Int    @id @default(autoincrement()) 
  email String @unique                      
  name  String
}

 

id email name
1 cheerio@naver.com 김연아
2 nanii@gmail.com 차은우
3 plzcoding@gmail.com 박서준

 

그러면 이런 식으로 위에 표처럼 테이블에 레코드가 생성될 것이고, id가 autoincrement를 설정하여 자동으로 올라가는 만큼,

"정렬"로서 기능을 할 것이며, 이것이 index가 아닌가.. 라는게 나의 초보자다운 생각이었다.

 

하지만 index란 여기 테이블에 있는 id나 email 혹은 name column 내 그 자체의 값이 아니다.

위의 데이터는 id값으로 순서가 정렬되어 있다. 그런데 만약 name을 한글 ㄱ-ㅎ 까지 정렬을 별도로 하고 싶다면,

name을 기반으로 또 다른 정렬, 그러니까 (name 기반) index를 생성을 하면 된다.

스크립트로 나타내면 다음과 같다.

-- UTF-8 인코딩 및 한글 정렬 시퀀스 설정
ALTER TABLE Customer CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- name 컬럼에 인덱스 생성
CREATE INDEX idx_name ON Customer (name);

 

여기서 utf8mb4_unicode_ci는 한글 ㄱ-ㅎ까지의 정규식을 나타낸 것이다.

또한 index는 idx_name이라는 이름으로 할당을 하게 되었다.

이렇게 index 순으로 정렬된 가상의 표를 표현하면 아래와 같이 될 것이다.

id email name index_name
1 cheerio@naver.com 김연아 1
3 plzcoding@gmail.com 박서준 2
2 nanii@gmail.com 차은우 3

 

그렇다고.. 실제 index_name이 다음과 같은 숫자로 표현이 되거나, 실제 테이블이 저렇게 바뀌어서 정렬이 되어 저장이 되거나, 별도로 테이블이 생성되어 저장되는 것은 아니다! (만약 그랬다면 db에 또 다른 테이블이 생성되는 거니, 필요없이 차지하는 공간은 상당히 늘어나게 된다)

 

원본 테이블은 하드웨어 db상 기존 순서대로 저장되어 있고, index_name에 별도의 정렬이 레코드마다 표시가 되어 있는 방식이라고 gpt에게 물어보니 그렇다고 하더라...

 

 

 

그럼 왜 특정 column의 값으로 별도의 index를 만드는 걸까?

프로그래밍에서 모든 (확신하지 않지만) 기술은 그 용도가 있기 때문에 만들어진 것이다.

테이블에 있는 데이터를 조회할 때, SELECT나 WHERE 쿼리구문을 사용하여 선별하는 과정을 거친다.

여기서 마치 for문 처럼 데이터를 첫 번째 row에서 마지막 row까지 모두 순회하여 찾아내는 방식을 선택한다면, 데이터가 적을 때라면 모르겠지만, 테이블의 row가 수 십만 단위로 넘어가는 경우라면 시간 지연 현상이 뚜렷하게 나타난다.

 

이럴 경우, 첫 번째에서 마지막까지 모두 순회하는 방식이 아닌, 이분탐색, B Tree와 같은 기법이 사용되어, 시간을 상당히 감축시키는 것이 가능한데, 이러한 기법은 먼저 데이터가 (특정 규칙을 전제로 한) "순서대로 정렬"이 전제되어야 한다.

 

예를 들어, 아래 그림에 있는 B+ Tree라는 탐색 매커니즘을 살펴보자.

만약 Page 6을 찾는다고 가정을 해보자.

간단하게 모든 페이지, 0, 1, 2, ...... ,7 까지 일일이 순회하여 Page 6을 찾을 수 있으나, 나중에 페이지가 방대해지면 이는 시간복잡도가 확 늘어나는 방식이다.

 

첫 번째 꼭데기(node)에서 Page가 3보다 크거나 작음의 유무를 판단해, 클 경우 우측 화살표로 가지치기 하여 내려간다.

두 번째 우측 node에서는 6이상인 숫자인지, 아닌 4이상이라는 조건만 만족하는 지 판별을 하고, 역시 아래 가지롤 내려간다.

이런 방식으로 몇 번의 "가지치기"를 하면 적은 연산으로 원하는 데이터를 탐색할 수 있다.

 

이런 식으로 효율적인 탐색이 일어나려면, Level 0에서 Page가 특정 조건대로 (여기의 경우: 페이지 숫자 크기) 정렬이 되어야 한다.

 

그럼 탐색에 필요한 B Tree는 어떻게 만드냐..?

GPT에 물어보니까, Index를 설정하면 알아서 만들어준다고 한다.

하지만.. 개발자로서 성장하려면 만들어지는 원리도 추후에 터득해야 하지 않을까 싶다.

 

 

 

<제 글이 이해가 되지 않는다면, 제 설명력 부족이니.. 제가 듣고 이해한 코딩애플 영상을 살펴보시길 바란다>

코딩애플 index설명 영상: https://youtu.be/iNvYsGKelYs?si=n9147xFZh8Gl84Es