[SQL] MySQL의 오류 : 키 길이없는 키 사양
SQLMySQL의 오류 : 키 길이없는 키 사양
나는 VARCHAR (255)입니다 기본 키가있는 테이블이있다. 255 개 문자가 충분하지 않습니다 경우 어떤 경우가 생겨있다. 나는 텍스트에 필드를 변경했지만, 나는 다음과 같은 오류가 발생합니다 :
BLOB/TEXT column 'message_id' used in key specification without a key length
나는이 문제를 어떻게 해결할 수 있습니까?
편집 : 나는 또한이 표를 지적해야 여러 열 복합 기본 키를 가지고있다.
해결법
-
==============================
1.오류가 발생하기 때문에 MySQL의 캔 색인 BLOB 또는 TEXT 칼럼의 첫 번째 N의 문자. 이 TEXT 또는 BLOB 또는 TINYBLOB, MEDIUMBLOB, LONGBLOB, TINYTEXT, MEDIUMTEXT로 TEXT 또는 BLOB 유형에 속하는 사람들의 필드 / 열 유형이며, LONGTEXT 때 오류가 주로 발생 그래서 당신은 기본 키 또는 인덱스를 만들기 위해 노력하고있다. 이 변수 및 동적 크기의 같은 길이 값없이 전체 BLOB 또는 TEXT로, MySQL은 컬럼의 고유성을 보장 할 수 없습니다. 지표로서 BLOB 또는 TEXT 형식을 사용하는 경우에 따라서, N의 값은 MySQL이 키 길이를 결정할 수 있도록 제공되어야한다. 그러나 MySQL은 TEXT 또는 BLOB의 키 길이 제한을 지원하지 않습니다. TEXT (88)은 단순히 작동하지 않습니다.
오류가 발생하기 때문에 MySQL의 캔 색인 BLOB 또는 TEXT 칼럼의 첫 번째 N의 문자. 이 TEXT 또는 BLOB 또는 TINYBLOB, MEDIUMBLOB, LONGBLOB, TINYTEXT, MEDIUMTEXT로 TEXT 또는 BLOB 유형에 속하는 사람들의 필드 / 열 유형이며, LONGTEXT 때 오류가 주로 발생 그래서 당신은 기본 키 또는 인덱스를 만들기 위해 노력하고있다. 이 변수 및 동적 크기의 같은 길이 값없이 전체 BLOB 또는 TEXT로, MySQL은 컬럼의 고유성을 보장 할 수 없습니다. 지표로서 BLOB 또는 TEXT 형식을 사용하는 경우에 따라서, N의 값은 MySQL이 키 길이를 결정할 수 있도록 제공되어야한다. 그러나 MySQL은 TEXT 또는 BLOB의 키 길이 제한을 지원하지 않습니다. TEXT (88)은 단순히 작동하지 않습니다.
이미 고유 제한 조건 또는 인덱스로 정의 된 컬럼과, TEXT 또는 BLOB 유형으로 같은 VARCHAR 및 ENUM과 같은 비 텍스트 및 비 BLOB 타입에서 테이블 열을 변환 할 때 오류가 나타납니다. 테이블 변경 SQL 명령이 실패합니다.
이 문제에 대한 해결책은 인덱스 또는 고유 제한 조건에서 TEXT 또는 BLOB 열을 제거하거나 기본 키와 같은 다른 필드를 설정하는 것입니다. 당신이 그렇게하고, TEXT 또는 BLOB 컬럼에 제한을 배치하고자 할 수없는 경우, VARCHAR 타입을 사용하고 그 위에 길이의 제한을 배치하려고합니다. 기본적으로 VARCHAR은 최대 255 자까지로 제한되고 한계는 긴 200 개 문자로 제한됩니다 바로 선언 후 브래킷 내에서 암시 적으로 즉 VARCHAR (200)를 지정해야합니다.
때때로, 당신은 당신의 테이블에 TEXT 또는 BLOB 관련 유형을 사용하지 않는 경우에도 오류 1170도 나타날 수 있습니다. 여기에는 당신이 기본 키로 VARCHAR 컬럼을 지정하지만, 잘못 길이 또는 문자 크기를 설정할 때와 같은 상황에서 발생합니다. 에 MySQL의 강제 등 VARCHAR (512)와 같은 어떤 열이 주로 사용하는 경우 이후에 키 길이에 오류 1170와 함께 실패 SMALLTEXT의 데이터 유형에 VARCHAR (512)를 자동으로 변환되도록 VARCHAR은 256 자까지 허용 만 할 수 있습니다 키 또는 고유 또는 비 고유 인덱스. 이 문제를 해결하기 위해, VARCHAR 필드의 크기가 적은 256보다 그림을 지정합니다.
참조 : MySQL의 오류 1170 (42000) : 키 길이없이 주요 사양에서 사용 BLOB / TEXT 열
-
==============================
2.당신은 당신이 인덱스에 원하는 텍스트 컬럼의 일부를 선도 정의해야합니다.
당신은 당신이 인덱스에 원하는 텍스트 컬럼의 일부를 선도 정의해야합니다.
InnoDB는 인덱스 키 당 768 바이트의 한계를 가지고 있으며, 당신은 더 이상보다 인덱스를 만들 수 없습니다.
이것은 잘 작동합니다 :
CREATE TABLE t_length ( mydata TEXT NOT NULL, KEY ix_length_mydata (mydata(255))) ENGINE=InnoDB;
주 키 크기의 최대 값은 열 캐릭터 세트에 따라 달라집니다. 그것은 LATIN1 같은 단일 바이트 문자 집합에 대한 767 개 문자와 UTF8에만 255 자입니다 (MySQL은 단지 문자 당 최대 3 바이트가 필요 BMP는 사용)
당신이 당신의 전체 열을해야하는 경우 PRIMARY KEY, 계산 SHA1이나 MD5 해시하고 기본 키를 사용합니다.
-
==============================
3.당신은 테이블 변경 요청에 키 길이를 지정할 수 있습니다, 같은 :
당신은 테이블 변경 요청에 키 길이를 지정할 수 있습니다, 같은 :
alter table authors ADD UNIQUE(name_first(20), name_second(20));
-
==============================
4.BLOB의 전체 값을 인덱싱 MySQL의 것을 허용하지, 그들은 거대 할 수 있습니다 포함하는 데이터 때문에 TEXT 긴 VARCHAR 열 및 암시 적으로 DB 지수는 지수로부터 이익을 의미가없는, 큰 것입니다.
BLOB의 전체 값을 인덱싱 MySQL의 것을 허용하지, 그들은 거대 할 수 있습니다 포함하는 데이터 때문에 TEXT 긴 VARCHAR 열 및 암시 적으로 DB 지수는 지수로부터 이익을 의미가없는, 큰 것입니다.
MySQL은 당신이 색인 먼저 N 문자를 정의하는 것이 필요하며, 트릭 공간 절약에 좋은 선택을 줄 오랫동안의 수 N하지만 짧은만큼을 선택하는 것입니다. 접두사는 전체 열을 색인에 경우가있을 것처럼 거의 유용한 인덱스를 만들 충분히해야한다.
우리가 더 가기 전에 우리가 몇 가지 중요한 용어를 정의 할 수 있습니다. 선택성 지수는 총 고유 인덱스 값의 비와 행의 총 수이다. 다음은 테스트 테이블에 대한 하나의 예입니다 :
+-----+-----------+ | id | value | +-----+-----------+ | 1 | abc | | 2 | abd | | 3 | adg | +-----+-----------+
우리는 인덱스 첫 번째 문자 (N = 1), 다음 인덱스 테이블은 다음 표와 같이됩니다 :
+---------------+-----------+ | indexedValue | rows | +---------------+-----------+ | a | 1,2,3 | +---------------+-----------+
이 경우, 인덱스 선택성 IS = 1 / 3의 = 0.33와 같다.
우리는 지금 우리가이 (N = 2)에 인덱스 문자의 수를 늘릴 경우 무슨 일이 일어날 지 보자.
+---------------+-----------+ | indexedValue | rows | +---------------+-----------+ | ab | 1,2 | | ad | 3 | +---------------+-----------+
이 시나리오에서, IS = 우리는 인덱스 선택성을 증가하지만 또한 인덱스의 크기를 증가 수단 2 / 3 = 0.66. 트릭은 최대 인덱스 선택에 발생합니다 최소한의 숫자 N을 찾는 것입니다.
데이터베이스 테이블에 대한 당신이 계산을 할 수있는 방법은 두 가지가 있습니다. 나는이 데이터베이스 덤프에 대한 데모를 만들 것입니다.
하자 우리가 인덱스에 테이블 직원의 열 LAST_NAME을 추가하고 싶은 말은, 우리는 최적의 인덱스 선택도를 생성합니다 작은 숫자 N을 정의하고 싶다.
먼저 우리가 가장 자주 성과 이름을 식별 할 수 있습니다 :
select count(*) as cnt, last_name from employees group by employees.last_name order by cnt +-----+-------------+ | cnt | last_name | +-----+-------------+ | 226 | Baba | | 223 | Coorg | | 223 | Gelosh | | 222 | Farris | | 222 | Sudbeck | | 221 | Adachi | | 220 | Osgood | | 218 | Neiman | | 218 | Mandell | | 218 | Masada | | 217 | Boudaillier | | 217 | Wendorf | | 216 | Pettis | | 216 | Solares | | 216 | Mahnke | +-----+-------------+ 15 rows in set (0.64 sec)
당신이 볼 수 있듯이, 마지막 이름 바바가 가장 자주 하나입니다. 이제 우리는 다섯 글자로 된 접두어로 시작하는, 가장 자주 발생하는 LAST_NAME 접두사를 찾을 것입니다.
+-----+--------+ | cnt | prefix | +-----+--------+ | 794 | Schaa | | 758 | Mande | | 711 | Schwa | | 562 | Angel | | 561 | Gecse | | 555 | Delgr | | 550 | Berna | | 547 | Peter | | 543 | Cappe | | 539 | Stran | | 534 | Canna | | 485 | Georg | | 417 | Neima | | 398 | Petti | | 398 | Duclo | +-----+--------+ 15 rows in set (0.55 sec)
우리는 값은 앞의 예에서와 거의 같은 때까지 수 N을 증가시키는 것을 의미 모든 접두사의 더 많은 발생이 있습니다.
여기서 N = 9 결과는
select count(*) as cnt, left(last_name,9) as prefix from employees group by prefix order by cnt desc limit 0,15; +-----+-----------+ | cnt | prefix | +-----+-----------+ | 336 | Schwartzb | | 226 | Baba | | 223 | Coorg | | 223 | Gelosh | | 222 | Sudbeck | | 222 | Farris | | 221 | Adachi | | 220 | Osgood | | 218 | Mandell | | 218 | Neiman | | 218 | Masada | | 217 | Wendorf | | 217 | Boudailli | | 216 | Cummings | | 216 | Pettis | +-----+-----------+
여기서 N = 10 결과이다.
+-----+------------+ | cnt | prefix | +-----+------------+ | 226 | Baba | | 223 | Coorg | | 223 | Gelosh | | 222 | Sudbeck | | 222 | Farris | | 221 | Adachi | | 220 | Osgood | | 218 | Mandell | | 218 | Neiman | | 218 | Masada | | 217 | Wendorf | | 217 | Boudaillie | | 216 | Cummings | | 216 | Pettis | | 216 | Solares | +-----+------------+ 15 rows in set (0.56 sec)
이것은 매우 좋은 결과이다. 우리는 처음 10 문자의 색인과 열 LAST_NAME 인덱스를 만들 수 있다는이 의미합니다. 표에서 정의 열 LAST_NAME은 VARCHAR (16)로 정의되며,이 수단을 우리는 항목 당 (마지막 이름에 UTF8 문자가있는 경우 더 이상) 6 바이트를 저장했습니다. 이 표에서이 9킬로바이트에 대해 6 바이트를 곱한 1,637 고유 값이 있고, 우리 테이블의 행 만이 포함 된 경우이 숫자가 증가 할 방법을 상상한다.
당신은 MySQL의에서 내 게시물 접두사 인덱스에 N의 수를 계산하는 다른 방법을 읽을 수 있습니다.
-
==============================
5.텍스트 유형의 열이있는 테이블에 인덱스를 추가 할 때이 오류를 얻었다. 당신은 당신이 각 텍스트 유형에 사용할 크기의 양을 선언해야합니다.
텍스트 유형의 열이있는 테이블에 인덱스를 추가 할 때이 오류를 얻었다. 당신은 당신이 각 텍스트 유형에 사용할 크기의 양을 선언해야합니다.
() 괄호 안에 크기의 양을 넣어
너무 많은 바이트 당신이 VARCHAR의 브라켓의 크기를 선언 할 수 있습니다 사용하는 경우 인덱싱에 사용되는 양을 감소시킵니다. 이것은 당신이 이미 VARCHAR (1000)와 같은 유형의 크기를 선언해도됩니다. 당신은 다른 사람이 말한 것처럼 새 테이블을 만들 필요가 없습니다.
인덱스를 추가
alter table test add index index_name(col1(255),col2(255));
고유 인덱스를 추가
alter table test add unique index_name(col1(255),col2(255));
-
==============================
6.
alter table authors ADD UNIQUE(name_first(767), name_second(767));
참고 : 767 문자의 수가 제한되는 개까지 MySQL의 의지 인덱스 컬럼 BLOB / 텍스트 인덱스를 처리하는 동안
참조 : http://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html
-
==============================
7.기본 키만큼 값이 없습니다. 그게 당신의 성능을 파괴 할 것이다. MySQL의 설명서 섹션 13.6.13 'InnoDB의 성능 튜닝 및 문제 해결'을 참조하십시오.
기본 키만큼 값이 없습니다. 그게 당신의 성능을 파괴 할 것이다. MySQL의 설명서 섹션 13.6.13 'InnoDB의 성능 튜닝 및 문제 해결'을 참조하십시오.
대신, 보조 UNIQUE 1 차 (AUTO_INCREMENT와)과 룽 키와 대리 INT의 키가 있습니다.
-
==============================
8.이 다루는 또 다른 좋은 방법은 고유 제한없이 텍스트 필드를 만들고 고유 한 텍스트 필드의 다이제스트 (MD5, SHA1 등)이 포함 된 형제 VARCHAR 필드를 추가하는 것입니다. 계산 및 삽입하거나 빠르게 검색 할 수 있습니다 전체 텍스트 필드 (보다는 일부 주요 부분)에 비해 고유성 제약 조건이 다음 텍스트 필드를 업데이트 할 때 전체 텍스트 필드를 통해 소화 저장합니다.
이 다루는 또 다른 좋은 방법은 고유 제한없이 텍스트 필드를 만들고 고유 한 텍스트 필드의 다이제스트 (MD5, SHA1 등)이 포함 된 형제 VARCHAR 필드를 추가하는 것입니다. 계산 및 삽입하거나 빠르게 검색 할 수 있습니다 전체 텍스트 필드 (보다는 일부 주요 부분)에 비해 고유성 제약 조건이 다음 텍스트 필드를 업데이트 할 때 전체 텍스트 필드를 통해 소화 저장합니다.
-
==============================
9.255 개 문자가 충분하지 않은 경우 오버 플로우를 개최 (빈 문자열이 널 (null) 기본적으로) 또 다른 VARCHAR (255) 열을 추가하고 두 열을 사용하려면이 PK를 변경합니다. 그러나 이것은 잘 설계된 데이터베이스 스키마 같은 소리하지 않으며, 난 당신이 더 정상화를 위해 리팩토링을 향해보기로 무엇을보고 데이터 모델러를 받고 추천 할 것입니다.
255 개 문자가 충분하지 않은 경우 오버 플로우를 개최 (빈 문자열이 널 (null) 기본적으로) 또 다른 VARCHAR (255) 열을 추가하고 두 열을 사용하려면이 PK를 변경합니다. 그러나 이것은 잘 설계된 데이터베이스 스키마 같은 소리하지 않으며, 난 당신이 더 정상화를 위해 리팩토링을 향해보기로 무엇을보고 데이터 모델러를 받고 추천 할 것입니다.
-
==============================
10.이 필드에 인덱스를 사용하려는 경우 또한, 당신은 MyISAM 스토리지 엔진과 전체 텍스트 인덱스 유형을 사용해야합니다.
이 필드에 인덱스를 사용하려는 경우 또한, 당신은 MyISAM 스토리지 엔진과 전체 텍스트 인덱스 유형을 사용해야합니다.
-
==============================
11.이 문제에 대한 해결책은 CREATE TABLE 문에, 당신은 예를 들어, 텍스트 필드에 300 개 문자의 키 길이를 지정 정의를 작성 열 후 제약 UNIQUE (problemtextfield (300))를 추가 할 수 있다는 것이다. 그런 다음 problemtextfield 텍스트 필드의 첫 번째 300 개 문자는 고유해야하고, 그 후 어떤 차이가 무시 될 것이다.
이 문제에 대한 해결책은 CREATE TABLE 문에, 당신은 예를 들어, 텍스트 필드에 300 개 문자의 키 길이를 지정 정의를 작성 열 후 제약 UNIQUE (problemtextfield (300))를 추가 할 수 있다는 것이다. 그런 다음 problemtextfield 텍스트 필드의 첫 번째 300 개 문자는 고유해야하고, 그 후 어떤 차이가 무시 될 것이다.
-
==============================
12.이 같은 사용
이 같은 사용
@Id @Column(name = "userEmailId", length=100) private String userEmailId;
-
==============================
13.당신은 인덱싱 VARCHAR 또는 정수로 열 유형을 변경해야합니다.
당신은 인덱싱 VARCHAR 또는 정수로 열 유형을 변경해야합니다.
-
==============================
14.MySQL의 편집 VARCHAR (45)에 테이블 -> 변경 열 유형으로 이동합니다.
MySQL의 편집 VARCHAR (45)에 테이블 -> 변경 열 유형으로 이동합니다.
-
==============================
15.아무도는 4 바이트이며, 또한 (우리가 더 많은 3 바이트 UTF8을 사용해서는 안) 우리가 잘못된 문자열 값과 같은 오류를 방지 할 수 이모티콘을 저장할 수 utf8mb4로 ... 지금까지 언급하지 : \ xF0 \ x9F \ x98 \ .. . 때문에 우리의 경우 utf8mb4 및 VARCHAR 전형적인 VARCHAR (255)가 아니라 VARCHAR (191)를 사용하지 말아야합니다 ((255)는 데이터의 동일한 부분은 페이지를 저장하고 당신은 열 VARCHAR (255)에 대한 인덱스를 생성 할 수 있지만 VARCHAR에 대한 191)을 수행 할 수 있습니다. 최대 인덱스 컬럼 크기 ROW_FORMAT = COMPACT 또는 ROW_FORMAT REDUNDANT = 767 바이트이기 때문이다.
아무도는 4 바이트이며, 또한 (우리가 더 많은 3 바이트 UTF8을 사용해서는 안) 우리가 잘못된 문자열 값과 같은 오류를 방지 할 수 이모티콘을 저장할 수 utf8mb4로 ... 지금까지 언급하지 : \ xF0 \ x9F \ x98 \ .. . 때문에 우리의 경우 utf8mb4 및 VARCHAR 전형적인 VARCHAR (255)가 아니라 VARCHAR (191)를 사용하지 말아야합니다 ((255)는 데이터의 동일한 부분은 페이지를 저장하고 당신은 열 VARCHAR (255)에 대한 인덱스를 생성 할 수 있지만 VARCHAR에 대한 191)을 수행 할 수 있습니다. 최대 인덱스 컬럼 크기 ROW_FORMAT = COMPACT 또는 ROW_FORMAT REDUNDANT = 767 바이트이기 때문이다.
새로운 행 형식 ROW_FORMAT = DYNAMIC 또는 ROW_FORMAT를 들어 = COMPRESSED (새로운 파일 형식 innodb_file_format =을 필요로하는 바라쿠다 영양하지 이상) 최대 인덱스 열 크기 그것은 사용할 수있는 3072 때문에 MySQL의> = 5.6.3 innodb_large_prefix = 1 (위해 기본적으로 사용하는 경우 MySQL의 <= 5.7.6와 MySQL에 대해 기본적으로 활성화> = 5.7.7). 이 경우 우리는 인덱스 컬럼 (구 UTF8 또는 VARCHAR (1024)) utf8mb4에 대한 VARCHAR (768)를 사용할 수 있습니다. 그 동작이 내장되어 있기 때문에 MySQL의 8 옵션 innodb_large_prefix은 5.7.7부터 사용되지 않습니다 (이 버전에서 옵션을 제거)입니다.
from https://stackoverflow.com/questions/1827063/mysql-error-key-specification-without-a-key-length by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 어떻게 새로운 PostgreSQL의 JSON 데이터 형식의 내부 필드를 사용하여 쿼리 할 수 있습니까? (0) | 2020.03.13 |
---|---|
[SQL] 조건 내에서 JOIN 또는 WHERE (0) | 2020.03.13 |
[SQL] MAX와 GROUP BY (DATE) [중복] (0) | 2020.03.13 |
[SQL] 왼쪽은 SQL Server의 성능을 가입 대 INNER는 가입 (0) | 2020.03.13 |
[SQL] 어떻게 SQL Server의 테이블에서 열 이름을 얻을 수 있나요? (0) | 2020.03.13 |