# 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. 그것은 성숙한 프로젝트 인 phpdevshell에서 나왔습니다. 그래서 저는이 사람들이 그들이 무엇을하고 있는지 알고 있다고 생각합니다.
단서 감사합니다.
phpMyAdmin을 사용하고 있습니다.
@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`;
menu_link
열에 주어진 문자열 길이 이하의 행 비율을 알려줍니다 . 다음과 같은 출력이 표시 될 수 있습니다.
+---------------+---------------+---------------+----------------+
| pct_length_10 | pct_length_20 | pct_length_50 | pct_length_100 |
+---------------+---------------+---------------+----------------+
| 21.78 | 80.20 | 100.00 | 100.00 |
+---------------+---------------+---------------+----------------+
이것은 문자열의 80 %가 20 자 미만이고 모든 문자열이 50 자 미만임을 알려줍니다. 따라서 접두사 길이 50 이상을 인덱싱 할 필요가 없으며 255 자의 전체 길이를 인덱싱 할 필요가 없습니다.
PS: The INT(1)
and INT(32)
data types indicates another misunderstanding about MySQL. The numeric argument has no effect related to storage or the range of values allowed for the column. INT
is always 4 bytes, and it always allows values from -2147483648 to 2147483647. The numeric argument is about padding values during display, which has no effect unless you use the ZEROFILL
option.
This error means that length of index index
is more then 1000 bytes. MySQL and storage engines may have this restriction. I have got similar error on MySQL 5.5 - 'Specified key was too long; max key length is 3072 bytes' when ran this script:
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 is multi-bytes, and key length is calculated in this way - 500 * 3 * 6 = 9000 bytes.
But note, next query works!
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;
...because I used CHARSET=latin1, in this case key length is 500 * 6 = 3000 bytes.
run this query before creating or altering table.
SET @@global.innodb_large_prefix = 1;
this will set max key length to 3072 bytes
I had this issue, and solved by following:
Cause
There is a known bug with MySQL related to MyISAM, the UTF8 character set and indexes that you can check here.
Resolution
Make sure MySQL is configured with the InnoDB storage engine.
Change the storage engine used by default so that new tables will always be created appropriately:
set GLOBAL storage_engine='InnoDb';
For MySQL 5.6 and later, use the following:
SET GLOBAL default_storage_engine = 'InnoDB';
And finally make sure that you're following the instructions provided in Migrating to MySQL.
This index size limit seems to be larger on 64 bit builds of MySQL.
I was hitting this limitation trying to dump our dev database and load it on a local VMWare virt. Finally I realized that the remote dev server was 64 bit and I had created a 32 bit virt. I just created a 64 bit virt and I was able to load the database locally.
I have just made bypass this error by just changing the values of the "length" in the original database to the total of around "1000" by changing its structure, and then exporting the same, to the server. :)
I was facing same issue, used below query to resolve it.
While creating DB you can use utf-8 encoding
eg. create database my_db character set utf8 collate utf8_bin;
'Programing' 카테고리의 다른 글
base64로 이미지 소스를 설정하는 방법 (0) | 2020.09.25 |
---|---|
Git 하위 모듈. (0) | 2020.09.24 |
Windows에서 Meld와 Git mergetool (0) | 2020.09.24 |
내 Ruby 프로그램이 실행중인 운영 체제를 어떻게 찾을 수 있습니까? (0) | 2020.09.24 |
'uint32_t'식별자를 찾을 수 없음 오류 (0) | 2020.09.24 |