MySQL 오류 #1071 - 지정된 키가 너무 깁니다. 최대 키 길이는 767바이트입니다.
다음 명령을 실행했을 때:
ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);
다음 오류 메시지가 나타납니다.
#1071 - Specified key was too long; max key length is 767 bytes
column1 및 column2에 대한 정보:
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
MySQL 버전 5.6(및 이전 버전)의 767 바이트는 InnoDB 테이블의 프레픽스 제한입니다.MyISAM 테이블의 길이는 1,000바이트입니다.MySQL 버전 5.7 이상에서는 이 제한이 3072바이트로 증가했습니다.
, 큰 나 「큰 문자」에는, .varchar
( ,),utf8mb4
부호화된 경우 최대 인덱스프리픽스 길이 767바이트(또는 3072바이트)를 4로 나누면 191이 됩니다.그 이유는 의 최대 길이가utf8mb4
character는 4바이트입니다.의 utf8
문자는 3바이트이며 최대 인덱스 프리픽스 길이는 255(또는 늘 터미네이터를 뺀 254자)가 됩니다.
는 '을 '하한선을 하는 것입니다.VARCHAR
[ ]이렇게 하다
(이 문제에 대한 응답에 따라) 다른 옵션은 전체 금액이 아닌 열의 하위 집합을 가져오는 것입니다.
ALTER TABLE `mytable` ADD UNIQUE ( column1(15), column2(200) );
적용하기 위한 키를 얻을 필요가 있는 만큼 수정해 주세요.그러나 MySQL의 제한에 영향을 주지 않고 의도한 비즈니스 규칙을 구현할 수 있는지 이 엔티티에 관한 데이터 모델을 검토할 가치가 있는지 궁금합니다.
한계에 다다랐을 때.다음을 설정합니다.
utf8
VARCHAR(255)
utf8mb4
VARCHAR(191)
INNODB INNODB/Utf-8을 .UNIQUE
의 VARCHAR(256)
] , [ ]로 합니다.VARCHAR(255)
255달러입니다.
MySQL은 문자열의 문자당 바이트 수에 대해 최악의 경우를 가정합니다.은 MySQL 'utf8'을 초과하는 문자를 수 입니다.U+FFFF
이라고 부릅니다.MySQL 'utf8mb4'는 4바이트입니다. MySQL UTF-8입니다.
따라서 'utf8'을 사용하는 경우 첫 번째 열은 인덱스의 60바이트를 사용하고 두 번째 열은 1500바이트를 사용합니다.
쿼리 전에 다음 쿼리를 실행합니다.
SET @@global.innodb_large_prefix = 1;
.3072 bytes
.
Larabel Framework용 솔루션
Larabel 5.4.* 매뉴얼에 따라 기본 문자열 길이를 설정할 필요가 있습니다.boot
의 of의 app/Providers/AppServiceProvider.php
하다
use Illuminate\Support\Facades\Schema;
public function boot()
{
Schema::defaultStringLength(191);
}
이 수정에 대한 설명(Larabel 5.4.* 문서 참조):
은 라라벨을 한다.
utf8mb4
기본적으로 설정된 문자 집합. 지스7.2보다 오래된 MySQL이 문자열 해야 합니다.5.7 "MySQL " 10.2 "DB "Maria.하려면 , 「 」를 합니다.Schema::defaultStringLength
내부 메서드AppServiceProvider
.는음, 음음음을 하게 할 도 있습니다.
innodb_large_prefix
옵션을 선택합니다.이 옵션을 올바르게 사용 가능으로 설정하는 방법은 데이터베이스 설명서를 참조하십시오.
어떤 문자 인코딩을 사용하고 있습니까?일부 문자 세트(UTF-16 등)는 1 문자당1 바이트를 넘습니다.
varchar(20)는 21바이트만 필요한 반면 varchar(500)는 501바이트만 필요로 한다고 생각합니다.따라서 총 바이트 수는 522로 767보다 작습니다.그럼 왜 에러 메시지가 뜨는 거죠?
UTF8은 문자열을 저장하려면 문자당 3바이트가 필요합니다.따라서 이 경우 20 + 500 문자 = 20*3 + 500 * 3 = 1560 바이트로, 767 바이트보다 큽니다.
UTF8 의 제한은 767/3 = 255 문자, UTF8mb4 의 경우는 767/4 = 191 문자입니다.
제한보다 긴 열을 사용해야 하는 경우 이 문제에 대한 두 가지 해결 방법이 있습니다.
- 수가 를 사용합니다.
에는 기사해야 했습니다.은 SEO의 Unique Index를 하는 것입니다.[A-z0-9\-]
SEO를 요.latin1_general_ci
1글자당1바이트밖에 사용하지 않기 때문에 컬럼의 길이는 767바이트입니다. - 해당 합니다.
을 하나 더 이 컬럼에는 SEO의 해시가 포함되어 .이 컬럼은UNIQUE
SEO라고 합니다.KEY
인덱스를 원래 SEO 열로 변경하여 조회 속도를 높입니다.
utf8mb4
utf8
Import하다.
오류 메시지가 표시되는 이유에 대한 답변은 이미 많은 사용자에 의해 응답되었습니다.제 대답은 어떻게 고쳐서 그대로 사용할 것인가 하는 것입니다.
이 링크에서 참조해 주세요.
- MySQL 클라이언트(또는 MariaDB 클라이언트)를 엽니다.명령줄 도구입니다.
- 비밀번호가 요구됩니다.올바른 비밀번호를 입력합니다.
- 명령어를 합니다.
use my_database_name;
데이터베이스가 변경되었습니다.
set global innodb_large_prefix=on;
Query OK(0.00초)에 해당하는 0행
set global innodb_file_format=Barracuda;
Query OK(0.02초), 영향을 받는 행 수 0개
- 관리를 쉽게 하려면 phpMyAdmin 등의 데이터베이스로 이동하십시오.> database > View table structure > Go to Operations 탭을 선택합니다.> ROW_FORMAT을 DYNAMIC으로 변경하여 변경을 저장합니다.
- 테이블 구조 탭> [ Unique ]버튼을 클릭합니다.
- 완료. 이제 오류가 없어야 합니다.
이 수정의 문제는 db를 다른 서버(예를 들어 localhost에서 실제 호스트)로 내보내고 해당 서버에서 MySQL 명령줄을 사용할 수 없는 경우입니다.당신은 거기서 그걸 작동시킬 수 없어요.
Specified key was too long; max key length is 767 bytes
는 1 이기 때문에 이 되는 것은 1 가 1 이기 때문입니다.latin-1
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★utf8
키 컬럼을 정의할 때 각 문자는 3바이트로 간주됩니다.「 」를 사용하고 utf8mb4
키 컬럼을 정의할 때 각 문자는 4바이트로 간주됩니다.따라서 키 필드의 문자 제한에 1, 3, 또는 4를 곱하여 키 필드가 허용하는 바이트 수를 결정해야 합니다.사용하는 할 수 uft8mb4 입니다.uft8mb4는 InnoDB 입니다..767 를 위반하지 마십시오
5가지 회피책:
제한은 5.7.7(MariaDB 10.2.2?)로 증가했습니다.또한 5.6(10.1)에서 일부 작업을 수행하면 증가할 수 있습니다.
CARTER SET utf8mb4를 사용하려고 하기 때문에 한계에 도달한 경우.다음으로 다음 중 하나(각각 단점이 있음)를 실행하여 오류를 방지합니다.
⚈ Upgrade to 5.7.7 for 3072 byte limit -- your cloud may not provide this;
⚈ Change 255 to 191 on the VARCHAR -- you lose any values longer than 191 characters (unlikely?);
⚈ ALTER .. CONVERT TO utf8 -- you lose Emoji and some of Chinese;
⚈ Use a "prefix" index -- you lose some of the performance benefits.
⚈ Or... Stay with older version but perform 4 steps to raise the limit to 3072 bytes:
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_large_prefix=1;
logout & login (to get the global values);
ALTER TABLE tbl ROW_FORMAT=DYNAMIC; -- (or COMPRESSED)
-- http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes
긴 열의 md5 열을 추가할 수 있습니다.
레벨 5.7~9.0의 경우
따라야 할 것
- ★★★★★★★★★★★★★★★로 이동
App\Providers\AppServiceProvider.php
. - 을 프로바이더 「」에 합니다.
use Illuminate\Support\Facades\Schema;
맨 위에 - 에서는 이 기능을 합니다.
Schema::defaultStringLength(191);
그것뿐이에요, 즐기세요.
이 문제는 다음과 같이 수정했습니다.
varchar(200)
로 대체하다
varchar(191)
200을 초과하는 모든 고유 또는 기본 varchar 키는 191로 대체하거나 텍스트로 설정합니다.
이 문제는 utf8mb4를 사용하여 VARCHAR(255) 필드에 UNIQURE 인덱스를 추가하려고 할 때 발생했습니다.이 문제는 이미 잘 정리되어 있지만, 어떻게 문제를 해결하고 해결했는지에 대한 몇 가지 실질적인 조언을 덧붙이고 싶습니다.
utf8mb4를 사용하는 경우 문자는 4바이트로 계산되지만 utf8에서는 3바이트로 계산될 수 있습니다.InnoDB 데이터베이스에는 인덱스가 767바이트만 포함할 수 있다는 제한이 있습니다.따라서 utf8을 사용하는 경우 255자(767/3 = 255)를 저장할 수 있지만 utf8mb4를 사용하는 경우 191자(767/4 = 191)만 저장할 수 있습니다.
경우 반드시 할 수 VARCHAR(255)
사용하는 입니다만, 사이즈는 utf8mb4의 경우 : utf8mb4의 경우, 191의 경우).unique_key
삭제:
일반 인덱스는 MySQL이 데이터를 보다 빠르게 검색할 수 있도록 하기 위해 사용되기 때문에 괜찮습니다.전체 필드를 인덱싱할 필요가 없습니다.
그렇다면 MySQL은 일반 인덱스에 대해서는 인덱스를 자동으로 잘라내지만 고유 인덱스에 대해서는 인덱스를 실행하려고 할 때 명시적 오류가 발생하는 이유는 무엇일까요?MySQL이 삽입 또는 업데이트 중인 값이 이미 존재하는지 여부를 확인할 수 있으려면 값의 일부가 아니라 전체 값을 인덱싱해야 합니다.
마지막으로 필드에 고유한 인덱스를 사용하려면 필드의 전체 내용이 인덱스에 맞아야 합니다.utf8mb4의 경우 VARCHAR 필드의 길이를 191자 이하로 줄입니다.해당 테이블 또는 필드에 utf8mb4가 필요하지 않은 경우 utf8로 드롭하여 255개의 필드를 유지할 수 있습니다.
제 답변은 다음과 같습니다.
데이터베이스를 삭제하고 다음과 같이 재생성하면 오류가 사라집니다.
drop database if exists rhodes; create database rhodes default CHARACTER set utf8 default COLLATE utf8_general_ci;
하지만 모든 경우에 효과가 있는 것은 아닙니다.
에 VARCHAR 문자 집합이 되어 있는 .utf8
(오류)utf8mb4
길이를 초과하는 을 사용합니다 VARCHAR 컬럼은 VARCHAR 컬럼을 사용합니다. utf8mb4
191번이다.
MySQL 데이터베이스에서 긴 인덱스를 사용하는 방법에 대한 자세한 내용은 이 문서의 긴 인덱스 섹션을 참조하십시오. http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4
그걸 고치려면 이게 저한테는 마법처럼 작용해요.
ALTER DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci;
이 주제에 대해 검색해 봤더니 드디어 커스텀 체인지로 바뀌었네요.
MySQL Workbench 6.3.7 Version의 경우 그래픽 인터 페이즈를 사용할 수 있습니다.
- Workbench를 시작하고 연결을 선택합니다.
- 관리 또는 인스턴스로 이동하여 옵션 파일을 선택합니다.
- Workbench가 구성 파일을 읽을 수 있는 권한을 요청한 후 OK를 두 번 눌러 허용합니다.
- 중앙에 Administrator options 파일창이 나타납니다.
- InnoDB 탭으로 이동하여 innodb_large_prefix가 General 섹션에서 체크되지 않은 경우 확인합니다.
- innodb_default_row_format 옵션 값을 DYNAMIC으로 설정합니다.
6.3.7 이전 버전의 경우 직접 옵션을 사용할 수 없으므로 명령 프롬프트로 이동해야 합니다.
- CMD를 관리자로 시작합니다.
- mysql 서버가 설치되어 있는 디렉터로 이동 대부분의 경우 "C:\Program Files\MySQL\MySQL Server 5.7\bin 명령어는 cd \"cd Program Files\My"입니다.SQL\MySQL Server 5.7\bin"을 클릭합니다.
- 이제 명령어 mysql -u userName -p databasesheema를 실행합니다.이것으로, 각 유저의 패스워드를 요구했습니다.비밀번호를 입력하고 mysql 프롬프트를 입력합니다.
- 몇 가지 글로벌 설정을 해야 합니다.다음 명령어를 하나씩 입력하고 set global innodb_large_format=on, set global innodb_file_per_table=true, set global innodb_file_per_table=true,
- 마지막으로 필수 테이블의 ROW_FORMAT을 기본적으로 변경해야 합니다.COMPT를 DYNAMIC으로 설정해야 합니다.
- 다음 명령어 alter table_name ROW_FORMAT=DYNAMIC을 사용합니다.
- 다 했어요.
대조 결과를 변경하세요.거의 모든 것을 지원하는 utf8_general_ci를 사용할 수 있습니다.
인덱스 길이 & MySQL / 마리아DB
Larabel은 기본적으로 utf8mb4 문자 집합을 사용합니다. 여기에는 데이터베이스에 "emojis" 저장 지원이 포함됩니다.5.7.7 이전 버전의 MySQL 또는 10.2.2 이전 버전의 MariaDB를 실행하고 있는 경우 MySQL에서 마이그레이션에 의해 생성된 기본 문자열 길이를 수동으로 구성해야 할 수 있습니다.이를 설정하려면 AppServiceProvider 내에서 Schema::defaultStringLength 메서드를 호출합니다.
use Illuminate\Support\Facades\Schema;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
또는 데이터베이스에 innodb_large_prefix 옵션을 활성화 할 수도 있습니다.이 옵션을 올바르게 사용 가능으로 설정하는 방법은 데이터베이스 설명서를 참조하십시오.
블로그 참조: https://www.scratchcode.io/specified-key-too-long-error-in-laravel/
공식 문서 참조: https://laravel.com/docs/5.7/migrations
★★★★★★★★★utf8mb4
로로 합니다.utf8
테이블을 만들 때 문제가 해결되었습니다.를 들면, '먹다'와 같이요.CREATE TABLE ... DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
로로 합니다.CREATE TABLE ... DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
.
이것으로 문제가 해결되었다
ALTER DATABASE dbname 문자 집합 utf8 COLATE utf8_general_ci;
은 " "를 사용하고 .utf8_general_ci
collation)utf8
차셋
、 MySQL ( MySQL 。utf8
charset은 각 문자에 대해 최대 3바이트를 사용합니다.따라서 MySQL이 허용하는 767바이트보다 훨씬 큰 500*3=120바이트를 할당해야 합니다.그렇기 때문에 이 1071 에러가 발생하고 있습니다.
모든 이 단일 표현 때문에 집합의 할 필요가 utf8
1 3 문자, 1 의 「3」, 767/3 255 문자,utf8mb4
, 최대 4바이트의 표현, 767/4µ191 문자.
또한 MySQL은
column1 varchar(20) utf8_general_ci
column2 varchar(500) utf8_general_ci
이 문제는 Linux 리다이렉션 출력/입력 문자를 사용하여 데이터베이스를 백업할 때 발생했습니다.따라서 아래와 같이 구문을 변경합니다.PS: Linux 또는 Mac 터미널 사용.
백업(> 리다이렉트 없음)
# mysqldump -u root -p databasename -r bkp.sql
복원(< 리다이렉트 없음)
# mysql -u root -p --default-character-set=utf8 databasename
mysql> SET names 'utf8'
mysql> SOURCE bkp.sql
"Specified key was too long; max key length is 767 bytes" simple 오류는 사라졌습니다.
이 쿼리는 인덱스가 최대 길이를 위반하는 열을 탐지하는 데 유용합니다.
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')
확인 부탁드립니다sql_mode
~와 같다
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
만약 그렇다면 로 바꿔라.
sql_mode=NO_ENGINE_SUBSTITUTION
또는
my.cnf 파일 변경 후 서버를 재시작합니다(다음 항목 참조).
innodb_large_prefix=on
프리픽스 제한으로 인해 이 오류가 발생합니다.767 바이트는 MySQL 5.7 이전 버전의 InnoDB 테이블에 대해 명시된 접두사 제한입니다. MyISAM 테이블의 길이는 1,000 바이트입니다.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;
문제
MySQL에는 최대 키 길이 제한이 있습니다.
- InnoDB: 최대 키 길이는 1,536 바이트(8KB 페이지 크기) 및 768 바이트(4KB 페이지 크기)입니다(출처:Dev.MySQL.com).
- MyISAM : 최대 키 길이는 1,000 바이트입니다(Source Dev).MySQL.com )를 참조해 주세요.
이것들은 바이트 단위로 카운트됩니다!따라서 UTF-8 문자는 키에 저장되기까지1바이트 이상 걸릴 수 있습니다.
따라서 즉시 해결할 수 있는 솔루션은 다음 두 가지뿐입니다.
- 텍스트 유형의 첫 번째 n번째 문자만 인덱싱합니다.
- 작성하다
FULL TEXT
search : 모든 것을 Elastic Search와 같은 방법으로 텍스트 내에서 검색할 수 있습니다.
텍스트 유형의 첫 번째 N번째 문자 인덱싱
테이블을 작성할 경우 다음 구문을 사용하여 일부 필드의 첫 255자를 색인화합니다.KEY
키 (
일부 텍스트(255))
. 이렇게.
CREATE TABLE `MyTable` (
`id` int(11) NOT NULL auto_increment,
`SomeText` TEXT NOT NULL,
PRIMARY KEY (`id`),
KEY `sometextkey` (`SomeText`(255))
);
테이블이 이미 있는 경우 필드에 다음과 같은 고유 키를 추가할 수 있습니다.ADD UNIQUE(
설정값(20));
. 이렇게.
ALTER TABLE
MyTable
ADD UNIQUE(`ConfigValue`(20));
필드 이름이 예약된 MySQL 키워드가 아닌 경우 필드 이름 주위에 backticks(')가 필요하지 않습니다.
전체 텍스트 검색 만들기
전체 텍스트 검색을 통해 모든 값을 검색할 수 있습니다.TEXT
필드입니다. 이 필드를 사용하면 전체 단어 매칭이 이루어집니다.NATURAL LANGUAGE MODE
, 또는 다른 모드 중 하나를 사용하는 경우 부분적인 단어 매칭입니다.FullText 옵션에 대한 자세한 내용은http://Dev.MySQL.com 를 참조해 주세요.
텍스트로 표를 만들고 전체 텍스트 색인을 추가합니다...
ALTER TABLE
MyTable
ADD FULLTEXT INDEX
`SomeTextKey` (`SomeTextField` DESC);
그럼 이렇게 테이블을 뒤지면...
SELECT
MyTable.id, MyTable.Title,
MATCH
(MyTable.Text)
AGAINST
('foobar' IN NATURAL LANGUAGE MODE) AS score
FROM
MyTable
HAVING
score > 0
ORDER BY
score DESC;
나는 varchar에서 nvarchar로 변경되어 나를 위해 일한다.
언급URL : https://stackoverflow.com/questions/1814532/mysql-error-1071-specified-key-was-too-long-max-key-length-is-767-bytes
'IT' 카테고리의 다른 글
WooCommerce 제품이 실제로 품절되지 않은 경우 "품절" 메시지를 표시합니다. (0) | 2022.11.17 |
---|---|
SQL Query 결과를 PANDA Data Structure로 변환하는 방법 (0) | 2022.11.17 |
파일의 첫 번째 N 행을 어떻게 읽습니까? (0) | 2022.11.17 |
원칙에서 findBy()를 사용하여 결과를 정렬하는 방법 (0) | 2022.11.17 |
시퀀스 첨자를 붙일 때 Python에서 ::(이중 콜론)이란 무엇입니까? (0) | 2022.11.08 |