-
MySQL과 PHP로 검색엔진 만들기Full-Stack/Back-end 2008. 11. 11. 10:12
검색 엔진이란? 검색엔진 쉽게 만들어 보기!
사실 검색엔진을 만드는 것은 쉬운 일이다. 키워드 검색 엔진 구조는 매우 간단하다.
스크립트 언어로 관계형 데이터베이스를 다루는 프로그래밍을 할 줄 안다면 그것 만으로도
만들 수 있다.
그럼 한번 MySQL과 PHP를 사용해 간단히 검색엔진을 구현해보자.
위 그림은 검색엔진에서 사용하는 세가지 기본적인 자료구조의 예이다.
검색엔진의 기본 구조에 대해 들어본 적이 있다면 각각 테이블이 어떤 역할을 하는지
금방 눈치챌 것이다. 그리고 그림 3.의 테이블이 '단어-문서'의 역색인 데이터 베이스라는 것도
알 수 있을 것이다.
겨우 테이블 세 개만으로도 검색엔진을 구현할 수 있는 것이다.검색엔진의 구조를 모르는 사람을 위해 간략히 설명하자면,
"키워드 검색엔진"이란 단어를 입력하면 그 단어를 포함하는 문서의 리스트를 보여주는
소프트웨어이다
. (이 정도는 검색엔진을 사용해 본 사람이라면 알고 있을 것이다.
언젠가 초등학생 사촌 동생에게 물어보니 '단어와 관계있는 문서를 보여주는' 것이라고 대답했었다.
그것이 더 옳은 정의일 것이나 키워드 검색엔진은 좀 더 좁은 의미에서 단어를 포함하는 문서를
찾는 소프트웨어라 정의하자.)
그렇다면 검색엔진은 사용자가 단어를 입력할 때 마다 모든 문서를 읽고 단어가 들어있는지를
찾아 보는 것일까? 그렇게 하면 문서가 많으면 검색이 너무나 느려질 것이다.
그래서 검색엔진은 모든 단어에 대해 그 단어가 등장하는 문서의 리스트를 미리 만들어 놓고
사용자가 단어를 입력하면 그 리스트를 보여준다.여기까지 이해했으면 그림 3.의 테이블이 바로 "단어가 출현하는 문서 리스트"를 저장하는
테이블임을 눈치챌 수 있을 것이다. 이런 테이블을 작성하는 과정을 역색인이라고 부르는데,
본래 "문서가 키인 데이터 속에 단어가 들어있는" 자료의 구조를 "단어가 키인 데이터 안에
문서가 들어있는" 구조로 바꾸기 때문에 역색인이라고 부른다. 하지만 그냥 색인이라고도 말한다.
나머지 두 테이블은 각각 문서와 단어를 숫자로 인코딩하는데 사용하는 테이블이다.
문서를 식별하는 문자열 키가 있을 경우 그 키와 숫자를 매핑하는 테이블을 사용할 수도 잇다.
이렇게 인코딩하면 긴 문자열의 단어와 문서 키 대신에 짧은 정수 키를 사용하여 색인 테이블의
공간 낭비를 줄이고 속도도 높일 수 있다.
색인하기
색인은 검색 엔진 중 제일 단순한 부분이면서 상용 검색엔진을 만들 때 가장 골치아픈 부분이다.
간단하게 생각하면 문서를 띄어쓰기 단위로 잘라 각 단어와 문서 키의 쌍을 저장하면 끝이다.
MySQL에 넣는 다면 그림 3.의 색인 테이블에 "(단어 ID, 문서 ID, 단어의 위치)" 튜플을 넣으면
된다. 단어위치는 띄어쓰기 단위로 단어를 잘라냈을 때 앞에서 부터 몇 번째 단어인지를 가리킨다.
검색하기
MySQL로 색인 테이블을 만들면 검색은 간단히 SQL문 만으로도 가능하다. "best of times"로
이렇게 해서 세개의 단어 best와 of, times가 모두
검색을 한다고 하면,
들어간 문서를 찾아 낼 수 있다.
여기에 검색 품질을 높이자면, "of"와 같이 너무나
흔하게 사용되고 특별한 의미가 없는 단어를
Stop word라 하는데, 이 Stop word를 제외하고
검색을 하면 속도도 높아지고 더 많은 문서를
찾을 수 있을 것이다. 또한 times는 time의 복수형이므로
원형인 time으로 검색한 결과도 관련성이 높은 문서일
것이므로 영어에서는 간단히 -s, -ing, -tive 등을
떼어내는 Word Stemming을 사용해 검색의 품질을
높일 수 있다.
MySQL의 FULLTEXT
MySQL에는 FULLTEXT라는 기능이 있어 한 필드를 검색엔진과 같이 색인해 놓고 키워드를
찾을 수 있다. 오라클 등의 상용 데이터 베이스에도 이러한 기능이 내장되어 있다.
하지만 잘 사용하지 않고 검색엔진을 만드는 이유는 무엇일까? 우선 Stop word같이 품질에
영향을 끼치는 부분은 사용자가 쉽게 튜닝할 수 있어야 하는데 MySQL의 FULLTEXT는 그것이
쉽지 않다. 예를 들어 책 제목 검색을 만들었는데 데이터에 '도서'란 단어가 너무 많이 들어가
이를 제외하고 싶어도 할 수가 없다. 또 다른 이유로 랭킹 기준이 자유롭지 않다. 그리고 가장
치명적인 문제는 영어 이외에 다른 언어는 잘 안된다!는 점이다. 이래 저래 관계형 데이터
베이스는 검색엔진 업계에 위협을 줄 수 있는 존재는 아닌 것 같다.Reference
- Tom Gidden, Desperately seeking susan: How to write your own search engine, php|architect Volume 5 Issue 9, Sep. 2006. p. 19-28.
댓글