Utf8_bin vs. 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'
Теперь я хочу знать, какая сортировка лучше всего в зависимости от следующих запросов
Ответы
Ответ 1
Это зависит от того, что вам нужно.
Сравнение utf8_bin
сравнивает строки, основанные исключительно на значениях Unicode code point. Если все кодовые точки имеют одинаковые значения, то строки равны. Однако это разваливается, когда у вас есть строки с различным составом для объединения меток (составленных против разложенных) или символов, которые канонически эквивалентны, но не имеют одинакового значения кодовой точки. В некоторых случаях использование utf8_bin
приведет к тому, что строки не будут соответствовать, когда вы их ожидаете. Теоретически utf8_bin
является самым быстрым, поскольку для строк не применяется нормализация Юникода, но это может быть не то, что вы хотите.
utf8_general_ci
применяет нормализацию Unicode с использованием специфичных для языка правил и сравнивает строки без учета регистра. utf8_general_cs
делает то же самое, но сравнивает строки случайным образом.
Ответ 2
Лично я бы пошел с 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 на месте он просто будет использовать индекс сначала, чтобы найти совпадения, а затем выполнить кодовую точку путем сравнения кодовой точки, пока не найдет значения, которые не будут равны, что обычно будет быстрее.
Ответ 3
Я использовал "utf8_unicode_ci", который по умолчанию является доктриной, мне пришлось изменить его на:
* @ORM\Table(name = "Table", options={"collate"="utf8_bin"})
Так как некоторые из моих составных первичных ключей состояли из текстовых полей. К сожалению, "utf8_unicode_ci" разрешил "poistný" и "poistny" как ту же ценность первичного ключа и закончил сбой при добавлении доктрины. Я не мог просто изменить сортировку одной части составного первичного ключа, пришлось отказаться от таблицы и воссоздать. Надеюсь, это сэкономит время кому-то другому.