Ответ 1
NO_ENGINE_SUBSTITUTION отключено с INNODB неактивным, плохая комбинация
- До MySql 5.5 по умолчанию sqlmode была пустая строка, это означает, что по умолчанию значение sqlmode NO_ENGINE_SUBSTITUTION не было установлено
В соответствии с документами MySql (см. https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html#sqlmode_no_engine_substitution) это значение sqlmode NO_ENGINE_SUBSTITUTION:
Управление автоматической заменой механизма хранения по умолчанию, когда такой как CREATE TABLE или ALTER TABLE, указывает хранилище который отключен или не скомпилирован.
Поскольку механизмы хранения могут быть подключаемы во время выполнения, недоступны двигатели обрабатываются одинаково:
С отключенным NO_ENGINE_SUBSTITUTION для CREATE TABLE значение по умолчанию используется двигатель, и появляется предупреждение, если требуемый двигатель недоступен. Для ALTER TABLE появляется предупреждение, и таблица не изменено.
При включенном NO_ENGINE_SUBSTITUTION возникает ошибка, и таблица не создается или не изменяется, если желаемый движок недоступен.
- Итак: если NO_ENGINE_SUBSTITUTION отключен и INNODB отключен, MySql переключится на MYISAM также, если вы укажете INNODB в инструкции CREATE TABLE.
- Если созданная вами таблица в порядке для MYISAM, вы получите предупреждение, и таблица будет создана. Это не ваш случай, ваш оператор создания включает индекс, который превышает ограничение на 1000 байтов MYISAM, тогда создание завершилось с ошибкой 1071, сообщающей об ошибке MYISAM. Это потому, что рабочий движок MYISAM, а не INNODB.
Доказательство
MySql версия 5.1.56 сообщество
Случай 1:
Options in my.cnf
sql-mode=""
default-storage-engine=MYISAM
skip-innodb uncommented (without#)
Return on execution of your create statement:
Error Code: 1071. Specified key was too long; max key length is 1000 bytes
Explanation: INNODB is not active, the engine is automatically switched to MYISAM
that returns this error as they key is longer than MYISAM 1000 bytes limit.
The key length is:
2 fields x 255 char x 3 bytes utf8 encoding + 2 x 1 length byte = 1532 bytes
Случай 2:
Options in my.cnf
sql-mode="NO_ENGINE_SUBSTITUTION"
default-storage-engine=MYISAM
skip-innodb uncommented (without#)
Return on execution of your create statement:
Error Code: 1286. Unknown table engine 'INNODB'
Explanation: INNODB is not active but the engine substitution is not permitted
by sql mode therefore the DB returns an error about the attempt of using a disabled engine.
Случай 3:
Options in my.cnf
sql-mode="NO_ENGINE_SUBSTITUTION"
default-storage-engine=MYISAM
skip-innodb commented (with#)
Return on execution of your create statement:
Table creation OK!
Explanation: INNODB is active (skip-innodb commented) and it is used also if
the default engine is MYISAM.
Чтобы воспроизвести тесты, перезапустите MySql после каждого изменения my.cnf.
Так как MySql версия 5.6 sqlmode по умолчанию не более пуста и содержит NO_ENGINE_SUBSTITUTION, кроме того, INNODB является механизмом по умолчанию, поэтому ошибку трудно встретить.
ДРУГИЕ ИСПЫТАНИЯ
Нет другого способа воспроизведения ошибки:
Error Code: 1071. Specified key was too long; max key length is 1000 bytes
при попытке создать таблицу INNODB.
В INNODB у вас есть два типа ERROR 1071:
Error Code: 1071. Specified key was too long; max key length is 767 bytes
это не имеет никакого отношения к innodb_large_prefix ON или OFF, но относится только к размеру одного столбца VARCHAR, используемого в качестве индекса.
Mysql хранит varchar utf8 с 3 байтами плюс 1 байт для длины до 255 символов и 2 после (см. http://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html), поэтому, если вы попытаетесь установить ключ с VARCHAR (256) utf8 вы получаете:
256 x 3 + 2 = 770 bytes
и вы получите предыдущую ошибку, так как максимальная длина ключа для одного столбца составляет 767 байт для таблицы InnoDB. VARCHAR (255) в порядке, потому что:
255 x 3 + 1 = 766 bytes
Я тестировал его на четырех установках Mysql, версии 5.1.56, 5.5.33, 5.6 и 5.7, и это подтверждено. Нет проблемы с вашим запросом с VARCHAR (255), выпуском с VARCHAR (256):
Error Code: 1071. Specified key was too long; max key length is 767 bytes
Как вы можете видеть, сообщение отличается, потому что это сообщение INNODB, а не MYISAM!
Другой тип ERROR 1071 для таблиц INNODB:
Error Code: 1071. Specified key was too long; max key length is 3072 bytes
Это связано с ключами с несколькими столбцами. Чтобы эти ключи были включены, вам необходимо установить innodb_large_prefix для включения. В любом случае, если вы попытаетесь запустить что-то вроде этого:
CREATE TABLE `phppos_modules_actions` (
`action_id` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`module_id` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`action_name_key` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`action_name_key1` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`action_name_key2` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL ,
`sort` INT NOT NULL ,
PRIMARY KEY ( `action_id` , `module_id`, `action_name_key`, `action_name_key1`, `action_name_key2` )
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
С помощью ключа из 5 столбцов utf8 VARCHAR (255), то есть 3830 байт, вы столкнетесь с:
Error Code: 1071. Specified key was too long; max key length is 3072 bytes
Экзотическая гипотеза
Во время поиска причины я сформулировал и протестировал разные и довольно странные гипотезы:
Формат ROW
Протестировано REDUNDANT, COMPACT, COMPRESS, DYNAMIC: не влияет на создание таблицы с вашим выражением.
Формат файла
Протестированная Antelope и Barracuda: никакого влияния на создание таблицы с вашим выражением.
MySql построен
Протестировано 32-битное и 64-битное MySql: не влияет на создание таблицы с вашим выражением.
Другие аналогичные отказы
Здесь вы можете найти ту же ошибку в той же ситуации:
https://www.drupal.org/node/2466287
Я тестировал этот оператор в трех тестовых ситуациях, перечисленных в PROOF, и он воспроизводил точно такое же поведение, как ваше, поэтому я могу сказать, что проблема такая же. В этом случае они переключились на другую БД, но проблема заключается в сочетании настроек, а не версии БД.
Ссылки
Здесь очень хорошая статья индексации с INNODB:
http://mechanics.flite.com/blog/2014/07/29/using-innodb-large-prefix-to-avoid-error-1071/
ПРЕДУПРЕЖДЕНИЕ: отключив INNODB, раскомментировав skip-innodb в my.cnf после создания таблицы INNODB с индексом более 1000, не разрешит запуск службы MySql
Привет