Подход демонстрируемый в вопросе должен (в основном) прекрасно работают в MySQL по следующим причинам:
Collation (не следует путать с кодированием) является набор или правила, которые определяют, как сортировать и сравнивать символы, обычно используемые для тиражирования на уровне базы данных ожиданий пользователей с точки зрения культуры (если я ищу cafe
I , ожидайте, чтобы найти café
).
Сортировка играет важную роль в уникальных ограничениях, поскольку она устанавливает определение уникального.
Двоичные сортировки специально предназначены для игнорирования культурных правил и работы на уровне байтов, поэтому utf8mb4_bin
- правильный выбор здесь.
MySQL позволяет установить комбинацию кодирования и сопоставления с гранулярностью на уровне столбца.
Если в определении столбца отсутствует сортировка, он будет использовать таблицу уровня один.
Если в определении таблицы отсутствует сортировка, он будет использовать уровень базы данных один.
Если в определении базы данных отсутствует сортировка, она будет использовать серверный уровень один.
Стоит также отметить, что MySQL будет конвертировать между кодировками прозрачно до тех пор, как:
- кодирования Подключения правильно установить
- преобразования физически возможно (например, все символы источника также принадлежат к целевой кодировке)
По этой последней причине VARBINARY
, возможно, не лучший выбор для столбца, который по-прежнему является текстовым, поскольку он ns дверь для получения café
, хранящейся из соединения, настроенного для использования ISO-8859-1, и не может правильно извлечь его из соединения, настроенного для использования UTF-8.
Примечание стороны: определение таблицы показано, может вызвать следующее сообщение об ошибке:
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
Индексы могут иметь относительно небольшой максимальный размер. От docs:
If innodb_large_prefix is enabled (the default), the index key prefix limit is 3072 bytes for InnoDB tables that use DYNAMIC or COMPRESSED row format. If innodb_large_prefix is disabled, the index key prefix limit is 767 bytes for tables of any row format.
innodb_large_prefix is deprecated and will be removed in a future release. innodb_large_prefix was introduced in MySQL 5.5 to disable large index key prefixes for compatibility with earlier versions of InnoDB that do not support large index key prefixes.
The index key prefix length limit is 767 bytes for InnoDB tables that use the REDUNDANT or COMPACT row format. For example, you might hit this limit with a column prefix index of more than 255 characters on a TEXT or VARCHAR column, assuming a utf8mb3 character set and the maximum of 3 bytes for each character.
Attempting to use an index key prefix length that exceeds the limit returns an error. To avoid such errors in replication configurations, avoid enabling innodb_large_prefix on the master if it cannot also be enabled on slaves.
С utf8_mb8 выделяет 4 байта на символ, 767 предел будет потоплен только 192 символов.
У нас есть еще одна проблема:
mysql> CREATE TABLE `dummy` (
-> `key` varchar(191) COLLATE utf8mb4_bin NOT NULL,
-> UNIQUE KEY `key` (`key`)
->)
-> ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO `dummy` (`key`) VALUES ('one');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO `dummy` (`key`) VALUES ('one ');
ERROR 1062 (23000): Duplicate entry 'one ' for key 'key'
Pardon?
mysql> INSERT INTO `dummy` (`key`) VALUES ('One');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO `dummy` (`key`) VALUES ('öne');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM `dummy`;
+-----+
| key |
+-----+
| One |
| one |
| öne |
+-----+
3 rows in set (0.00 sec)
Эта последняя проблема представляет интересную тонкость MySQL-сопоставлений. Из docs:
All MySQL collations are of type PADSPACE. This means that all CHAR, VARCHAR, and TEXT values in MySQL are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant
[...] For those cases where trailing pad characters are stripped or comparisons ignore them, if a column has an index that requires unique values, inserting into the column values that differ only in number of trailing pad characters will result in a duplicate-key error.
Я бы осмелился сказать то, что VARBINARY
типа это единственный способ преодолеть это ...
Это по умолчанию. Вы переопределяете их в своем заявлении 'CREATE TABLE'? –
Álvaro, какие части вы имеете в виду? Весь SQL представлен как представленный. –
Версия 5.7.17. –