MySQL VARCHAR (255) UTF8 слишком длинный для ключа, но максимальная длина составляет 1000 байтов - PullRequest
41 голосов
/ 30 мая 2011

Я знаю, что было много вопросов по этому поводу, но я думаю, что моя математика верна.

  • MySQL резервирует 3 байта на символ UTF8.
  • MyISAM допускает ключи длиной 1000 байт.
  • Мой UTF8 VARCHAR (255) должен быть 255 * 3 = 765 байтов

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

Ответы [ 3 ]

41 голосов
/ 04 апреля 2016

Если вы используете 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, которые используют ДИНАМИЧНЫЙ или СЖАТЫЙ формат строки. Если innodb_large_prefix отключен, предел префикса ключа индекса составляет 767 байт для таблиц любого формата строки.

innodb_large_prefix устарела в MySQL 5.7.7 и будет удалена в будущем выпуске. innodb_large_prefix был представлен в MySQL 5.5 отключить префиксы большого индекса ключа для совместимости с ранее версии InnoDB, которые не поддерживают префиксы ключа большого индекса.

Подводя итог, ограничение существует только для совместимости и будет увеличено в будущих версиях.

7 голосов
/ 18 июля 2012

Любой, кому нужна большая длина ключа, должен взглянуть на innodb_large_prefix

визит http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_large_prefix

7 голосов
/ 31 мая 2011

MySQL резервирует максимальную сумму для поля UTF8, которая составляет 4 байта, поэтому вы превышаете ограничение в 1000 байт.Я рекомендую создать varchar со значением менее 255 или создать его без UTF8.

Оба эти решения, вероятно, не подходят вам, или вы бы уже попробовали это.

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

Поскольку вам, вероятно, нужен UTF8,Я бы серьезно посмотрел на уменьшение колонки varchar (255) до 250 (или 249), чтобы это сработало.

...