#1071 - указанный ключ был слишком длинным; максимальная длина ключа составляет 1000 байт



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



Я получаю вышеуказанную ошибку для следующего запроса:



CREATE TABLE IF NOT EXISTS `pds_core_menu_items` (
`menu_id` varchar(32) NOT NULL,
`parent_menu_id` int(32) unsigned DEFAULT NULL,
`menu_name` varchar(255) DEFAULT NULL,
`menu_link` varchar(255) DEFAULT NULL,
`plugin` varchar(255) DEFAULT NULL,
`menu_type` int(1) DEFAULT NULL,
`extend` varchar(255) DEFAULT NULL,
`new_window` int(1) DEFAULT NULL,
`rank` int(100) DEFAULT NULL,
`hide` int(1) DEFAULT NULL,
`template_id` int(32) unsigned DEFAULT NULL,
`alias` varchar(255) DEFAULT NULL,
`layout` varchar(255) DEFAULT NULL,
PRIMARY KEY (`menu_id`),
KEY `index` (`parent_menu_id`,`menu_link`,`plugin`,`alias`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


кто-нибудь знает, почему и как это исправить?
Уловка - этот же запрос отлично работает на моей локальной машине, и работал также на моем предыдущем хосте. Btw.it ' s из зрелого проекта-phpdevshell-так что я бы предположил, что это ребята знают, что они делают, хотя вы никогда не знаете.



любая подсказка приветствуется.



Я использую phpMyAdmin.

815   7  

7 ответов:

как говорит @ Devart, общая длина вашего индекса слишком велика.

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

лучшая практика заключается в использовании индексы префикс таким образом, вы индексируете только левую подстроку данных. Большинство данных будет в любом случае намного короче, чем 255 символов.

вы можете указать длину префикса для каждого столбца, как вы определите индекс. Например:

...
KEY `index` (`parent_menu_id`,`menu_link`(50),`plugin`(50),`alias`(50))
...

но какова лучшая длина префикса для данного столбца? Вот способ узнать:

SELECT
 ROUND(SUM(LENGTH(`menu_link`)<10)*100/COUNT(`menu_link`),2) AS pct_length_10,
 ROUND(SUM(LENGTH(`menu_link`)<20)*100/COUNT(`menu_link`),2) AS pct_length_20,
 ROUND(SUM(LENGTH(`menu_link`)<50)*100/COUNT(`menu_link`),2) AS pct_length_50,
 ROUND(SUM(LENGTH(`menu_link`)<100)*100/COUNT(`menu_link`),2) AS pct_length_100
FROM `pds_core_menu_items`;

он говорит вам долю строк, которые имеют не более заданной длины строки в . Вы можете увидеть вывод следующим образом:

+---------------+---------------+---------------+----------------+
| pct_length_10 | pct_length_20 | pct_length_50 | pct_length_100 |
+---------------+---------------+---------------+----------------+
|         21.78 |         80.20 |        100.00 |         100.00 |
+---------------+---------------+---------------+----------------+

это говорит вам, что 80% ваших строк меньше 20 символов, и все ваши строки меньше 50 символов. Так что нет необходимости индексировать больше, чем a длина префикса 50, и уж точно не нужно индексировать всю длину 255 символов.

ЗЫ:INT(1) и INT(32) типы данных указывает на другое недоразумение о MySQL. Числовой аргумент не имеет никакого эффекта, связанного с хранением или диапазоном значений, разрешенных для столбца. INT всегда 4 байта, и это всегда позволяет значения от -2147483648 до 2147483647. Числовой аргумент - это заполнение значений во время отображения, которое не имеет никакого эффекта, если вы не используете ZEROFILL выбор.

эта ошибка означает, что длина индекса index больше чем 1000 байт. MySQL и механизмы хранения могут иметь это ограничение. Я получил аналогичную ошибку на MySQL 5.5- 'указанный ключ был слишком длинным; максимальная длина ключа составляет 3072 байта' при запуске этого скрипта:

CREATE TABLE IF NOT EXISTS test_table1 (
  column1 varchar(500) NOT NULL,
  column2 varchar(500) NOT NULL,
  column3 varchar(500) NOT NULL,
  column4 varchar(500) NOT NULL,
  column5 varchar(500) NOT NULL,
  column6 varchar(500) NOT NULL,
  KEY `index` (column1, column2, column3, column4, column5, column6)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

UTF8 является многобайтовым, и длина ключа рассчитывается таким образом - 500 * 3 * 6 = 9000 байт.

но обратите внимание, следующий запрос работает!

CREATE TABLE IF NOT EXISTS test_table1 (
  column1 varchar(500) NOT NULL,
  column2 varchar(500) NOT NULL,
  column3 varchar(500) NOT NULL,
  column4 varchar(500) NOT NULL,
  column5 varchar(500) NOT NULL,
  column6 varchar(500) NOT NULL,
  KEY `index` (column1, column2, column3, column4, column5, column6)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

...потому что я использовал CHARSET=latin1, в этом случае ключ длина-500 * 6 = 3000 байт.

выполните этот запрос перед созданием или изменением таблицы.

SET @@global.innodb_large_prefix = 1;

это установит максимальную длину ключа в 3072 байта

этот предел размера индекса, кажется, больше на 64-битных сборках MySQL.

Я ударил это ограничение, пытаясь сбросить нашу базу данных dev и загрузить ее на локальном VMWare virt. Наконец я понял, что удаленный сервер dev был 64-битным, и я создал 32-битный virt. Я только что создал 64-битный Вирт, и я смог загрузить базу данных локально.

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

ссылка:

причина

существует известная ошибка с MySQL, связанная с MyISAM, символом UTF8 набор и индексы, которые вы можете проверить здесь.

разрешение

  • убедитесь, что MySQL настроен с механизмом хранения InnoDB.

  • изменить механизм хранения используется по умолчанию, чтобы новые таблицы всегда создавались соответствующим образом:

    set GLOBAL storage_engine='InnoDb';

  • для MySQL 5.6 и более поздних версий используйте следующее:

    SET GLOBAL default_storage_engine = 'InnoDB';

  • и, наконец, убедитесь, что вы следуете инструкциям в миграция в MySQL.

Я только что сделал обход этой ошибки, просто изменив значения " длины "в исходной базе данных на общую сумму около" 1000", изменив ее структуру, а затем экспортировав ее на сервер. :)

я столкнулся с той же проблемой, используемой ниже запроса, чтобы решить ее.

при создании БД вы можете использовать кодировку utf-8

например. create database my_db character set utf8 collate utf8_bin;

Comments

    Ничего не найдено.