utf8_bin против utf_unicode_ci

Мой стол Веб-сайт

Website_Name//column name
Google
Facebook
Twitter
Orkut
Frype
Skype
Yahoo
Wikipedia

Я использую сопоставление utf8_bin, тогда мой запрос на поиск википедии на веб-сайте

Select Website_Name from Website where lower(Website_Name)='wikipedia'

И если я использую utf8_unicode_ci, то мой запрос выбора для поиска википедии на веб-сайте будет

Select Website_Name from Website where Website_Name='wikipedia'

Теперь я хочу знать, какая сортировка лучше всего зависит от следующих запросов.


person Community    schedule 07.06.2012    source источник


Ответы (3)


Это зависит от того, что вам нужно.

Сопоставление utf8_bin сравнивает строки исключительно по их значениям кодовой точки в Юникоде. Если все кодовые точки имеют одинаковые значения, то строки равны. Однако это не работает, когда у вас есть строки с разным составом для объединения меток (составленных и разложенных) или символов, которые канонически эквивалентны, но не имеют одинакового значения кодовой точки. В некоторых случаях использование utf8_bin приведет к тому, что строки не будут совпадать, когда вы ожидаете. Теоретически utf8_bin является самым быстрым, поскольку к строкам не применяется нормализация Unicode, но это может быть не то, что вам нужно.

utf8_general_ci применяет нормализацию Unicode с использованием правил для конкретного языка и сравнивает строки без учета регистра. utf8_general_cs делает то же самое, но сравнивает строки с учетом регистра.

person Delan Azabani    schedule 07.06.2012
comment
так что я должен использовать .будьте конкретными - person ; 07.06.2012
comment
Как я уже сказал, вы должны принимать это решение на основе того, что вам нужно. Судя по тому, что вы пытаетесь сделать, я бы сам согласился с utf8_general_ci. - person Delan Azabani; 07.06.2012
comment
Есть ли недостаток в использовании lower() с utf8_bin - person ; 07.06.2012
comment
Хотя в английском языке то же самое, использование lower() не всегда совпадает со сравнением без учета регистра в некоторых языках, и вы можете столкнуться с проблемами, используя lower() для сравнения без учета регистра. Я бы придерживался использования сортировки без учета регистра. - person Delan Azabani; 07.06.2012

Лично я бы выбрал utf8_unicode_ci, если вы ожидаете, что регистр букв обычно не важен для результатов, которые вы хотите найти.

Сопоставления используются не только во время выполнения, но и при построении индексов MySQL. Таким образом, если какой-либо из этих столбцов появится в индексе, поиск данных в соответствии с правилами сравнения этого сопоставления будет максимально быстрым.

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

mysql> create table utf8 (name varchar(24) charset utf8 collate utf8_general_ci, primary key (name));
Query OK, 0 rows affected (0.14 sec)

mysql> insert into utf8 values ('Roland');
Query OK, 1 row affected (0.00 sec)

mysql> insert into utf8 values ('roland');
ERROR 1062 (23000): Duplicate entry 'roland' for key 'PRIMARY'
mysql> select * from utf8 where name = 'roland';
+--------+
| name   |
+--------+
| Roland |
+--------+
1 row in set (0.00 sec)

mysql> select * from utf8 where binary name = 'roland';
Empty set (0.01 sec)

Это должно быть намного быстрее, чем использование нижнего или верхнего, поскольку в этих случаях MySQL сначала должен сделать копию значения столбца и изменить его регистр букв, а затем применить сравнение. При наличии BINARY он просто сначала использует индекс для поиска совпадений, а затем выполняет сравнение кодовых точек, пока не обнаружит, что значения не равны, что, как правило, будет быстрее.

person Roland Bouman    schedule 07.06.2012
comment
Просто предостережение от моего опыта; использование WHERE BINARY или COLLATE utf8_bin отрицательно влияет на производительность запросов, использующих PRIMARY KEY, когда строка имеет значение utf8_general_ci. Протестировано на MySQL 5.6.22 и 5.6.10. Проблема не появлялась, пока база данных не была под приличной нагрузкой. - person mikeytown2; 02.02.2015

Я использовал «utf8_unicode_ci», который по умолчанию используется в доктрине, мне пришлось изменить его на:

 * @ORM\Table(name = "Table", options={"collate"="utf8_bin"})

Поскольку некоторые из моих составных первичных ключей состояли из текстовых полей. К сожалению, 'utf8_unicode_ci' разрешил "poistný" и "poistny" как одно и то же значение первичного ключа и завершился сбоем при вставке доктрины с флеша. Я не мог просто изменить сопоставление одной части составного первичного ключа, мне пришлось удалить таблицу и создать ее заново. Надеюсь, это сэкономит время кому-то еще ..

person Jiro Matchonson    schedule 18.02.2016
comment
В этой статье utf8_unicode_ci vs utf8_general_ci объясняются различия между utf8_unicode_ci и utf8_general_ci. - person boris1993; 12.12.2019