Интернет, компьютеры, софт и прочий Hi-Tech | |||||
Избранные докиМетки (все метки)internet, it, интернет, интернет сеть, информационные технологии, ит, по, программное обеспечение, сайт, софт
Подписаться через RSS2Email.ru
Дополнительномониторы, движок, Битрикс, хостинг, сайты, мобильные, электроника, видеокарта, СКС, AXIS |
SQLite: расширения FTS3 и FTS4
Содержание
ПредисловиеFTS3 и FTS4 — это модули виртуальных таблиц SQLite, которые позволяют пользователям выполнять полнотекстовый поиск на множестве документов. Наиболее общий (и эффективный) способ описать полнотекстовый поиск — следующий: "То, что делают Google, Yahoo и Altavista с документами, находящимися во всемирной сети". Пользователь вводит слово или набор слов, возможно соединённые бинарным оператором или сгруппированные во фразу, и система полнотекстового поиска находит множество документов, которые наилучшим образом соответствуют введенным словам с учетом операторов и группировок, заданных пользователем. Эта статья описывает установку и использование FTS3 и FTS4. FTS1 и FTS2 являются устаревшими модулями полнотекстового поиска для SQLite. Существуют известные проблемы с этими старыми модулями и их использования следует избегать. Часть первоначального кода FTS3 была предоставлена проекту SQLite Скоттом Хессом (Scott Hess) из Google. С тех пор этот модуль разрабатывается и распространяется как часть SQLite. 1. Введение в FTS3 и FTS4Модули расширений FTS3 и FTS4 дают пользователям возможность создавать специальные таблицы с поддержкой полнотекстового индекса (далее — "таблицы FTS"). Полнотекстовый индекс позволяет пользователям эффективно запрашивать записи из базы данных, содержащие одно или более слов (далее — "токены"), даже когда таблица содержит множество больших документов. Например, вставим каждый из 517430 документов "Энроновской коллекции E-Mail" в таблицу FTS и в обычную таблицу SQLite, созданные следующим скриптом SQL: CREATE VIRTUAL TABLE enrondata1 USING fts3(content TEXT); /* таблица FTS3 */ CREATE TABLE enrondata2(content TEXT); /* обычная таблица */ Затем выполним следующие два запроса для поиска в базе данных числа документов (351), содержащих слово "linux". В проведённом авторами эксперименте на одном и том же настольном компьютере запрос к таблице FTS отработал примерно за 0.03 секунды против 22.5 секунд для обычной таблицы: SELECT count(*) FROM enrondata1 WHERE content MATCH 'linux'; /* 0.03 секунды */ SELECT count(*) FROM enrondata2 WHERE content LIKE '%linux%'; /* 22.5 секунды */ Конечно, два вышеприведённых запроса в целом неэквивалентны. Например, запрос
1.1. Различия между FTS3 и FTS4FTS3 и FTS4 почти идентичны. Они делят друг с другом большую часть своего кода и имеют одинаковые интерфейсы. Но имеют следующие различия:
FTS4 является усовершенствованным FTS3. FTS3 доступен в SQLite начиная с версии 3.5.0, вышедшей 04.09.2007. Усовершенствованный FTS4 был добавлен в SQLite версии 3.7.4 от 08.12.2010. Какой из модулей, FTS3 или FTS4, следует использовать в своем приложении?
FTS4 иногда работает значительно быстрее чем FTS3. Для некоторых запросов даже
на несколько порядков быстрее, хотя в общем случае производительность этих двух
модулей аналогична. Кроме того FTS4 поддерживает усовершенствованный вывод для
matchinfo(), который может быть использован для ранжирования результатов
поиска с помощью оператора
MATCH. С другой стороны, при отсутствии директивы
Для новых приложений рекомендуется использовать FTS4. Если же важна совместимость со старыми версиями SQLite, то FTS3 должен работать достаточно хорошо. 1.2. Создание и удаление таблиц FTSПодобно другим типам виртуальных таблиц, новые таблицы FTS создаются с
помощью запроса Если имена столбцов таблицы FTS явно перечислены в выражении -- Создаем таблицу FTS с названием "data" и одним столбцом — "content": CREATE VIRTUAL TABLE data USING fts3(); -- Создаем таблицу FTS с названием "pages" и тремя столбцами: CREATE VIRTUAL TABLE pages USING fts4(title, keywords, body); -- Создаем таблицу FTS с названием "mail" и двумя столбцами. -- Для каждого столбца указываем тип данных и ограничения, -- которые полностью игнорируются FTS и SQLite. CREATE VIRTUAL TABLE mail USING fts3( subject VARCHAR(256) NOT NULL, body TEXT CHECK(length(body)<10240) ); Так же как список столбцов, в качестве аргументов модуля в запросе
"CREATE VIRTUAL TABLE" при создании таблицы FTS можно указать используемый
токенайзер.
Это делается указанием строки в форме
-- Создаем таблицу FTS с названием "papers" и двумя столбцами, -- которые используют токенайзер "porter". CREATE VIRTUAL TABLE papers USING fts3(author, document, tokenize=porter); -- Создаем таблицу FTS с единственным столбцом — "content", -- который использует токенайзер "simple". CREATE VIRTUAL TABLE data USING fts4(tokenize=simple); -- Создаем таблицу FTS с двумя столбцами, которые используют токенайзер -- "icu". Спецификатор "en_AU" указывает на локализацию токенайзера. CREATE VIRTUAL TABLE names USING fts3(a, b, tokenize=icu en_AU); Если в запросе "CREATE VIRTUAL TABLE" указан модуль FTS4 (а не FTS3), то
можно указать также специальную директиву -- Создаем таблицу FTS4 экономя дисковое пространство. CREATE VIRTUAL TABLE papers USING fts4(author, document, matchinfo=fts3); При использовании FTS4 указание имени столбца, содержащего символ "=" и не
совпадающего с директивами -- Ошибка. FTS4 не понимает директиву "xyz=abc". CREATE VIRTUAL TABLE papers USING fts4(author, document, xyz=abc); -- Создаем таблицу FTS3 с тремя столбцами — -- "author", "document" и "xyz". CREATE VIRTUAL TABLE papers USING fts3(author, document, xyz=abc); -- Ошибка. FTS4 не разрешает несколько директив "tokenize=*" CREATE VIRTUAL TABLE papers USING fts4(tokenize=porter, tokenize=simple); -- Создаем таблицу FTS3 с единственным столбцом под названием "tokenize". -- Таблица использует токенайзер "porter". CREATE VIRTUAL TABLE papers USING fts3(tokenize=porter, tokenize=simple); -- Ошибка. Нельзя создавать два столбца с названием "tokenize". CREATE VIRTUAL TABLE papers USING fts3(tokenize=porter, tokenize=simple, tokenize=icu); Таблицы FTS могут удаляться из базы данных с помощью обычного запроса
-- Создаем и сразу уничтожаем таблицу FTS4. CREATE VIRTUAL TABLE data USING fts4(); DROP TABLE data; 1.3. Заполнение таблиц FTSТаблицы FTS заполняются и редактируются с помощью запросов
Вместе с заданными пользователем столбцами (или со столбцом "content", если в
выражении Существует одно тонкое отличие "docid" от обычных алиасов SQLite для столбца
-- Создать таблицу FTS
CREATE VIRTUAL TABLE pages USING fts4(title, body);
-- Вставляем строку с указаннием значения docid.
INSERT INTO pages(docid, title, body) VALUES(53, 'Главная', 'SQLite — это...');
-- Вставляем строку и позволяем FTS назначить значение docid с
-- использованием того же алгоритма, который SQLite применяет для обычных
-- таблиц. В этом случае новый docid будет иметь значение 54, т.е. на единицу
-- больше, чем наибольший docid, существующий в таблице на момент запроса.
INSERT INTO pages(title, body) VALUES('Скачать', 'Весь исходный код SQLite...');
-- Изменяем title только что добавленной строки.
UPDATE pages SET title = 'Скачать SQLite' WHERE rowid = 54;
-- Удаляем все содержимое таблицы.
DELETE FROM pages;
-- Следующий код приведет к ошибке. Для таблиц FTS нельзя указывать
-- различные не-NULL значения для обоих полей — rowid и docid.
INSERT INTO pages(rowid, docid, title, body) VALUES(1, 2, 'Заголовок', 'Документ');
Для поддержки полнотекстового поиска FTS создает инвертированный индекс,
которые назначает каждому уникальному терму или слову, которое встречается в
наборе данных, карту его расположения в содержимом таблицы. Если интересно,
можете ознакомиться с полным описанием
структуры
данных, используемой для хранения этого индекса в файле базы данных.
Особенностью этой структуры данных является то, что база данных может содержать
не одно индексное b-дерево, а несколько различных b-деревьев, которые постепенно
сливаются по мере вставки, редактирования и удаления строк. Эта техника улучшает
производительность при записи в таблицу FTS, но приводит к некоторым накладкам
при использовании индекса в полнотекстовых запросах. Выполнение SQL-запроса в
форме Вот так, например, оптимизируется полнотекстовый индекс для FTS-таблицы под названием "docs": -- Оптимизация внутренней структуры FTS-таблицы "docs".
INSERT INTO docs(docs) VALUES('optimize');
Вышеприведённый запрос может показаться синтаксически неправильным. Разъяснения можно прочитать в следующем разделе "Простые запросы FTS". Существует также другой, нежелательный метод вызова операции оптимизации с
помощью запроса 1.4. Простейшие FTS-запросыКак и для всех других таблиц SQLite, как виртуальных, так и обычных, данные
из таблиц FTS получаются с помощью запросов Таблицы FTS могут эффективно запрашиваться с использованием выражений
Если в запросе нельзя использовать ни одну из этих стратегий, то запрос на таблице FTS будет выполнен с использованием полного сканирования содержимого таблицы. Если таблица содержит большое количество данных, это может оказаться непрактичным подходом. В первом примере этого руководства демонстрировалось, что на современном ПК линейное сканирование 1.5 ГБ данных выполнялось около 30 секунд. -- В примерах этого блока используется следующая таблица FTS: CREATE VIRTUAL TABLE mail USING fts3(subject, body); -- Быстро. Запрос по rowid. SELECT * FROM mail WHERE rowid = 15; -- Быстро. Полнотекстовый запрос. SELECT * FROM mail WHERE body MATCH 'sqlite'; -- Быстро. Полнотекстовый запрос. SELECT * FROM mail WHERE mail MATCH 'search'; -- Медленно. Полное сканирование. SELECT * FROM mail WHERE rowid BETWEEN 15 AND 20; -- Медленно. Полное сканирование. SELECT * FROM mail WHERE subject = 'database'; -- Быстро. Полнотекстовый запрос. SELECT * FROM mail WHERE subject MATCH 'database'; Все вышеприведённые полнотекстовые запросы имеют в правой части оператора
Как правило, полнотекстовые запросы являются регистронезависимыми. Однако они являются зависимыми от специфики токенайзера, используемого при запросах таблицы FTS. Более детально читайте об этом в разделе о токенайзерах. Абзацем выше было замечено, что оператор -- Схема примера
CREATE VIRTUAL TABLE mail USING fts3(subject, body);
-- Заполняем таблицу примера
INSERT INTO mail(docid, subject, body)
VALUES(1, 'software feedback', 'found it too slow');
INSERT INTO mail(docid, subject, body)
VALUES(2, 'software feedback', 'no feedback');
INSERT INTO mail(docid, subject, body)
VALUES(3, 'slow lunch order', 'was a software problem');
-- Примеры запросов
-- Будут выбраны строки 1 и 2
SELECT * FROM mail WHERE subject MATCH 'software';
-- Будет выбрана строка 2
SELECT * FROM mail WHERE body MATCH 'feedback';
-- Будут выбраны строки 1, 2 и 3
SELECT * FROM mail WHERE mail MATCH 'software';
-- Будут выбраны строки 1 и 3
SELECT * FROM mail WHERE mail MATCH 'slow';
На первый взгляд, последние два полнотекстовых запроса этого примера являются
синтаксически некорректными из-за той позиции в SQL-выражении, в которой
используется имя таблицы ("mail"). Однако это допустимо по той причине, что
таблица FTS действительно имеет скрытый (HIDDEN) столбец с тем же самым именем,
что и сама таблица (в нашем случае "mail"). Значения, хранящиеся в этом столбце,
не являются осмысленными для поискового приложения, но могут быть использованы в
качестве правого операнда для оператора Следующий пример иллюстрирует сказанное выше. Все выражения "docs", "docs.docs" и "main.docs.docs" ссылаются на столбец "docs". Однако выражение "main.docs" не ссылается на какой-то из столбцов. Оно может использоваться только для ссылки на таблицу, но в данном контексте не разрешается ссылаться на имя таблицы. -- Схема примера CREATE VIRTUAL TABLE docs USING fts4(content); -- Примеры запросов SELECT * FROM docs WHERE docs MATCH 'sqlite'; -- Правильно. SELECT * FROM docs WHERE docs.docs MATCH 'sqlite'; -- Правильно. SELECT * FROM docs WHERE main.docs.docs MATCH 'sqlite'; -- Правильно. SELECT * FROM docs WHERE main.docs MATCH 'sqlite'; -- Ошибка. 1.5. РезюмеС точки зрения пользователя таблицы FTS во многом похожи на обычные таблицы
SQLite. Данные в таблицах FTS могут добавляться, редактироваться и удаляться с
использованием команд
Перевод Дмитрия Скоробогатова, 01.06.2011 Предыдущие публикации: Последнее редактирование: 2011-06-02 20:19:09 Метки материала: sqlite, fts3, fts4, базы данных, программирование, разработка по, db, sql, алгоритмы поисковых систем Оставьте, пожалуйста, свой комментарий к публикации |
||||
© 2007-2012, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.