[[PageOutline]] = Mroonga = https://mroonga.org/docs/ 일본에서 ムルンガ라고 하므로 무룽가라고 발음하면 될 듯 하다. MariaDB가 기본 제공하는 Full-Text 검색 엔진은 구분자 기준 색인을 하기 때문에 띄어쓰기가 잘못된 경우는 검색하지 못한다. 특히나 띄어쓰기 없이 조사를 붙이거나 합성어를 붙여쓰는 경우가 많은 한국어의 특징에 맞지 않아 잘 안쓴다. Mroonga는 N-Gram 색인을 지원하기 때문에 경우에 따라서 한국어에도 유용하게 사용할 수 있는 Full-Text 검색 엔진이다. N-Gram 색인이란 N개의 글자만큼 무조건 잘라서 색인을 만드는 방법이다. N-Gram 색인을 하면 '아이폰'으로 검색했을 때 '애플아이폰'이라고 되어 있는 텍스트도 검색할 수 있다. == 설치 == RHEL 8의 기본 배포본은 Mroonga를 지원하지 않는다. 굳이 컴파일해서 설치하느니 ["MariaDB 설치#MariaDB사이트패키지" MariaDB 사이트에서 제공하는 MariaDB 패키지를 설치]하는 것이 나아 보인다. MariaDB 사이트에서 설치했다면 다음과 같이 Mroonga 엔진을 이용할 수 있다. {{{ [mariadb] ... plugin_load_add=ha_mroonga ... }}} MariaDB 설정 파일에 지정하지 않고 다음과 깉은 SQL문을 실행해도 된다. {{{ INSTALL SONAME 'ha_mroonga'; }}} SHOW ENGINES 명령을 내리면 제대로 Mroonga 검색 엔진이 설치되어 있는지를 확인할 수 있다. == 예제 입력 == {{{ -- MariaDB 기본 Full-Text 검색 엔진 create or replace table fulltext_test (apt_name varchar(100) not null primary key, FULLTEXT(apt_name)) ENGINE=INNODB; insert into fulltext_test (apt_name) values ('KCC 스위첸 웰츠타워'); insert into fulltext_test (apt_name) values ('스위트 스위첸 웰츠타워'); insert into fulltext_test (apt_name) values ('KCC 웰츠타워'); -- Mroonga create or replace table mroonga_test (apt_name varchar(100) not null primary key, FULLTEXT(apt_name)) ENGINE=MROONGA; insert into mroonga_test (apt_name) values ('KCC 스위첸 웰츠타워'); insert into mroonga_test (apt_name) values ('스위트 스위첸 웰츠타워'); insert into mroonga_test (apt_name) values ('KCC 웰츠타워'); }}} 다음과 같이 여러 컬럼을 합쳐서 FULLTEXT 인덱스를 생성할 수도 있다. {{{ create or replace table mroonga_test (apt_name varchar(100) not null primary key, address varchar(100) not null, FULLTEXT(apt_name,address)) ENGINE=MROONGA; }}} == 검색 방법 == {{{ -- MariaDB의 기본 Full-Text 검색 엔진은 '타워'라고 검색하면 검색 결과가 나오지 않는다. select * from fulltext_test where MATCH(apt_name) AGAINST('타워'); select * from mroonga_test where MATCH(apt_name) AGAINST('타워'); -- 둘다 대소문자 구분을 하지 않는다. select * from fulltext_test where MATCH(apt_name) AGAINST('kcc'); select * from mroonga_test where MATCH(apt_name) AGAINST('kcc'); -- 유사어도 검색한다. select * from fulltext_test where MATCH(apt_name) AGAINST('스위스'); select * from mroonga_test where MATCH(apt_name) AGAINST('스위스'); }}} 여러 컬럼을 합쳐서 FULLTEXT 인덱스를 생성한 경우에는 MATCH에서도 동일한 컬럼을 지정해줘야 한다. {{{ select * from mroonga_test where MATCH(apt_name,address) AGAINST('스위스'); }}} == 정렬 == 일치하는 정도(유사도 점수)가 높은 것이 먼저 나오길 바란다면 다음과 같이 한다. {{{ select *, MATCH(apt_name) AGAINST('스위스') as score from mroonga_test where MATCH(apt_name) AGAINST('스위스') ORDER BY score DESC; }}} == BOOLEAN MODE == Mroonga 스토리지 엔진의 기본 검색 모드는 NATURAL LANGUAGE MODE다. 그러나 BOOLEAN MODE가 웹 검색 엔진의 사용법과 비슷해 더 친숙하게 검색할 수 있다. 단, 유사어 검색은 BOOLEAN MODE에서 지원하지 않는다. {{{ select * from mroonga_test where MATCH(apt_name) AGAINST('스위스'); select * from mroonga_test where MATCH(apt_name) AGAINST('스위스' IN BOOLEAN MODE); }}} === 검색어에 특별한 표시가 없을 때 === BOOLEAN MODE에서 특별한 표시 없이 검색어 두 개를 나열하면 OR 검색이 된다. 예를 들어 '스위스'이나 '타워' 둘 중 하나가 있는 데이터를 검색하려면 다음과 같다. {{{ select * from mroonga_test where MATCH(apt_name) AGAINST('스위스 타워' IN BOOLEAN MODE); }}} NATURAL LANGUAGE MODE에서는 검색어 두 개를 나열하면 OR가 아니다. {{{ select * from mroonga_test where MATCH(apt_name) AGAINST('스위스 타워'); }}} 1. 먼저 '스위', '위스', '스위스', '타워' 이렇게 네 개의 토큰으로 검색어를 분할한다. 2. 일치하지 않는 토큰을 제거한다. 여기서는 '위스', '스위스' 두 개의 토큰이 제거된다. 3. 토큰별 가중치를 구한다. 토큰이 포함된 레코드의 갯수가 적은 것이 가중치가 높다. '스위'가 두 레코드와 일치하고 '타워'가 세 레코드와 일치하므로 '스위'가 가중치가 높다. 4. 상위 N개의 토큰을 구한다. 이 때 N은 토큰 갯수/8 + 1 이 되는데, 여기서는 2/8 + 1, 약 1이므로 상위 한 개의 토큰만 구하게 된다. 따라서 '타워'는 토큰에서 배제된다. 5. 레코드 내에서 토근이 많이 나온 횟수 기준으로 유사도 점수를 구한다. '스위'가 두 번 나온 '스위트 스위첸 웰츠타워'가 유사도 점수가 높다. 따라서 유사도 점수로 정렬하면 제일 먼저 나온다. === +와 - === + 표시는 반드시 있어야 하는 검색어 앞에, - 표시는 없어야 하는 검색어 앞에 적어준다. {{{ select * from mroonga_test where MATCH(apt_name) AGAINST('+스위첸 +타워' IN BOOLEAN MODE); select * from mroonga_test where MATCH(apt_name) AGAINST('-스위첸' IN BOOLEAN MODE); select * from mroonga_test where MATCH(apt_name) AGAINST('-스위첸 +타워' IN BOOLEAN MODE); }}} - '스위트'는 없고 - '스위첸'이나 '센트럴' 중 하나는 반드시 있는 데이터를 검색한다면 {{{ select * from mroonga_test where MATCH(apt_name) AGAINST('-스위트 +(스위첸 센트럴)' IN BOOLEAN MODE); }}} === 정확한 구문 === 두 검색어의 OR 검색이 아니라 전체를 한 검색어로 보려면 겹따옴표를 쓴다. {{{ select * from mroonga_test where MATCH(apt_name) AGAINST('"웰츠타워 스위첸"' IN BOOLEAN MODE); }}} == tokenizer == Mroonga는 검색 효율성을 높이기 위해 특정 형태로 텍스트를 분할하여 인덱싱한다. 이 때 인덱싱하는 단위를 토큰이라고 하고, 텍스트를 토큰으로 분할하는 것을 tokenizer라고 한다. CREATE TABLE 명령문에서 tokenizer를 주석으로 지정해서 원하는 tokenizer를 설정할 수 있다. {{{ -- 테스트 테이블 생성 create or replace table Off (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "off"') ENGINE=MROONGA; create or replace table Bigram (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigram"') ENGINE=MROONGA; create or replace table BigramIgnoreBlank (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigramIgnoreBlank"') ENGINE=MROONGA; create or replace table BigramSplitSymbol (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigramSplitSymbol"') ENGINE=MROONGA; create or replace table BigramSplitSymbolAlpha (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigramSplitSymbolAlpha"') ENGINE=MROONGA; create or replace table BigramIgnoreBlankSplitSymbol (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigramIgnoreBlankSplitSymbol"') ENGINE=MROONGA; create or replace table BigramIgnoreBlankSplitSymbolAlpha (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigramIgnoreBlankSplitSymbolAlpha"') ENGINE=MROONGA; create or replace table BigramIgnoreBlankSplitSymbolAlphaDigit (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenBigramIgnoreBlankSplitSymbolAlphaDigit"') ENGINE=MROONGA; create or replace table Delimit (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenDelimit"') ENGINE=MROONGA; create or replace table DelimitNull (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenDelimitNull"') ENGINE=MROONGA; create or replace table Trigram (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenTrigram"') ENGINE=MROONGA; create or replace table Unigram (txt varchar(100) not null primary key, FULLTEXT(txt) COMMENT 'tokenizer "TokenUnigram"') ENGINE=MROONGA; }}} 다음과 같이 컬럼 별로 다른 tokenizer를 지정할 수도 있다. {{{ create or replace table test (name varchar(100) not null primary key, address varchar(100) not null, address1 varchar(100) not null, FULLTEXT(name) COMMENT 'tokenizer "TokenBigramIgnoreBlank"', FULLTEXT(address, address1) COMMENT 'tokenizer "TokenBigram"') ENGINE=MROONGA; }}} 다음 tokenizer 설정을 사용할 수 있다. || tokenizer || 설명 || || off ||텍스트를 분할하는 작업을 하지 않는다. || || {{{TokenBigram}}} ||디폴트. 텍스트를 2글자씩 묶어서 분할한다. 예를 들어, '한글 검색'은 '한글', '글_', '_검', '검색', '색', 이렇게 분할한다. 단, 아스키 문자, 숫자, 기호는 두 글짜씩 나누지 않고 공백이나 구두점으로 나눈다.|| || {{{TokenBigramIgnoreBlank}}} ||공백을 없애고 두 글짜씩 묶어서 분할한다. 단, 아스키 문자, 숫자, 기호는 두 글짜씩 나누지 않고 공백이나 구두점으로 나눈다. || || {{{TokenBigramSplitSymbol}}} ||{{{TokenBigram}}}과 같지만 기호도 두 글짜씩 묶어서 분할한다. 단, 아스키 문자, 숫자는 두 글짜씩 나누지 않고 공백이나 구두점으로 나눈다.|| || {{{TokenBigramSplitSymbolAlpha}}} ||{{{TokenBigram}}}과 같지만 아스키 문자와 기호도 두 글짜씩 묶어서 분할한다. 단, 숫자는 두 글짜씩 나누지 않고 공백이나 구두점으로 나눈다.|| || {{{TokenBigramIgnoreBlankSplitSymbol}}} ||{{{TokenBigramIgnoreBlank}}}와 같지만 기호도 두 글짜씩 묶어서 분할한다. 단, 아스키 문자, 숫자는 두 글짜씩 나누지 않고 공백이나 구두점으로 나눈다. || || {{{TokenBigramIgnoreBlankSplitSymbolAlpha}}} ||{{{TokenBigramIgnoreBlank}}}와 같지만 아스키 문자와 기호도 두 글짜씩 묶어서 분할한다. 단, 숫자는 두 글짜씩 나누지 않고 공백이나 구두점으로 나눈다.|| || {{{TokenBigramIgnoreBlankSplitSymbolAlphaDigit}}} ||{{{TokenBigramIgnoreBlank}}}와 같지만 아스키 문자, 숫자, 기호까지 두 글짜씩 묶어서 분할한다. || || {{{TokenDelimit}}} ||공백이나 구두점을 기준으로 토큰을 나눈다. || || {{{TokenDelimitNull}}} ||null characters (\0)로 토큰을 나눈다. || || {{{TokenMecab}}} ||일본어 형태소 분석기를 사용해 토큰을 나눈다. 아쉽게 한국어는 형태소 분석기를 지원하지 않는다. || || {{{TokenTrigram}}} ||연속된 세 글자를 잘라서 토큰으로 한다. 단, 아스키 문자, 숫자, 기호는 세 글짜씩 나누지 않고 공백이나 구두점으로 나눈다.|| || {{{TokenUnigram}}} ||텍스트를 한 글자 단위로 분할하여 저장하고 검색할 때 사용한다. 단, 아스키 문자, 숫자, 기호는 한 글짜씩 나누지 않고 공백이나 구두점으로 나눈다.|| mroonga 명령을 사용하면 각 tokenizer가 어떻게 주어진 텍스트를 토큰으로 분할하는지 테스트할 수 있다. 한글이 안 깨지려면 터미널 창에서 실행해야 한다. {{{ > select MROONGA_COMMAND('tokenize TokenBigram "한글 검색"'); [{"value":"한글","position":0,"force_prefix":false},{"value":"글 ","position":1,"force_prefix":false},{"value":" 검","position":2,"force_prefix":false},{"value":"검색","position":3,"force_prefix":false},{"value":"색","position":4,"force_prefix":false}] }}} {{{NormalizerAuto}}}를 붙여야 실제로 인덱싱하는 토큰을 알 수 있다. {{{ > select MROONGA_COMMAND('tokenize TokenUnigram "한글 검색" NormalizerAuto'); [{"value":"한글","position":0,"force_prefix":false},{"value":"글","position":1,"force_prefix":false},{"value":"검색","position":2,"force_prefix":false},{"value":"색","position":3,"force_prefix":false}] }}} - {{{NormalizerAuto}}}를 붙이기 전과 비교하면 공백이 사라졌고, " 검"이라는 토큰이 사라졌다. - 아마 공백을 제외하면 "검'이라는 토큰만 남는데 "검색'이라는 토큰의 첫 글자가 "검"이므로 "검"만 따로 인덱싱하지 않아도 되므로 생략한 것이 아닌가 한다. {{{NormalizerAuto}}}는 다음 작업을 수행한다. - 대소문자 통일: 모든 텍스트를 소문자로 변환한다. * Hello를 hello로 변환. - 반각/전각 문자 변환: 반각과 전각 문자를 서로 다르게 인식하지 않도록 모두 반각 문자로 변환한다. * abc → abc (전각에서 반각으로 변환) - 조합형 변환: 한국어의 조합형을 유니코드 문자로 변환 * 한글의 조합형 ({{{ᄒ}}}{{{ᅡ}}}{{{ᆫ}}}{{{ᄀ}}}{{{ᅳ}}}{{{ᆯ}}})을 한글로 변환. - 공백 및 특수 문자 처리: 불필요한 공백이나 특수 문자를 제거 {{{--mode GET}}}을 추가하면 인덱싱을 할 때 사용하는 토큰이 아니라 검색어를 추려낼 때 사용하는 토큰을 알 수 있다. {{{ > select MROONGA_COMMAND('tokenize TokenBigram "한글 검색" NormalizerAuto --mode GET'); [{"value":"한글","position":0,"force_prefix":false},{"value":"검색","position":2,"force_prefix":false}] }}} - "한글 검색"이라는 데이터를 저장할 때는 "한글", "글", "검색", "색" 이렇게 네 개의 토큰을 저장한다. 가능한 한 많은 토큰으로 쪼개어 인덱스에 추가하기 위함이다. - "한글 검색"이라는 검색어를 입력하면 인덱스에서 "한글", "검색" 이렇게 두 개의 토큰만 찾는다. 검색 효율과 정확도를 위해 문서 인덱싱 때보다 좀 더 간결하거나 통합된 토큰을 생성하는 경향이 있다. {{{ -- 테스트 데이터 입력 insert into Off values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into Bigram values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into BigramIgnoreBlank values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into BigramSplitSymbol values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into BigramSplitSymbolAlpha values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into BigramIgnoreBlankSplitSymbol values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into BigramIgnoreBlankSplitSymbolAlpha values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into BigramIgnoreBlankSplitSymbolAlphaDigit values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into Delimit values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into DelimitNull values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into Trigram values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); insert into Unigram values ('1000원만!?@#'), ('1000 원 만 !?@#'), ('1 0 0 0 원 만 ! ? @ #'), ('동해물과 백두산이,마르고.닳도록'), ('1000cents!?@#'), ('1000 cents !?@#'); -- 테스트 select txt from Off where match(txt) against('?@#' IN BOOLEAN MODE); }}} == 제한 == Mroonga 스토리지 엔진에서 테이블을 만들 때는 다음과 같은 제한이 있다. 이 제한은 조건에 따라 달라질 수 있다. * 최대 레코드 갯수: 1,073,741,823 (2^30^ - 1) - 일반적인 PRIMARY KEY USING BTREE 테이블일 경우. * 한 키의 최대 크기: 4kB * 키의 크기 총합 : 4GB * 컬럼의 최대 크기: 256GB == Null 사용시 주의 사항 == Mroonga 스토리지 엔진은 특정 값을 자동으로 변환한다. Null은 DATE나 DATETIME 컬럼에서 '1970-01-01 00:00:00'으로 변환해서 저장한다. Null은 문자열 컬럼에서는 ''(빈 문자열)로, 숫자형 컬럼에서는 0으로 변환해서 저장한다. {{{ create or replace table mroonga_conversion ( id int primary key auto_increment, date DATE null, datetime DATETIME null, string VARCHAR(10) null, number INT null ) ENGINE=MROONGA; -- 데이터 입력 insert into mroonga_conversion (id) values (default); -- 결과 확인 select * from mroonga_conversion; }}} == UDF == === mroonga_highlight_html() === 특정 단어를 강조해서 웹에서 보여주고 싶을 때가 있다. 이 때 사용할 수 있는 것이 mroonga_highlight_html() 함수다. mroonga_highlight_html() 함수는 지정한 단어에 ... 태그를 붙여준다. mroonga_highlight_html() 함수는 UDF로 Mroonga에 포함되어 있지만 CREATE FUNCTION 명령으로 함수를 등록해야만 사용할 수 있다. {{{ CREATE FUNCTION mroonga_highlight_html RETURNS STRING SONAME 'ha_mroonga.so'; }}} 구문은 다음과 같다. {{{ mroonga_highlight_html(컬럼이나 텍스트, 키워드1, ..., 키워드N) }}} {{{ select apt_name, MROONGA_HIGHLIGHT_HTML(apt_name, '웰츠', 'KCC') from mroonga_test where MATCH(apt_name) AGAINST ('웰츠'); }}} === mroonga_snippet() === mroonga_highlight_html() 함수의 결과값을 커스터마이징하고 싶은 경우나 검색어와 주변 텍스트를 검색 결과로 추출하고 싶은 경우가 있다. 검색어와 주변 텍스트를 컨텍스트 내 키워드, snippet이라고 한다. mroonga_snippet() 함수는 검색 결과에서 snippet을 가져오는 방법을 지정할 수 있다. mroonga_snippet() 함수는 UDF로 Mroonga에 포함되어 있지만 CREATE FUNCTION 명령으로 함수를 등록해야만 사용할 수 있다. {{{ CREATE FUNCTION mroonga_snippet RETURNS STRING SONAME 'ha_mroonga.so'; }}} 구문은 다음과 같다. {{{ mroonga_snippet(document, max_length, max_count, encoding, skip_leading_spaces, html_escape, snippet_prefix, snippet_suffix, word1, word1_prefix, word1_suffix, ..., [wordN, wordN_prefix, wordN_suffix]) }}} * document: 컬럼이나 텍스트 * max_length: snippet의 최대 길이. 단위 바이트. 대부분의 한글은 3바이트. * max_count: snippet의 최대 갯수 * encoding: document의 collation. utf8_general_ci, euckr_korean_ci, ascii_general_ci, ... * skip_leading_spaces: 1은 맨 앞 공백 제거. 0은 제거하지 않음 * html_escape: 1은 HTML 태그 변환. 0은 변환하지 않음 * snippet_prefix: snippet의 시작. 보통 ... 과 같은 앞 부분이 생략되었다는 텍스트를 많이 쓴다. * snippet_suffix: snippet의 끝. 보통 ... 과 같은 뒷 부분이 생략되었다는 텍스트를 많이 쓴다. * word1: snippet의 키워드 * word1_prefix: word1의 앞에 붙일 텍스트. 보통 강조하는 HTML 태그를 많이 쓴다. * word1_suffix: word1의 끝에 붙일 텍스트. {{{ select apt_name, MROONGA_SNIPPET(apt_name, 22, 3, 'UTF8_GENERAL_CI', 1, 1, '...', '...
', '웰츠', '', '') as snippet from mroonga_test WHERE MATCH(apt_name) AGAINST ('웰츠'); }}} === mroonga_command() === mroonga_command() 함수는 mroonga 명령을 직접 실행할 때 쓴다. MariaDB 명령보다 빠르다. mroonga_command() 함수는 UDF로 Mroonga에 포함되어 있지만 CREATE FUNCTION 명령으로 함수를 등록해야만 사용할 수 있다. {{{ CREATE FUNCTION mroonga_command RETURNS STRING SONAME 'ha_mroonga.so'; }}} mroonga_command() 함수의 예는 다음과 같다. {{{ select MROONGA_COMMAND('reindex mroonga_test'); }}} - reindex 명령만 내리면 현재 데이터베이스의 모든 인덱스가 대상이 된다. == Wrapper 모드 == Mroonga에는 Storage 모드와 wrapper 모드가 있다. * Storage 모드는 Full-Text 검색과 데이터 저장 모두에 Mroonga를 사용한다. 스토리지 엔진의 모든 기능을 Mroonga로 구현하기 때문에 Full-Text 검색이 빠르다. * Wrapper 모드는 Full-Text 검색 기능에만 Mroonga를 사용하고 MyISAM, InnoDB와 같은 다른 기존 스토리지 엔진은 데이터 저장에 사용한다. Mroonga는 SQL을 처리하는 SQL Handler와 기존 스토리지 엔진 사이에서 모든 데이터를 처리한다. Wrapper 모드로 사용할 때는 다음을 주의한다. * 반드시 PK가 있어야 한다. * Null 값을 사용할 수 있다. * InnoDB를 사용하면 트랜잭션을 사용할 수 있다. - 다만, rollback을 할 때 Full-Text 인덱스까지 롤백되지 않기 때문에 잘못된 결과가 나올 수 있다. 그런 경우에는 인덱스를 재생성해야 한다. Wrapper 모드로 테이블을 생성하려면 다음과 같이 COMMENT 항목에서 기존 스토리지 엔진을 적어주면 된다. {{{ create or replace table mroonga_test (apt_name varchar(100) not null primary key, FULLTEXT(apt_name)) ENGINE=MROONGA COMMENT='engine "InnoDB"'; }}} ---- [WikiStart 처음으로]