Поиск PHP / Mysql – чувствительный к регистру

Я использую следующие PHP и MySql для извлечения строк из таблицы,

$search_word=$_GET['search_word']; $search_word_new=mysql_escape_string($search_word); $search_word_fix=str_replace(" ","%",$search_word_new); $sql=mysql_query("SELECT * FROM tweets WHERE content LIKE '%$search_word_fix%' ORDER BY votes DESC LIMIT 20"); 

Поле «content» – поле TEXT, содержащее твиты.

Проблема в том, что если я ищу « S tackoverflow», я получаю все результаты, содержащие «Stackoverflow», но никаких результатов, если текст является «потоком перехода». В основном поиск чувствителен к регистру.

Можно ли изменить запрос или PHP, поэтому при поиске «Stackoverflow» возвращаются результаты с верхним и нижним регистром?

Можешь попробовать:

 $search_word_fix=strtolower(str_replace(" ","%",$search_word_new)); $sql=mysql_query("SELECT * FROM tweets WHERE lower(content) LIKE '%$search_word_fix%' ORDER BY votes DESC LIMIT 20"); 
  • Я добавил strtolower чтобы сделать $search_word_fix все в нижнем регистре.
  • И в предложении where я изменил content на lower(content) чтобы сравнить с строчным content .

Вы могли бы внести оба эти изменения в запрос, как было предложено в другом ответе.

Зафиксируйте случаи как поискового термина, так и значения столбца:

 SELECT * FROM tweets WHERE LOWER(content) LIKE LOWER('%$search_word_fix%') ORDER BY votes DESC LIMIT 20 

или:

 SELECT * FROM tweets WHERE UPPER(content) LIKE UPPER('%$search_word_fix%') ORDER BY votes DESC LIMIT 20 

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

«Правильный» способ сделать это – установить его в регистр без учета регистра:

 CREATE TABLE foo (col1 varchar(24) COLLATE utf8_bin,col2 varchar(24) COLLATE utf8_general_ci); Query OK, 0 rows affected (0.03 sec) DB 5.1.49-1-log:test mysql> INSERT INTO foo VALUES ('stackoverflow','stackoverflow'); Query OK, 1 row affected (0.01 sec) DB 5.1.49-1-log:test mysql> SELECT * FROM foo WHERE col1 LIKE 'Stackoverflow'; Empty set (0.00 sec) DB 5.1.49-1-log:test mysql> SELECT * FROM foo WHERE col2 LIKE 'Stackoverflow'; +---------------+---------------+ | col1 | col2 | +---------------+---------------+ | stackoverflow | stackoverflow | +---------------+---------------+ 1 row in set (0.00 sec) DB 5.1.49-1-log:test mysql> SELECT * FROM foo WHERE col1 COLLATE utf8_general_ci LIKE 'Stackoverflow'; +---------------+---------------+ | col1 | col2 | +---------------+---------------+ | stackoverflow | stackoverflow | +---------------+---------------+ 1 row in set (0.00 sec) 

Измените COLLATION столбца, о котором идет речь ( content ), чтобы он не utf8mb4_unicode_ci регистр, например utf8mb4_unicode_ci .

Выполнение фальцовки флага в PHP является дорогостоящим и неэффективным.

mysql> SELECT * FROM myDb.myTable WHERE username = 'test980'; 1 строка в наборе (0,00 сек)

mysql> SELECT * FROM myDb.myTable WHERE username = 'TEST980'; Пустой набор (0,00 сек)

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

SELECT * FROM myDb.myTable WHERE UCASE (имя пользователя) = 'TEST980';

который фактически делает строковое сравнение нечувствительным к регистру, несмотря на выбранный набор двоичных символов.

Это все о выборе наилучшего сопоставления при создании базы данных MySql.

  • utf8_unicode_ci полезен, если вы хотите точно отсортировать немецкий набор символов, но он медленный.
  • utf8_general_ci по умолчанию является стандартом при создании набора символов базы данных MySQL utf8, и это самый быстрый, но не чувствительный к регистру.
  • Правило большого пальца: всегда используйте utf8_general_ci для MySQL и сопоставляйте utf8_bin, если требуется регистр символов, или используйте SELECT BINARY в своем заявлении.