Sqlite с использованием таблицы fts5 для выполнения всех запросов вместо основной таблицы
Итак, скажем, у меня есть две таблицы: и где это таблица поиска. Так есть два поля и.
Обычно я бы создал индекс для них обоих. Но поскольку у меня есть, мне нужно создать индекс для
name
и
surname
в ? И есть ли предостережения относительно использования
users_fts
выполнять все запросы вместо использования основной таблицы
users
?
1 ответ
SQLite обеспечивает полнотекстовый поиск, и я предполагаю, что это то, что вы используете из имени своей таблицы. Я покажу пример кода с использованием FTS5, но вы можете адаптировать его назад, если вам нужно. Если у вас есть таблица, например:
CREATE TABLE users(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
surname TEXT NOT NULL
);
затем вы создали свою таблицу полнотекстового поиска, используя что-то вроде этого:
CREATE VIRTUAL TABLE users_fts USING fts5(
name,
surname,
content='user',
content_rowid='id'
);
На этом этапе мы должны убедиться, что записи в таблице проиндексированы для полнотекстового поиска, и это можно сделать с помощью триггеров в таблице, чтобы сделать это автоматически. Триггеры будут выглядеть так:
CREATE TRIGGER users_ai AFTER INSERT ON users
BEGIN
INSERT INTO users_fts (rowid, name, surname)
VALUES (new.id, new.name, new.surname);
END;
CREATE TRIGGER users_ad AFTER DELETE ON users
BEGIN
INSERT INTO users_fts (users_fts, rowid, name, surname)
VALUES ('delete', old.id, old.name, old.surname);
END;
CREATE TRIGGER users_au AFTER UPDATE ON users
BEGIN
INSERT INTO users_fts (users_fts, rowid, name, surname)
VALUES ('delete', old.id, old.name, old.surname);
INSERT INTO users_fts (rowid, name, surname)
VALUES (new.id, new.name, new.surname);
END;
Теперь, когда все это готово, вы можете использовать таблицу для полнотекстового поиска.
Итак, как индексы в таблице влияют на таблицу? Если вы выполняете поиск только по таблице, то индексы в таблице не имеют значения. Я не знаю, как вы планируете заполнять таблицу, но если вы используете триггеры в таблице, предлагаемые индексы в таблице все равно не имеют значения. Если вы вручную обновляете таблицу, то ответ таков: индексы в таблице могут повлиять на производительность. Большинство людей, которых я знаю, используют триггерный подход, и это то, что я делаю, что позволяет вам забыть о ручном ведении полнотекстового поиска и получить дополнительное преимущество, заключающееся в том, что вы можете игнорировать индексы в исходной таблице в отношении заполнения полнотекстового поиска. Помните, что это сценарий, когда вы вообще не запрашиваете таблицу - если у вас есть какие-либо запросы к
users
table, то вам могут понадобиться вспомогательные индексы.
Вы также спросили, есть ли какие-либо предостережения в отношении подхода к использованию таблицы для ваших запросов - пока вы поддерживаете таблицу в актуальном состоянии, у этого подхода нет недостатков. Если вам нужны функции полнотекстового поиска и ранжирование, это очень удобный подход, встроенный в SQLite. Для этого потребуется больше места для хранения, но вы можете минимизировать это влияние, используя внешнюю таблицу содержимого (я показал это, когда создавал
users_fts
Таблица). Вы можете прочитать некоторые подробности об этом в разделе 4.4.2 документации по расширению FTS5 по адресу https://www.sqlite.org/fts5.html.
Этот подход хорошо работает для возможностей полнотекстового поиска, и пока вы поддерживаете индексы, он должен хорошо работать и предоставлять вам больше возможностей для поиска, а также для ранжирования. По моему опыту, большинство полнотекстовых поисков выполняется быстрее, чем то, что вы могли бы сделать с помощью стандартных функций и операторов SQL (таких как
LIKE
и т. д.) и намного мощнее.