Mysql как найти слово

If you are avoiding stored procedures like the plague, or are unable to do a mysql_dump due to permissions, or running into other various reasons.

I would suggest a three-step approach like this:

1) Where this query builds a bunch of queries as a result set.

# =================
# VAR/CHAR SEARCH
# =================
# BE ADVISED USE ANY OF THESE WITH CAUTION
# DON'T RUN ON YOUR PRODUCTION SERVER 
# ** USE AN ALTERNATE BACKUP **

SELECT 
    CONCAT('SELECT * FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME, 
           ' WHERE ', A.COLUMN_NAME, ' LIKE '%stuff%';') 
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE 
            A.TABLE_SCHEMA != 'mysql' 
AND     A.TABLE_SCHEMA != 'innodb' 
AND     A.TABLE_SCHEMA != 'performance_schema' 
AND     A.TABLE_SCHEMA != 'information_schema'
AND     
        (
            A.DATA_TYPE LIKE '%text%'
        OR  
            A.DATA_TYPE LIKE '%char%'
        )
;

.

# =================
# NUMBER SEARCH
# =================
# BE ADVISED USE WITH CAUTION

SELECT 
    CONCAT('SELECT * FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME, 
           ' WHERE ', A.COLUMN_NAME, ' IN ('%1234567890%');') 
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE 
            A.TABLE_SCHEMA != 'mysql' 
AND     A.TABLE_SCHEMA != 'innodb' 
AND     A.TABLE_SCHEMA != 'performance_schema' 
AND     A.TABLE_SCHEMA != 'information_schema'
AND     A.DATA_TYPE IN ('bigint','int','smallint','tinyint','decimal','double')
;

.

# =================
# BLOB SEARCH
# =================
# BE ADVISED THIS IS CAN END HORRIFICALLY IF YOU DONT KNOW WHAT YOU ARE DOING
# YOU SHOULD KNOW IF YOU HAVE FULL TEXT INDEX ON OR NOT
# MISUSE AND YOU COULD CRASH A LARGE SERVER
SELECT 
    CONCAT('SELECT CONVERT(',A.COLUMN_NAME, ' USING utf8) FROM ', A.TABLE_SCHEMA, '.', A.TABLE_NAME, 
           ' WHERE CONVERT(',A.COLUMN_NAME, ' USING utf8) IN ('%someText%');') 
FROM INFORMATION_SCHEMA.COLUMNS A
WHERE 
            A.TABLE_SCHEMA != 'mysql' 
AND     A.TABLE_SCHEMA != 'innodb' 
AND     A.TABLE_SCHEMA != 'performance_schema' 
AND     A.TABLE_SCHEMA != 'information_schema'
AND     A.DATA_TYPE LIKE '%blob%'
;

Results should look like this:

Copy these results into another query window

2) You can then just Right Click and use the Copy Row (tab-separated)

enter image description here

3) Paste results in a new query window and run to your heart’s content.

Detail: I exclude system schema’s that you may not usually see in your workbench unless you have the option Show Metadata and Internal Schemas checked.

I did this to provide a quick way to ANALYZE an entire HOST or DB if needed or to run OPTIMIZE statements to support performance improvements.

I’m sure there are different ways you may go about doing this but here’s what works for me:

-- ========================================== DYNAMICALLY FIND TABLES AND CREATE A LIST OF QUERIES IN THE RESULTS TO ANALYZE THEM
SELECT CONCAT('ANALYZE TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname';

-- ========================================== DYNAMICALLY FIND TABLES AND CREATE A LIST OF QUERIES IN THE RESULTS TO OPTIMIZE THEM
SELECT CONCAT('OPTIMIZE TABLE ', TABLE_SCHEMA, '.', TABLE_NAME, ';') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbname';

Tested On MySQL Version: 5.6.23

WARNING: DO NOT RUN THIS IF:

  1. You are concerned with causing Table-locks (keep an eye on your client-connections)
  2. You are unsure about what you are doing.

  3. You are trying to anger you DBA. (you may have people at your desk with the quickness.)

Cheers, Jay ;-]

При работе с базой данных SQL вам может понадобиться найти записи, содержащие определенные строки. В этой статье мы разберем, как искать строки и подстроки в MySQL и SQL Server.

Содержание

  • Использование операторов WHERE и LIKE для поиска подстроки
  • Поиск подстроки в SQL Server с помощью функции CHARINDEX
  • Поиск подстроки в SQL Server с помощью функции PATINDEX
  • MySQL-запрос для поиска подстроки с применением функции SUBSTRING_INDEX()

Я буду использовать таблицу products_data в базе данных products_schema. Выполнение команды SELECT * FROM products_data покажет мне все записи в таблице:

Поскольку я также буду показывать поиск подстроки в SQL Server, у меня есть таблица products_data в базе данных products:

Поиск подстроки при помощи операторов WHERE и LIKE

Оператор WHERE позволяет получить только те записи, которые удовлетворяют определенному условию. А оператор LIKE позволяет найти определенный шаблон в столбце. Эти два оператора можно комбинировать для поиска строки или подстроки.

Например, объединив WHERE с LIKE, я смог получить все товары, в которых есть слово «computer»:

SELECT * FROM products_data
WHERE product_name LIKE '%computer%'

Знаки процента слева и справа от «computer» указывают искать слово «computer» в конце, середине или начале строки.

Если поставить знак процента в начале подстроки, по которой вы ищете, это будет указанием найти такую подстроку, стоящую в конце строки. Например, выполнив следующий запрос, я получил все продукты, которые заканчиваются на «er»:

SELECT * FROM products_data
WHERE product_name LIKE '%er'

А если написать знак процента после искомой подстроки, это будет означать, что нужно найти такую подстроку, стоящую в начале строки. Например, я смог получить продукт, начинающийся на «lap», выполнив следующий запрос:

SELECT * FROM products_data
WHERE product_name LIKE 'lap%'

Этот метод также отлично работает в SQL Server:

Поиск подстроки в SQL Server с помощью функции CHARINDEX

CHARINDEX() — это функция SQL Server для поиска индекса подстроки в строке.

Функция CHARINDEX() принимает 3 аргумента: подстроку, строку и стартовую позицию для поиска. Синтаксис выглядит следующим образом:

CHARINDEX(substring, string, start_position)

Если функция находит совпадение, она возвращает индекс, по которому найдено совпадение, а если совпадение не найдено, возвращает 0. В отличие от многих других языков, отсчет в SQL начинается с единицы.

Пример:

SELECT CHARINDEX('free', 'free is the watchword of freeCodeCamp') position;

Как видите, слово «free» было найдено на позиции 1. Это потому, что на позиции 1 стоит его первая буква — «f»:

Можно задать поиск с конкретной позиции. Например, если указать в качестве позиции 25, SQL Server найдет совпадение, начиная с текста «freeCodeCamp»:

SELECT CHARINDEX('free', 'free is the watchword of freeCodeCamp', 25);

При помощи CHARINDEX можно найти все продукты, в которых есть слово «computer», выполнив этот запрос:

SELECT * FROM products_data WHERE CHARINDEX('computer', product_name, 0) > 0

Этот запрос диктует следующее: «Начиная с индекса 0 и до тех пор, пока их больше 0, ищи все продукты, названия которых содержат слово «computer», в столбце product_name». Вот результат:

Поиск подстроки в SQL Server с помощью функции PATINDEX

PATINDEX означает «pattern index», т. е. «индекс шаблона». Эта функция позволяет искать подстроку с помощью регулярных выражений.

PATINDEX принимает два аргумента: шаблон и строку. Синтаксис выглядит следующим образом:

PATINDEX(pattern, string)

Если PATINDEX находит совпадение, он возвращает позицию этого совпадения. Если совпадение не найдено, возвращается 0. Вот пример:

SELECT PATINDEX('%ava%', 'JavaScript is a Jack of all trades');

Чтобы применить PATINDEX к таблице, я выполнил следующий запрос:

SELECT product_name, PATINDEX('%ann%', product_name) position
FROM products_data

Но он только перечислил все товары и вернул индекс, под которым нашел совпадение:

Как видите, подстрока «ann» нашлась под индексом 3 продукта Scanner. Но скорее всего вы захотите, чтобы выводился только тот товар, в котором было найдено совпадение с шаблоном.

Чтобы обеспечить такое поведение, можно использовать операторы WHERE и LIKE:

SELECT product_name, PATINDEX('%ann%', product_name) position
FROM products_data
WHERE product_name LIKE '%ann%'

Теперь запрос возвращает то, что нужно.

MySQL-запрос для поиска строки с применением функции SUBSTRING_INDEX()

Помимо решений, которые я уже показал, MySQL имеет встроенную функцию SUBSTRING_INDEX(), с помощью которой можно найти часть строки.

Функция SUBSTRING_INDEX() принимает 3 обязательных аргумента: строку, разделитель и число. Числом обозначается количество вхождений разделителя.

Если вы укажете обязательные аргументы, функция SUBSTRING_INDEX() вернет подстроку до n-го разделителя, где n — указанное число вхождений разделителя. Вот пример:

SELECT SUBSTRING_INDEX("Learn on freeCodeCamp with me", "with", 1);

В этом запросе «Learn on freeCodeCamp with me» — это строка, «with» — разделитель, а 1 — количество вхождений разделителя. В этом случае запрос выдаст вам «Learn on freeCodeCamp»:

Количество вхождений разделителя может быть как положительным, так и отрицательным. Если это отрицательное число, то вы получите часть строки после указанного числа разделителей. Вот пример:

SELECT SUBSTRING_INDEX("Learn on freeCodeCamp with me", "with", -1);

От редакции Techrocks: также предлагаем почитать «Индексы и оптимизация MySQL-запросов».

Заключение

Из этой статьи вы узнали, как найти подстроку в строке в SQL, используя MySQL и SQL Server.

CHARINDEX() и PATINDEX() — это функции, с помощью которых можно найти подстроку в строке в SQL Server. Функция PATINDEX() является более мощной, так как позволяет использовать регулярные выражения.

Поскольку в MySQL нет CHARINDEX() и PATINDEX(), в первом примере мы рассмотрели, как найти подстроку в строке с помощью операторов WHERE и LIKE.

Перевод статьи «SQL Where Contains String – Substring Query Example».

Задание: Необходимо найти, в каких полях таблицы, встречается запрошенное слово или строка и запросить данные всех полей таблиц, удовлетворяющих запросу.

Решением этой задачи будет служить SQL запрос содержащий оператора LIKE.

Приведу примитивный пример.
Представим, что у нас есть таблица с какими то данным:

Допустим нам нужно вывести все строки в поле text, которых содержится слово «статьи«.

Пишем запрос

:
Логика запроса: получить данные всех полей таблицы post, где в поле text встречается слово «статьи«.

SELECT * FROM post WHERE text LIKE '%статьи%'

Результат выполнения запроса:

/* Affected rows: 0 Найденные строки: 2 Предупреждения: 0 Длительность 1 query: 0,000 sec. */

Запрос для поиска слова в начале строки

:
Логика запроса: получить данные всех полей таблицы post, где в начале поля text встречается слово «статьи«.

SELECT * FROM post WHERE text LIKE 'статьи%'

Запрос для поиска слова в конце строки

:
Логика запроса: получить данные всех полей таблицы post, где в конце поля text встречается слово «статьи«.

SELECT * FROM post WHERE text LIKE '%статьи'

Знак % внутри условия оператора LIKE говорит о том, что до или после необходимого для поиска слова «статьи» может находится какой то текст.

Новость отредактировал: Fixlix — 8-05-2019, 17:04
Причина: Дописана информация с примерами заросов для поиска слова в начале и конце строки

Полнотекстовый поиск и его возможности

Время на прочтение
6 мин

Количество просмотров 181K

Многие СУБД поддерживают методы полнотекстового поиска (Fulltext search), которые позволяют очень быстро находить нужную информацию в больших объемах текста.

В отличие от оператора LIKE, такой тип поиска предусматривает создание соответствующего полнотекстового индекса, который представляет собой своеобразный словарь упоминаний слов в полях. Под словом обычно понимается совокупность из не менее 3-х не пробельных символов (но это может быть изменено). В зависимости от данных словаря может быть вычислена релевантность – сравнительная мера соответствия запроса найденной информации.

В статье рассказывается как работать с полнотекстовым поиском на примере БД MySQL, а так же приведу примеры «нестандартного» использования данного механизма.

В MySQL возможности полнотекстового поиска (только для MyISAM-таблиц) поддерживаются начиная с версии 3.23.23. В последующих версиях механизм потерпел существенные доработки и расширения, в тоге превратившись в мощное средство для создания поисковых механизмов веб-приложений. Главная особенность – быстрый поиск слов в очень больших объемах текстовой информации.

Индекс FULLTEXT

Итак, чтобы работать с полнотекстовым поиском, сначала нам нужно создать соответствующий индекс. Он называется FULLTEXT, и может быть наложен на поля CHAR, VARCHAR и TEXT. Причем, как и в случае с обычным индексом – если происходит поиск по 2-м полям, то нужен объединенный индекс 2-х полей, используйте поиск по одному полю – нужен индекс только этого поля. Например:

CREATE TABLE `articles` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(200) default NULL,
`body` text,
PRIMARY KEY (`id`),
FULLTEXT KEY `ft1` (`title`,`body`),
FULLTEXT KEY `ft2` (`body`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

В этом примере создается таблица с 2-мя полнотекстовыми индексами: ft1 и ft2, которые можно использовать для поиска в полях title и body, или только в body. Только в поле title искать не получится.

Конструкция MATCH-AGAINST

Собственно для самого полнотекстового поиска в MySQL используется конструкция MATCH(filelds)… AGAINST(words). Она может работать в различных режимах, которые достаточно сильно между собой отличаются. Для всех действует следующее правило: данная конструкция возвращает условную релевантность, но способ вычисления которой может быть разным в зависимости от режима. Еще стоит добавить что во всех режимах поиск всегда регистрозависимый. Далее более подробно о каждом из них.

MATCH-AGAINST IN NATURAL LANGUAGE MODE

— это основной вид поиска, который используется по умолчанию, т.е. если режим не указан:

SELECT * FROM `articles` WHERE MATCH (title,body) AGAINST ('database');

В этом примере мы ищем слово database в полях title и body таблицы articles на основе индекса ft1 (см. пример создания таблицы выше). Выборка будет автоматически отсортирована по релевантности – это происходит в случае указания конструкции MATCH-AGAINST внутри блока WHERE и не задано условие сортировки ORDER BY.

Кстати, несмотря на возможности алиасов, при запросах конструкцию приходится повторять в разных местах, что усложняет запросы. Вот например нельзя написать так:

SELECT *, MATCH (title,body) AGAINST ('database') as REL
FROM `articles`
WHERE REL > 0;

— этот запрос выдаст ошибку: поле Rel не определено. Что бы работало, придется продублировать данную конструкцию:

SELECT *, MATCH (title,body) AGAINST ('database') as REL
FROM `articles`
WHERE MATCH (title,body) AGAINST ('database') > 0;

Однако, сколько бы вы не использовали одну и туже конструкцию (разумеется с одинаковыми параметрами) она будет вычислена только один раз.

В примере выше в переменной REL будет вычислена релевантность. Эта величина зависит прежде всего от количества слов в полях tilte и body, того насколько близко данное слово встречается к началу текста, отношения количества встретившихся слов к количеству всех слов в поле и др.

Например, релевантность будет не нулевая, если слово database встретится либо в title, либо body, но если оно встретится и там и там, значение релевантности будет выше, нежели если оно два раза встретится в body.

Сама по себе релевантность ничего не определяет. Это лишь сравнительная характеристика, по которой можно сортировать результат выборки, не более того.

Еще следует заметить что для IN NATURAL LANGUAGE MODE действует так называемое «50% threshold». Это означает, что если слово встречается более чем в 50% всех просматриваемых полей, то оно не будет учитываться, и поиск по этому слову не даст результатов.

MATCH-AGAINST IN BOOLEAN MODE

В бинарном режиме, в отличие от других режимов, релевантность вычисляется несколько иначе — как условная мера совпадения заданного шаблона. Положение искомого шаблона в тексте, количество встретившихся вариантов роли не играют.

Самая важная особенность бинарного режима – возможность указания логических операторов. Сами операторы я приводить не буду, о них хорошо рассказано в оригинальной документации по MySQL.

Еще особенностями бинарного режима является отсутствие автоматической сортировки в случае указания условия WHERE, однако для сортировки можно использовать алиас:

SELECT *,
MATCH (title,body) AGAINST ('+database MySQL' IN BOOLEAN MODE) as REL
FROM `articles`
WHERE MATCH (title,body) AGAINST ('+database MySQL' IN BOOLEAN MODE)
ORDER BY REL;

Пример выведет все записи содержащие слово database, но если в записи присутствует слово MySQL, то его релевантность будет выше. Записи будут отсортированы по релевантности.

В бинарном режиме отсутствует ограничение «50% threshold». Бинарный режим можно использовать и без создания полнотекстового индекса, однако это будет работать очень медленно.

MATCH-AGAINST IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION

Или просто «WITH QUERY EXPANSION». Работает примерно также, как NATURAL LANGUAGE MODE, с той лишь разницей, то в результат поиска попадают не только совпадения с шаблоном, но и возможные логические совпадения. Это работает примерно так:

Сначала MySQL выполняет запрос аналогичный NATURAL LANGUAGE MODE и формирует результат. По этому результату производится попытка вычислить слова, которые так же имеют высокую релевантность для полученной выборки. В случае, если эти слова присутствуют производится поиск и по ним тоже, но значение их на релевантность будет существенно ниже. Отдается смешанная выборка – сначала те результаты, где слово присутствует, а потом те, которые были получены в результате «повторного» поиска.

WITH QUERY EXPANSION не рекомендуется использовать для больших объемов информации, так как в результат может попасть очень много лишнего.

Использование FULLTEXT SEARCH

Пара слов об алгоритмах поиска

Ну, конечно полнотекстовый поиск можно использовать прежде всего для написания алгоритмов поиска. :-) Я не буду заострять на них внимание, скажу просто что при индексации текстовой информации может понадобиться сложный алгоритм обработки, например такой:

  1. убрать все HTML-теги
  2. убрать все непечатные символы, знаки препинания и тому подобное
  3. убрать все слова длинной менее 3-х символов
  4. перевести все слова в нижний регистр

— это только в самом простом случае, без учета морфологии, подсветки, учета ключевых слов и кодировки.

Соответственно, с поисковым запросом надо сделать тоже самое. Режим поиска используется любой – как удобнее… А вообще поиск – это отдельная тема, про которую нужна отдельная статья.

Раскрытие связок многое-ко-многим

В некоторых случаях – не во всех – с помощью полнотекстового поиска можно раскрывать соотношения многое-ко-многим без привлечения третьей таблицы.

Допустим, у нас есть две большие таблицы: с пользователями и группами пользователей. Причем, каждый пользователь имеет отношение к большому количеству различных групп, в свою очередь группы включают в себя большое количество пользователей. При нормальном соотношении (т.е. раскрытии через 3-ю таблицу), что бы выбрать все группы, которые принадлежат к некоторому пользователю понадобиться сделать запрос, объединяющий 2 или 3 таблицы, что даже при присутствии индексов очень накладно.

Однако можно выполнить денормализацию по следующей схеме:

Теперь, что бы выбрать группы, принадлежащие к пользователю 2 можно сделать:

SELECT *
FROM `groups`
WHERE MATCH (groups) AGAINST ('+user2' IN BOOLEAN MODE);

Это будет работать намного быстрее, чем исходный вариант (с 3-ей таблицей). Аналогично с группами, но если подобные выборки нам в принципе не нужны, то можно обойтись без соответствующего поля в таблице групп. Тогда получится что-то вроде «односторонней» связи M:N. То есть можно вычислить все M, которые принадлежат к N, не нельзя сделать обратного.

В этом случае, как правило, используется IN BOOLEAN MODE.

— Кстати, на эту схему очень хорошо ложится тегирование информации, но там не все так просто и это опять же отдельная тема.

Использование релевантности как меры отношения одного объекта к другому

Один из алгоритмов для вычисления статей, «похожих» на данную статью. Всё просто: берутся теги данной статьи, и делается полнотекстовый запрос по полю с тегами всех остальных статей с сортировкой по релевантности (если она нужна). Естественно, сначала вылезут те, которые содержат максимальное совпадение по тегам.

Можно и без учета тегов. Если статьи индексированы для полнотекстового поиска, из индекса выбираются с десяток наиболее употребляемых слов, после чего делается поиск по ним.

Или вот еще пример – интересы пользователей. Используя точно такую же схему можно легко найти других пользователей, у которых интересы наиболее соответствуют вашим.

И кое-что в заключение:

Несмотря на все возможности полнотекстовых индексов, стоит учитывать, что сами индексы занимают очень значительное место на диске, и изменения таблиц с ними будет выполняться значительно дольше.

Table of contents

What is Full-Text Search in MySQL?
How does the Full-Text Search in MySQL work?
LIKE vs Full-Text Search operators in MySQL
Advantages and disadvantages of Full Text Search and LIKE operator in MySQL
Full-text Search Restrictions
Example of Using the Full-text Search in MySQL
Conclusion

What is a Full-Text Search in MySQL?

You can have Google-like superpowers to find words and phrases across your entire database. Search engines use Full-Text Search to find results in databases. These databases often contain a lot of textual data. For example, news websites contain lots of news articles and may want to find a specific phrase. Or users may file support tickets with the same wording that indicates a common problem.

Full-Text Search does not try to find a word-for-word phrase written by the user. It is trying to guess what the user had in mind, to learn the deeper meaning, so to speak.

Its goal is to find results that are approximate in meaning and quickly issue them. Thus, the result will be much more useful to the user, as it will be more relevant.

Typically, a search service has two components.Search engine and indexer:

  • The indexer receives text as input, does text processing (cutting out endings, insignificant words, etc.), and stores everything in the index. The structure of such an index allows for very fast searches;
  • The search engine, an index search interface, accepts a request from the client, processes the phrase, and searches for it in the index.

Full-text search in Google

How does the Full-Text Search in MySQL work?

To use full-text search in MySQL you need to use full-text indexes and the MATCH () function. The full-text index is FULLTEXT.

Mysql supports full-text indexes on MyISAM tables. InnoDB support has been added since version 5.6.4.

When you create a table using the CREATE TABLE command, you can create these indexes on the VARCHAR and TEXT columns. You can also add indexes later using the ALTER TABLE or CREATE INDEX commands.

However, you should refrain from adding the FULLTEXT index right away when creating the table. Large amounts of data are loaded into the table much faster if no index is added. That is why indexes are usually added later.

The MATCH () function executes a language search. It compares a string to the text content. By content I mean the combination of one or more columns included in the FULLTEXT index.

FULLTEXT index in MySQL 

The search string is specified with an argument in the AGAINST () expression. The search is case-insensitive. The MATCH () command returns the relevance value for each row in a column. Relevance value is how similar the search string and the text in the string are.

MATCH (column1,column2,column3...) AGAINST (expression [search_modifier])

When you use the MATCH () command in a WHERE clause, the result column rows are automatically sorted by relevance.

The relevance value is a non-negative floating-point number.
Relevance is calculated based on:

  • Words in a given row of a column;
  • Unique words in that row;
  • Number of words in the text;
  • Rows containing a single word.

Full-Text Search is not a complex tool, it is almost as simple as the LIKE operator. But the LIKE operator alone is not as useful as FTS. I’ll talk about this in the next subsection.

LIKE vs Full-Text Search operators in MySQL

A synonym for the LIKE operator is precision, for full-text input it is flexibility. Thus, you can easily understand the intricacies of the work of each method. And now for more details.

LIKE Operator

High LIKE operator precision means that fewer false results are displayed. A high recall rate means fewer relevant results are overlooked. This means that LIKE is 100% accurate when searching for a phrase.

However, the MySQL LIKE statement may not be useful in some circumstances.
If you apply it to a non-indexed column, the database will use a full scan to find matches.

If the column is indexed, matching can be done against the index keys, but with much less efficient than most index searches.
In the worst case, the LIKE pattern will have leading wildcards requiring each index key to be checked.

The LIKE operator is better when there are not a huge number of records and it is practically impossible to use it in tables with hundreds of thousands of rows since the search is performed on all records and this reduces performance.

Full-Text Search

Most full-text search implementations use an index, where keys are individual terms and related values are recordsets that contain the term.
FTS is optimized to compute the intersection, combining these recordsets. It often provides a ranking algorithm to quantify how closely a given entry matches your search keywords.

Full-text search features include:

  • Splitting a block of unstructured text into separate words, phrases, and special tokens;
  • Combining variations of a word into one index term;
  • Measuring the similarity of a matched record to a query string.

LIKE Operator vs MATCH AGAINST

Let’s take a quick look at the comparison. Morphology means searching based on the root of the word using specific language and grammar knowledge.

Searching with the LIKE Operator

Benefits Disadvantages
Less than O(n^2) complexity No morphology support
Sort the results No modifiers
Used on any type of field Search in all lines

Searching with Full-text Search

Benefits Disadvantages
Support for Morphology Lack of sorting capability
Results ordered by relevance VARCHAR and TEXT with indexes only
Google style modifiers Resource intensive process
Stop words Native support for MyISAM tables only
Ability to customize Adding data takes longer with FULLTEXT

Full-text Search Restrictions

When using full-text search, it is also worth remembering that the MATCH () function has its limitations:

  1. All parameters of the MATCH () function must be columns of the same table. This means that they must be part of the same FULLTEXT index. Does not apply to BOOLEAN MODE;
  2. The list of columns in the MATCH () command must exactly match the list of columns in the FULLTEXT index definition for this table. Does not apply to BOOLEAN MODE;
  3. The argument in AGAINST () must be an immutable string.

Full-text Search Example in MySQL

In this example, you will see how relevant the results of a full-text search are.

First, let’s create a schema:

CREATE SCHEMA IF NOT EXISTS `mydb`;

Our schema will be a database of cosmetic products. That is, now we are creating a table of categories:

CREATE TABLE IF NOT EXISTS `mydb`.`category` (
  `id` INT NOT NULL,
  `name_category` VARCHAR(45) NOT NULL,
  FULLTEXT(name_category),
  PRIMARY KEY (`id`))
ENGINE = InnoDB;

And now we create a table of products:

CREATE TABLE IF NOT EXISTS `mydb`.`product` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name_product` VARCHAR(45) NOT NULL,
  `price_product` DECIMAL NOT NULL,
  `amount_product` INT NOT NULL,
  `desc_product` VARCHAR(255) NOT NULL,
  `idcategory` INT NOT NULL,
  FULLTEXT(name_product, desc_product),
  PRIMARY KEY (`id`),
  INDEX `fk_product_category_idx` (`idcategory` ASC),
  CONSTRAINT `fk_product_category`
    FOREIGN KEY (`idcategory`)
    REFERENCES `mydb`.`category` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

Now that we have the tables, we fill them in starting with the category table:

INSERT INTO `mydb`.category (`id`, `name_category`) VALUES (1,'Shampoo'), (2,'Eyeshadow'), (3,'Face lotionproduct'), (4,'Face Primer'), (5,'Lipstick'), (6,'Powder'), (7,'Mascara'), (8,'Blush'), (9,'Highlighter'), (10,'Toner');

And also fill in the product table:

INSERT INTO product (id, name_product, price_product, amount_product, desc_product, idcategory) VALUES 
(1, 'Shampoo perfumes "Clear"', 130, 100, 'Styling products and environmental pollutants have been filling the hair structure from time to time, making it dull and hard. This shampoo is formulated to effectively remove this impurity while rejuvenating the hair structure.',1),
(2, 'Eyeshadow "Makeup"', 245, 104, 'Contains an all-natural mineral wax with added kaolin and zinc oxide to create lush, healthy lashes. The brush is designed to reduce clumping of the product. Apply in a zigzag motion from root to tip to completely cover each lash. Reapply if desired.',2),
(3, 'Face Lotion "Gigi"', 120, 99, 'The lotion promotes the resorption of inflammation, maturation and drying of abscesses. The lotion has a disinfectant, anti-inflammatory, antibacterial and antifungal effect, and also prevents the development of a secondary infection.',3),
(4, 'Lipstick Set "LP"', 250, 165, 'The properties of lipstick will be appreciated by professional makeup artists and lovers of the perfect make-up. A variety of dazzling shades allow you to choose the right tone for elegant daytime and spicy evening make-up.',5),
(5, 'Highlighter "NAC"', 175, 111, 'The skin seems to glow from the inside.',9),
(6, 'Powder "Pow"', 190, 205, 'With a high concentration of shimmery pigments and a unique holographic shade, the powder enhances facial features and fills the skin with radiance.',6),
(7, 'Toner "Tonn"', 160, 198, 'This is a versatile toner that removes deep impurities, tones the skin and gently removes dead skin cells from the skin!',10),
(8, 'Blush "Gigi"', 135, 57, 'The cosmetic product has a silky texture that lays down on the skin very softly and smoothly, without clogging pores or making the make-up heavier.',8),
(9, 'Highlighter "Lily"', 200, 30, 'It has a light texture that creates a weightless shimmer on the skin. Thanks to the smallest reflective particles, the face acquires a delicate, soft, natural shine.',9),
(10, 'Shampoo "Lux"', 160, 11, 'Dry and damaged hair requires intensive repair. Gentle cleansing and deep nourishment in minutes.',1),
(11, 'Lipstick "Gigi"', 90, 225, 'On your lips, lipstick will retain a flawless look for up to 12 hours, decorating them with a luxurious matte finish and a sophisticated shade.',5);

The table we have:

The «product» table

Outputting fields from a table by the word “shampoo” for two indirectly joined tables:

SELECT * FROM category c JOIN product p ON c.id = p.idcategory
WHERE MATCH(p.name_product, p.desc_product) AGAINST ('shampoo');

Output of fields from a table 

You can notice that the search found this word in the product description and product name (line 1), and in line 2 this word is present only in the product name, but not in the description.

Conclusion

This was a short piece of information about full-text search in MySQL. A basic understanding of the usefulness of Full-Text Search will come from using this search in practice. Now you know that the LIKE operator is not the only way to search through text in the MySQL database. Full-Text Search in MySQL gives you search superpowers like Google has to find any string or word across all tables in your database.

Join the Arctype Newsletter

Join 800+ developers and receive actionable advice from industry professionals about programming every week

Понравилась статья? Поделить с друзьями:
  • Как найти фаворит одежду роблокс
  • Как найти модель обоев
  • Как найти молярную концентрацию полученного раствора
  • Как найти работу свободно падающего тела
  • Как составить синквейн самостоятельно