У меня есть система, которая ищет компанию. Я хочу, чтобы, когда пользователь выполняет поиск «Demo», все записи, имеющие «Demo», будут возвращены, например «Демо», «Demo Inc.» и т. Д. Я не хочу, чтобы такие записи, как «Демократические», «Снос» и т. Д. Я думаю, вы поняли мою точку зрения.
Прямо сейчас мой рабочий запрос выглядит примерно так:
select * from table where company LIKE "Demo%"
Но это действительно не повлияло на мое требование. Я также попробовал это:
select * from table where company RLIKE "[[:<:]]demo[[:>:]]"
Единственная проблема в том, что это исключает возможность индексации в моей компании. Таким образом, поиск выполняется очень медленно. Сейчас у меня более миллиона записей. Есть идеи, как это сделать? Если это невозможно сделать в mysql, любая идея, если это возможно в PHP? Благодаря!
Создайте полный текстовый индекс, а затем вы можете искать более легко.
ALTER TABLE table ADD FULLTEXT INDEX fulltext_index; SELECT * FROM table WHERE MATCH (company) AGAINST ('+Demo' IN BOOLEAN MODE);
dev.mysql.com/doc/refman/5.6/en/fulltext-search.html
Выстрел в темноте в соответствии с моим комментарием. Если вы всегда будете получать точные критерии соответствия. не было бы лучше выполнить стандартный запрос выбора?
SELECT * FROM table WHERE company='The Demo'
Или для практического:
$Search = $_GET['company']; SELECT * FROM table WHERE company='$Search'
Очевидно, что при работе с пользовательскими вводами и запросами рекомендуется использовать лучшие методы.
Полученные результаты будут либо в строках, найденных как Demo , демонстрация будет возвращена, либо ничего.
Если вы не всегда имеете точное соответствие. Вы могли бы снова использовать $ _GET с добавленным значением, т.е. $ _GET ['Exact'] и иметь две разные функции:
function ExactMatch ($DB,$Company){ /* Query to get exact match as exampled */ } function NotExact($DB,$Company){ /* Query using LIKE syntax */ }
и подтвердите:
if (isset($_GET['Exact'])){ if ($_GET['Exact'] === 1){ ExactMatch($DB,$_GET['Company']); }else{ NotExact($DB,$_GET['Company']) } }
Кроме того, возможно прочитать DBA.stackexchange:
Я не понимаю, почему 1M является проблемой, которую я только что протестировал на моем ноутбуке MySQL MyISAM, который также имеет компанию, но это 250K строк, и это заняло 3,3 мс, и поле не индексируется. вы можете попробовать
$search='Demo'; $regex="/\b$search\b/i"; $sql = "select * from table where company like '%$search%'; //... get the results foreach($results as $companyName){ if(preg_match($regex,$companyName,$match)){ //here you got a match } }
SELECT * FROM table_name WHERE company LIKE "% Demo %" OR company LIKE "Demo %" OR company="Demo";
Лучшим решением является создание полнотекстового индекса:
create fulltext index `i_company` on `table`(`company`);
Затем вы можете искать:
select * from `table` where match(company) against ('Demo');
Подробнее о полнотекстовом поиске mysql .
В зависимости от вашей версии MySQL полный текстовый индекс доступен для MyISAM в версии 5.5 или менее и доступен для InnoDB с 5.6.
Вы можете использовать REGEXP
и REGEXP
[[:<:]]
и [[:>:]]
:
SELECT * FROM `table` WHERE company REGEXP '[[:<:]]Demo[[:>:]]';
Другое решение
SELECT * FROM `table` WHERE company REGEXP '(^|[[:space:]])Demo([[:space:]]|$)';
Демо-версия SQL Fiddle
Попробуйте это, это может помочь вам ..
SELECT * FROM table_name WHERE company LIKE "%Demo%";
Попробуйте протестировать пространство с обеих сторон:
select * from table where company LIKE "Demo %" OR company LIKE "% Demo"
Однако, как вы заявили, вам нужно использовать ваши индексы, и все, что связано с ведущим шаблоном, не будет использовать индексы.
Предварительно обработайте свои имена записей:
Затем, когда пользователь выполняет поиск:
Пример stemmed_words Столбцы таблицы:
id, stemmed_word // Eg. 1 (auto generated), "Demo"
Пример record_index Столбцы таблицы:
record_id, stemmed_word_id, occurrence_count // Eg. 1 (auto generated), 1 (ID of "Demo" in stemmed_words table), 2 (2 occurrences)
Вот базовое учебное пособие, в котором вы можете начать с сокращения и подсчета слов