MySQL VARCHAR (255) UTF8 слишком длинный для ключа, но максимальная длина - 1000 байт
Я знаю, что в этом было много вопросов, но я думаю, что моя математика правильная.
- MySQL резервирует 3 байта на символ UTF8.
- MyISAM позволяет использовать ключи длиной 1000 байт.
- Мой UTF8 VARCHAR (255) должен быть
255 * 3 = 765
bytes
Если UNQUE не требует дополнительных 200 + байтов на запись, почему это не работает?
mysql> ALTER TABLE entry ADD UNIQUE INDEX (name(255));
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes
Есть ли что-нибудь, что я могу сделать с этим?
EDIT:
Оказалось, что предел равен 250. Кажется, что число символов составляет 4 байта для уникальных индексов, но я не знаю почему.
ИЗМЕНИТЬ 2:
Спасибо, Владислав Вайнтруб, кодировка действительно utf8mb4. Это решает загадку. Я не видел никакой документации об этом изменении.
Я предполагаю, что он строит не уникальный индекс, неявно обрезая поле, что неприемлемо для уникальных индексов, поэтому он отказывается.
Если вы повторно представите свой комментарий в качестве ответа, я был бы рад принять его.
Решение: Укажите utf8, а не utf8mb4 (администратор MySQL не разрешает это, поэтому создайте таблицу вручную)
Ответы
Ответ 1
Если вы используете utf8mb4, и у вас есть уникальные индексы для столбцов varchar, длина которых превышает 191 символ, вам нужно включить innodb_large_prefix, чтобы разрешить большие столбцы в индексах, потому что utf8mb4 требует больше места для хранения, чем utf8 или latin1. Добавьте в файл my.cnf следующее.
[mysqld]
innodb_file_format=barracuda
innodb_file_per_table=1
innodb_large_prefix=1
init_connect='SET collation_connection = utf8mb4_unicode_ci'
init_connect='SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
Подробнее о том, почему и будущее от Документация MySQL 5.7:
Если innodb_large_prefix включен (по умолчанию в MySQL 5.7.7), префикс префикса ключа составляет 3072 байта для таблиц InnoDB, которые используют DYNAMIC или COMPRESSED. Если innodb_large_prefix отключен, префикс префикса ключа составляет 767 байт для таблиц любого формата строки.
innodb_large_prefix устарел в MySQL 5.7.7 и будет удален в будущем выпуске. innodb_large_prefix был представлен в MySQL 5.5 для отключения больших префиксов ключевых ключей для совместимости с предыдущими версии InnoDB, которые не поддерживают префиксы больших индексов.
Подводя итог, предел существует только для совместимости и будет увеличен в будущих версиях.
Ответ 2
MySQL резервирует максимальное количество для поля UTF8
, которое составляет 4 байта, поэтому вы превышаете ограничение в 1000 байт. Моя рекомендация - создать varchar
меньше 255 или создать без UTF8
.
Возможно, оба эти решения вам не подходят, иначе вы бы уже это попробовали.
Единственное другое решение, которое я могу придумать, - это разбить столбец на 2 маленьких столбца и создать уникальный индекс для обоих этих полей, но я считаю, что вы получите ту же ошибку, что и выше.
Поскольку вам, вероятно, нужен UTF8
, я бы серьезно подумал о том, чтобы уменьшить колонку varchar(255)
до 250 (или 249), чтобы это сработало.
Ответ 3
Любой, кому нужна большая длина ключа, должен смотреть на innodb_large_prefix
посетите http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_large_prefix