предисловие
В последнее время я изучаю и исследую ElasticSearch. ES — популярный поисковый сервер с открытым исходным кодом, который может предоставлять функцию полнотекстового поиска данных в режиме, близком к реальному времени. Одна из наиболее важных идей для реализации функции поиска — использовать倒排索引
в чем разница между ним и прямым индексом нашей реляционной базы данных, такой как Mysql? В этой статье я подытожу свое понимание двух видов индексов.
текст
положительный индекс
Взяв в качестве примера кластеризованный индекс Mysql Innodb, как показано на рисунке ниже, структура индекса дерева B+ в минималистской версии (без атрибутов страницы) примерно такая: конечные узлы хранят полные данные, а неконечные узлы хранят соответствующий кластеризованный индекс Поле (первичный ключ), Sql, который может использовать кластеризованный индекс, будет искать дерево B+ сверху вниз по очереди, пока поля не будут согласованы;
CREATE TABLE user_info (
id int,
name varchar(16),
hobby varchar(256)
);
Для некластеризованного индекса только содержимое конечного узла хранит информацию о первичном ключе таблицы.Порядок запроса состоит в том, чтобы сначала найти согласованные одиночные или несколько идентификаторов первичного ключа в конечном узле через поля некластеризованного index, а затем используйте эти первичные ключи. id для回表
и, наконец, получить соответствующие полные данные сущности.
Если мы посмотрим на поле хобби хобби в приведенной выше таблице mysql, если у нас есть бизнес-требования: запросите соответствующий список пользователей в соответствии с ключевыми словами хобби пользователя, такими как «баскетбол», как мы можем это сделать, мы можем написать только строку, подобную sql , все Логика сканирования таблицы.
SELECT *
FROM user_info
WHERE hobby LIKE '%篮球%';
Даже если мы создадим обычный индекс для поля хобби, под движком Innodb, если вы хотите использовать индекс строкового типа в запросе, вы можете только перейти最左前缀
Логика индекса, т.е. LIKE 'basketball%'. К счастью, Innodb поддерживает его после версии 5.6.全文索引full text
, После создания полнотекстового индекса полнотекстовый индекс можно использовать в запросе с использованием ПОИСКПОЗ и ПРОТИВ, что намного эффективнее, чем полное сканирование таблицы B+ дерева, но соответствующий полнотекстовый индекс будет занимать значительный объем диска космос. Полнотекстовый индекс — это то же самое, что инвертированный индекс, который мы хотим сказать.
SELECT *
FROM user_info
WHERE MATCH (hobby) AGAINST ('篮球');
Перевернутый индекс
По сравнению с прямым индексом дерева B+, если мы индексируем поле хобби, минимальный формат данных его инвертированного индекса выглядит следующим образом. Создадим поле с инвертированным индексом, которое будет проходить через分词器
По семантике поля в поле разбиваются на соответствующие терминоиндексы, которые составляют весь терминологический словарь данного типа данных, например, «как баскетбол и пение» будет делиться на «баскетбол» и «пение». индексы терминов; второй столбец содержит идентификатор документа (documentId), соответствующий этим индексам терминов, эти данные могут помочь нам проследить до полных данных объекта; третий столбец — это позиция соответствующего индекса термина в поле документа, 0 Указывает положение в начале, что может помочь отметить выделенную информацию извлеченных данных.
Инвертированный индекс и сегментация слов
Как создать соответствующий инвертированный индекс после ввода данных документа, таких как {"id":1,"name":"Zhang San","hobby":"Я люблю баскетбол и пение"}. Возьмите ES в качестве примера, вы можете установить поле в строку и соответствующий分词器
, будет предварительно обработан для поля хобби. После следующих трех шагов сегментации слов целое предложение будет разделено на несколько соответствующих индексов терминов, а также будут сгенерированы позиция и идентификатор документа, соответствующие каждому индексу термина. структура данных.
- Фильтры символов: обработка исходного текста, например удаление тегов html.
- Токенизатор: разделите исходный текст на слова по определенным правилам
- Фильтры токенов: повторная обработка слов, обработанных Tokenizer, таких как строчные буквы, удаление или добавление и т. д.
Для разного текстового контента мы можем использовать разные токенизаторы или даже пользовательские токенизаторы, такие как токенизаторы ES: Стандартный анализатор (токенизатор по умолчанию, сегментация по словам, обработка пунктуации), Простой анализатор (символы, не являющиеся буквами и буквами). разрезать на точки сегментации), Whitespace Analyzer (токенизатор на основе пространства), IKAnalyzer (более популярный китайский токенизатор); Полнотекстовый индекс Mysql также имеет соответствующий китайский токенизатор ngram.
Порядок запроса двух индексов
Через приведенное выше описание мы можем знать приближенный заказ запроса при использовании передового индекса и инвертированного индекса
Инвертирующий индекс идеологии
Я уже получил описание требования: нам нужно установить разные правила отображения контента для пользователей из разных городов, классов, семестров и устройств. Эти атрибуты могут быть установлены пустыми. Наконец, если атрибут пользователя соответствует нескольким правилам, то он должен основываться на весе этих атрибутов打分
, возьмем правило с наивысшим баллом.Например, мы настраиваем правила следующим образом: Затем приходит пользователь весной первого класса начальной школы Шанхая и сопоставляет два правила, а затем вычисляет значение веса в соответствии с атрибутами два правила и, наконец, выбирает отображение A или B.
city | grade | term | device | rule |
---|---|---|---|---|
Шанхай | весна | показать А | ||
Шанхай | Первый класс | показать Б |
При запросе данных выше sql выглядит следующим образом Идея процесса or аналогична "сегментация слова в инвертированном индексе + поиск всех данных документа, содержащих слово index" (только индекс слова уже определен) , а затем После поиска нескольких записей вычислите значение веса (аналогично оценке релевантности поиска в ES).
SELECT *
FROM tb_rules
WHERE (city = '上海' OR grade = '小学一年级' OR term = '春季')
Суммировать
Благодаря этой статье мы узнали об идее прямого индекса и инвертированного индекса и их кратких методах реализации, Мы надеемся, что с помощью этих разных принципов мы сможем найти разные решения проблем на работе.