InnoDB에서는 전문 검색 인덱스를 만들 때 텍스트를 단어 단위로 토큰화하고, 각 단어에 대해 역색인(Inverted Index)구조를 구성한다.
예를 들어 아래와 같은 단어가 있다고 가정해보자.
위와 같은 문장에서 역색인 구조는 아래와 같이 저장된다.
`applie` - [1]
`pineapple` - [2]
`fruit` - [1, 2]
CREATE TABLE board
(
id INT PRIMARY KEY,
title VARCHAR(255),
context TEXT,
FULLTEXT (title, context) -- 복합 전문 검색 인덱스
);
-- CREATE문으로 생성할 시에는 FULLTEXT를 명시해야 한다.
CREATE FULLTEXT INDEX idx_title_content
ON board (title, content);
SELECT *
FROM board
WHERE MATCH(title, context)
AGAINST('applie' IN NATURAL LANGUAGE MODE);
| 검색 모드 | 설명 |
|---|---|
| NATURAL LANGUAGE MODE | 기본 검색, 단어 빈도의 중요도 기반 |
| BOOLEAN MODE | 연산자(+, -, *, "...", ~) 사용 가늗 |
| WITH QUERY EXPANSION | 연관 단어 자동 확장(불안정하다) |
-- BOOLEAN 검색 예시
SELECT *
FROM board
WHERE MATCH(title, context)
AGAINST('+apple -pineapple' IN BOOLEAN MODE);
| 항목 | 설명 |
|---|---|
| 최소 단어 길이 | 기본적으로 4자 이상이어야 한다 |
| 불용어(Stopword) | 기본적으로 무시되는 단어가 존재한다 |
| 단어 정규화 | 대소문자 구분이 없으며, 특수문자를 제거하고, 중복 단어를 제거하는 등 규칙이 있다 |
[mysqld]
innodb_ft_min_token_size=3
ft_min_word_len=3
이 설정을 my.cnf 또는 my.ini에 바꾼 뒤에 인덱스를 재작성 해야 적용된다.(DROP INDEX -> CREATE INDEX)
이때 두 가지를 설정하는 이유는 innodb_ft_min_token_size가 InnoDB 전용 적용대상이고 ft_min_word_len는 MyISAM 전용 적용대상이기 때문이다. 둘 다 설정해두는 것이 일반적이며, InnoDB를 사용한다면 첫 번째 줄을 적용하는 것이 핵심이다.
| 특징 | 설명 |
|---|---|
| 인덱스 형태 | 역색인 |
| 저장 위치 | Auxiliary 테이블 + 내부 FTS index table |
| 업데이트 시 | INSERT, UPDATE, DELETE 시마다 FTS 테이블을 갱신한다 |
| 검색 방식 | 단어 -> 문서 매핑으로 검색 후 필요 시 정렬한다 |