#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은 성숙한 프로젝트인 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자 전체를 인덱싱할 필요도 없습니다.
: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 바이트입니다.
이 문제를 안고, 다음과 같이 해결했습니다.
원인
MySQL에는 UTF8 문자 집합 및 인덱스와 관련된 알려진 버그가 있습니다.
결의안
MySQL이 InnoDB 스토리지 엔진으로 구성되어 있는지 확인합니다.
새 테이블이 항상 적절하게 생성되도록 기본적으로 사용되는 스토리지 엔진을 변경합니다.
set GLOBAL storage_engine='InnoDb';
MySQL 5.6 이상의 경우 다음을 사용합니다.
SET GLOBAL default_storage_engine = 'InnoDB';
마지막으로 MySQL로 마이그레이션에 제공된 지침을 따르고 있는지 확인합니다.
테이블을 만들거나 변경하기 전에 이 쿼리를 실행합니다.
SET @@global.innodb_large_prefix = 1;
그러면 최대 키 길이가 3072바이트로 설정됩니다.
저도 같은 문제에 직면해 있었습니다.이 문제를 해결하기 위해 아래 쿼리를 사용했습니다.
사용할 수 있는 DB 생성 중utf-8
부호화를 실시합니다.
예:create database my_db character set utf8 collate utf8mb4;
편집:
(댓글 제안 검토)
변경되었다.utf8_bin
로.utf8mb4
이 인덱스 크기 제한은 MySQL의 64비트 빌드에서 더 큰 것 같습니다.
개발 데이터베이스를 덤프하여 로컬 VMWare 가상 시스템에 로드하려고 했습니다.최종적으로 리모트 개발 서버가 64비트이고 32비트 가상 서버를 작성했다는 것을 알게 되었습니다.방금 64비트 버추얼을 생성하여 데이터베이스를 로컬로 로드할 수 있었습니다.
이 에러는, 원래의 데이타베이스내의 「length」의 값을 약 1000 의 합계치로 변경해, 그 구조를 변경해 서버에 내보내는 것으로 바이패스 하고 있습니다.:)
Laravel 7 또는 Laravel 8을 사용하는 경우 구성/데이터베이스로 이동합니다.php
'engine' => 'innoDb',
특히 WAMP 또는 XAMP를 사용할 때 사용할 수 있습니다.
음, 나는 방금 에서 변했어.MyISAM
로.InnoDB
이것처럼.
변경 전
ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
변경 후
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
이 오류가 발생하여 인덱스된 외부 키 열의 테이블 열 길이를 작게 변경했기 때문에 다음과 같이 변경했습니다.
VARCHAR(1024)
수신인:
VARCHAR(512)
쿼리를 다시 실행합니다.
SQL이 직접 생성되지 않은 경우 열 길이를 확인하고 보통 길이로 설정하십시오.
나는 많은 속임수를 써봤지만, 어느 것도 통하지 않았다.그러다가 가장 간단하고 좋은 걸 찾았어요
인덱스를 변경하면서 mysql-workbench를 사용하는 경우 (엔진:)-innoDb를 선택합니다.
언급URL : https://stackoverflow.com/questions/8746207/1071-specified-key-was-too-long-max-key-length-is-1000-bytes
'programing' 카테고리의 다른 글
SQLSTATE[HY000]: 일반 오류: Larabel에서 2053 오류가 발생합니다. (0) | 2022.09.17 |
---|---|
컬렉션을 어레이로 변환하는 가장 쉬운 방법 (0) | 2022.09.17 |
CTE를 사용하지 않고 SQL 쿼리에서 계층적 결과(pedigree)를 생성하는 방법 (0) | 2022.09.17 |
테이블에 삽입하여 테이블에서 선택합니다. 여기서 열 이름 = xxx 및 열 이름 2 = yyy 루프가 너무 많습니다. (0) | 2022.09.17 |
MySQL에 데이터를 삽입하면서 잠금 테이블을 작성하는 방법 (0) | 2022.09.17 |