programing

#1071 - 지정된 키가 너무 깁니다. 최대 키 길이는 1000바이트입니다.

yoursource 2022. 9. 17. 10:54
반응형

#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★★★★★★ 。

는 인덱스의 가 "" " " " " " 입니다.index1000달러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

반응형