Подтвердить что ты не робот

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 не разрешает это, поэтому создайте таблицу вручную)

4b9b3361

Ответ 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), чтобы это сработало.