SQLite LinuxWindowsmacOS

Как настроить поиск по кириллице, если SQLite LIKE различает заглавные буквы

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

В стандартной сборке SQLite оператор LIKE сравнивает буквы без учёта регистра для латинского диапазона ASCII, но для кириллицы «Москва» и «москва» могут не считаться совпадением. SQL-функции lower()/upper() по умолчанию также не делают полного преобразования регистра Unicode. Поэтому проверка LOWER(title) LIKE LOWER(?) часто не исправляет поиск по русскому тексту; нужна выбранная стратегия нормализации или FTS5, учитывающая требования к поиску.

В этой статье
  1. Что происходит и когда возникает
  2. Возможные причины: как различить
  3. Пошаговая диагностика и исправление
  4. Команды и проверочные примеры
  5. Как проверить результат
  6. Если не помогло

#Что происходит и когда возникает

В стандартной сборке SQLite оператор LIKE сравнивает буквы без учёта регистра для латинского диапазона ASCII, но для кириллицы «Москва» и «москва» могут не считаться совпадением. SQL-функции lower()/upper() по умолчанию также не делают полного преобразования регистра Unicode. Поэтому проверка LOWER(title) LIKE LOWER(?) часто не исправляет поиск по русскому тексту; нужна выбранная стратегия нормализации или FTS5, учитывающая требования к поиску.

#Возможные причины: как различить

Возможная причинаКак узнатьЧто делать
LIKE работает только для ASCII без учёта регистраВстроенное сравнение не охватывает весь Unicode.SELECT 'ПРИВЕТ' LIKE 'привет' возвращает 0, а 'ABC' LIKE 'abc' — 1.Подобрать Unicode-совместимый механизм.
Нужен поиск внутри слова, а включён поиск по токенамFTS5 unicode61 индексирует слова, но обычный MATCH не равен LIKE %подстрока%.Поиск полного слова проходит, части слова посередине — нет.Решить, нужен ли поиск по словам, по префиксам или внутри строк.
Разная нормализация русских буквРазличия ё/е, Unicode-нормализации и пробелов не устраняются обычным LIKE.Одинаковые на вид фразы дают разные результаты.Принять и документировать правила нормализации при индексации и запросе.

#Пошаговая диагностика и исправление

  1. Уточните требование поискаЕсли пользователи ищут целое слово, префикс или произвольную часть названия, запишите 2–3 примера с ожидаемыми результатами. Например, поиск «москва» должен находить «Москва»; для поиска «скв» внутри слова потребуется отдельный способ. Без этого легко выбрать быстрый, но неподходящий индекс.
  2. Проверьте поведение текущей SQLiteОткройте SQL-консоль приложения либо терминал с sqlite3 и выполните диагностический SELECT из примера. Запрос не изменяет данных: два столбца с результатами 1 и 0 показывают, что ASCII сравнивается без учёта регистра, а кириллица — нет. Если результат другой, вероятно, в вашей сборке установлено расширение или пользовательская функция LIKE.
  3. Проверьте отсутствие опечатки в шаблонеПосмотрите, формирует ли приложение шаблон с % и _ правильно и передаёт ли строку как параметр, а не подставляет её в SQL текстом. Выведите обезличенные параметры запроса в тестовом окружении. Учтите, что % означает любую последовательность символов, _ — один символ; при буквальном поиске таких знаков нужен ESCAPE.
  4. Если нужно искать отдельные слова, испытайте FTS5В отдельной тестовой базе создайте виртуальную таблицу FTS5 с tokenizer unicode61 (пример ниже). Введите запись «Москва» и проверьте MATCH 'москва': строка должна находиться. Перед переносом проверьте, включён ли модуль FTS5: иначе SQLite сообщит «no such module: fts5». Такой поиск индексирует слова, а не любую подстроку.
  5. Если требуется поиск произвольных подстрок, выберите отдельный подходДля небольшого каталога разработчик может хранить дополнительную колонку с Unicode-нормализацией по заранее выбранным правилам и сравнивать нормализованные значения, включая запрос. Для больших наборов при наличии подходящей версии SQLite рассмотрите FTS5 trigram, испытайте особенности регистра и поиск коротких строк. Не рассчитывайте, что стандартные lower()/upper() обработают русский Unicode.
  6. Не меняйте глобальные настройки LIKE на рабочей базеНе используйте PRAGMA case_sensitive_like как «исправление кириллицы»: оно не добавляет Unicode-поддержку и устарело. Изменение семантики LIKE может повлиять на индексы и выражения схемы. Любую замену механизма поиска тестируйте на отдельной копии данных с запросами пользователей.
  7. Сравните качество и скорость на контрольных фразахПроверьте заглавные/строчные буквы, ё/е, буквы с комбинируемыми символами, короткие поиски и имена с дефисом. Зафиксируйте число совпадений и время ответа на тестовом объёме. Если новый индекс не подходит, откатите изменения к прежней схеме и оставьте прежний поиск, не изменяя исходные тексты.

#Команды и проверочные примеры

SQLКоманда
В SQL-консоли SQLite; ожидаемый результат стандартной сборки: 1 и 0.
SELECT 'ABC' LIKE 'abc' AS ascii_like, 'ПРИВЕТ' LIKE 'привет' AS russian_like;
SQL
Только в новой тестовой базе; найдёт строку «Москва», если сборка включает FTS5.
CREATE VIRTUAL TABLE titles_fts USING fts5(title, tokenize='unicode61');
INSERT INTO titles_fts(title) VALUES ('Москва');
SELECT title FROM titles_fts WHERE titles_fts MATCH 'москва';

#Как проверить результат

Ищите одинаковую фразу в нескольких вариантах регистра и сравните результаты на контрольном наборе. Для FTS5 проверьте, что слово «москва» находит «Москва», но не считайте подстрочный поиск автоматически реализованным.

#Если не помогло

Если в FTS5 «no such module: fts5», проверьте сборку SQLite через PRAGMA compile_options; и версию драйвера; не загружайте случайные расширения с сайтов. Если нужны правила русской морфологии, FTS5 unicode61 сам по себе не заменяет полноценный морфологический анализ.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.