# 1071 - Указанный ключ был слишком длинным; максимальная длина ключа 767 байт - PullRequest
470 голосов
/ 29 ноября 2009

Когда я выполнил следующую команду:

ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);

Я получил это сообщение об ошибке:

#1071 - Specified key was too long; max key length is 767 bytes

Информация о столбце 1 и столбце 2:

column1 varchar(20) utf8_general_ci
column2  varchar(500) utf8_general_ci

Я думаю, varchar(20) требуется всего 21 байт, а varchar(500) - только 501 байт. Таким образом, общее количество байтов составляет 522, а не 767. Так почему я получил сообщение об ошибке?

#1071 - Specified key was too long; max key length is 767 bytes

Ответы [ 32 ]

1 голос
/ 04 июня 2014

Пожалуйста, проверьте, если sql_mode похоже на

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

если это так, измените на

sql_mode=NO_ENGINE_SUBSTITUTION

OR

перезагрузите сервер, изменив файл my.cnf (добавив следующее)

innodb_large_prefix=on
1 голос
/ 21 февраля 2019

Длина индекса & MySQL / MariaDB


Laravel использует utf8mb4 символ , установленный по умолчанию, который включает поддержку для хранения "emojis" в базе данных. Если вы используете версию MySQL, более раннюю, чем версия 5.7.7, или MariaDB, более раннюю, чем версия 10.2.2, вам может потребоваться вручную настроить длину строки по умолчанию, создаваемую миграциями, чтобы MySQL создавал для них индексы. Вы можете настроить это, вызвав метод Schema :: defaultStringLength в вашем AppServiceProvider:

use Illuminate\Support\Facades\Schema;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}

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

Справка из официальной документации по Laravel: https://laravel.com/docs/5.7/migrations

1 голос
/ 16 ноября 2017

Я нашел этот запрос полезным для определения, какие столбцы имеют индекс, нарушающий максимальную длину:

SELECT
  c.TABLE_NAME As TableName,
  c.COLUMN_NAME AS ColumnName,
  c.DATA_TYPE AS DataType,
  c.CHARACTER_MAXIMUM_LENGTH AS ColumnLength,
  s.INDEX_NAME AS IndexName
FROM information_schema.COLUMNS AS c
INNER JOIN information_schema.statistics AS s
  ON s.table_name = c.TABLE_NAME
 AND s.COLUMN_NAME = c.COLUMN_NAME 
WHERE c.TABLE_SCHEMA = DATABASE()
  AND c.CHARACTER_MAXIMUM_LENGTH > 191 
  AND c.DATA_TYPE IN ('char', 'varchar', 'text')
1 голос
/ 14 мая 2018

В моем случае у меня была эта проблема, когда я выполнял резервное копирование базы данных, используя символы ввода / вывода перенаправления Linux. Поэтому я меняю синтаксис, как описано ниже. PS: используя терминал Linux или Mac.

Резервное копирование (без> перенаправления)

# mysqldump -u root -p databasename -r bkp.sql

Восстановление (без <перенаправления) </p>

# mysql -u root -p --default-character-set=utf8 databasename
mysql> SET names 'utf8'
mysql> SOURCE bkp.sql

Ошибка "Указанный ключ слишком длинный; максимальная длина ключа 767 байт" просто исчезла.

0 голосов
/ 18 января 2019

Из-за ограничений префикса эта ошибка произойдет. 767 байт - это заявленное ограничение префикса для таблиц InnoDB в версиях MySQL до 5.7. Это длина 1000 байтов для таблиц MyISAM. В версии MySQL 5.7 и выше этот предел был увеличен до 3072 байт.

Выполнение следующих действий в службе, сообщающей вам об ошибке, должно решить вашу проблему. Это должно быть выполнено в MYSQL CLI.

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=on;
SET GLOBAL innodb_large_prefix=on;
0 голосов
/ 05 августа 2015

Если вы недавно изменили innodb_log_file_size, попробуйте восстановить предыдущее значение, которое сработало.

0 голосов
/ 20 сентября 2014

Если вы создаете что-то вроде:

CREATE TABLE IF NOT EXISTS your_table (
  id int(7) UNSIGNED NOT NULL AUTO_INCREMENT,
  name varchar(256) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY name (name)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED;

это должно быть что-то вроде

CREATE TABLE IF NOT EXISTS your_table (
      id int(7) UNSIGNED NOT NULL AUTO_INCREMENT,
      name varchar(256) COLLATE utf8mb4_bin NOT NULL,
      PRIMARY KEY (id)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED;

но вам нужно проверить уникальность этого столбца из кода или добавить новый столбец как MD5 или SHA1 столбца varchar

0 голосов
/ 27 декабря 2013

Измените CHARSET поля индекса жалобы на "latin1"
т.е. ALTER TABLE tbl CHANGE myfield myfield varchar (600) Набор символов латинский 1 ПО УМОЛЧАНИЮ НУЛЬ; latin1 занимает один байт для одного символа вместо четырех

0 голосов
/ 02 марта 2019

Мое исправление этой самой проблемы заключалось в добавлении опции в качестве третьего аргумента: charset

queryInterface.createTable(
  tableName,
  { /*... columns*/ },
  { charset: 'utf8' } 
)

В противном случае sequelize создаст таблицы как utf8mb4 .

0 голосов
/ 18 марта 2016

Для меня проблема «# 1071 - указанный ключ был слишком длинным; максимальная длина ключа - 767 байт» была решена после изменения комбинации «первичный ключ / уникальный ключ» путем ограничения размера столбца на 200.

ALTER TABLE `mytable` ADD UNIQUE (
`column1` (200) ,
`column2` (200)
);
...