복붙노트

[SQL] MySQL의 오류 : 키 길이없는 키 사양

SQL

MySQL의 오류 : 키 길이없는 키 사양

나는 VARCHAR (255)입니다 기본 키가있는 테이블이있다. 255 개 문자가 충분하지 않습니다 경우 어떤 경우가 생겨있다. 나는 텍스트에 필드를 변경했지만, 나는 다음과 같은 오류가 발생합니다 :

BLOB/TEXT column 'message_id' used in key specification without a key length

나는이 문제를 어떻게 해결할 수 있습니까?

편집 : 나는 또한이 표를 지적해야 여러 열 복합 기본 키를 가지고있다.

해결법

  1. ==============================

    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. ==============================

    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. ==============================

    3.당신은 테이블 변경 요청에 키 길이를 지정할 수 있습니다, 같은 :

    당신은 테이블 변경 요청에 키 길이를 지정할 수 있습니다, 같은 :

    alter table authors ADD UNIQUE(name_first(20), name_second(20));
    
  4. ==============================

    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. ==============================

    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. ==============================

    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. ==============================

    7.기본 키만큼 값이 없습니다. 그게 당신의 성능을 파괴 할 것이다. MySQL의 설명서 섹션 13.6.13 'InnoDB의 성능 튜닝 및 문제 해결'을 참조하십시오.

    기본 키만큼 값이 없습니다. 그게 당신의 성능을 파괴 할 것이다. MySQL의 설명서 섹션 13.6.13 'InnoDB의 성능 튜닝 및 문제 해결'을 참조하십시오.

    대신, 보조 UNIQUE 1 차 (AUTO_INCREMENT와)과 룽 키와 대리 INT의 키가 있습니다.

  8. ==============================

    8.이 다루는 또 다른 좋은 방법은 고유 제한없이 텍스트 필드를 만들고 고유 한 텍스트 필드의 다이제스트 (MD5, SHA1 등)이 포함 된 형제 VARCHAR 필드를 추가하는 것입니다. 계산 및 삽입하거나 빠르게 검색 할 수 있습니다 전체 텍스트 필드 (보다는 일부 주요 부분)에 비해 고유성 제약 조건이 다음 텍스트 필드를 업데이트 할 때 전체 텍스트 필드를 통해 소화 저장합니다.

    이 다루는 또 다른 좋은 방법은 고유 제한없이 텍스트 필드를 만들고 고유 한 텍스트 필드의 다이제스트 (MD5, SHA1 등)이 포함 된 형제 VARCHAR 필드를 추가하는 것입니다. 계산 및 삽입하거나 빠르게 검색 할 수 있습니다 전체 텍스트 필드 (보다는 일부 주요 부분)에 비해 고유성 제약 조건이 다음 텍스트 필드를 업데이트 할 때 전체 텍스트 필드를 통해 소화 저장합니다.

  9. ==============================

    9.255 개 문자가 충분하지 않은 경우 오버 플로우를 개최 (빈 문자열이 널 (null) 기본적으로) 또 다른 VARCHAR (255) 열을 추가하고 두 열을 사용하려면이 PK를 변경합니다. 그러나 이것은 잘 설계된 데이터베이스 스키마 같은 소리하지 않으며, 난 당신이 더 정상화를 위해 리팩토링을 향해보기로 무엇을보고 데이터 모델러를 받고 추천 할 것입니다.

    255 개 문자가 충분하지 않은 경우 오버 플로우를 개최 (빈 문자열이 널 (null) 기본적으로) 또 다른 VARCHAR (255) 열을 추가하고 두 열을 사용하려면이 PK를 변경합니다. 그러나 이것은 잘 설계된 데이터베이스 스키마 같은 소리하지 않으며, 난 당신이 더 정상화를 위해 리팩토링을 향해보기로 무엇을보고 데이터 모델러를 받고 추천 할 것입니다.

  10. ==============================

    10.이 필드에 인덱스를 사용하려는 경우 또한, 당신은 MyISAM 스토리지 엔진과 전체 텍스트 인덱스 유형을 사용해야합니다.

    이 필드에 인덱스를 사용하려는 경우 또한, 당신은 MyISAM 스토리지 엔진과 전체 텍스트 인덱스 유형을 사용해야합니다.

  11. ==============================

    11.이 문제에 대한 해결책은 CREATE TABLE 문에, 당신은 예를 들어, 텍스트 필드에 300 개 문자의 키 길이를 지정 정의를 작성 열 후 제약 UNIQUE (problemtextfield (300))를 추가 할 수 있다는 것이다. 그런 다음 problemtextfield 텍스트 필드의 첫 번째 300 개 문자는 고유해야하고, 그 후 어떤 차이가 무시 될 것이다.

    이 문제에 대한 해결책은 CREATE TABLE 문에, 당신은 예를 들어, 텍스트 필드에 300 개 문자의 키 길이를 지정 정의를 작성 열 후 제약 UNIQUE (problemtextfield (300))를 추가 할 수 있다는 것이다. 그런 다음 problemtextfield 텍스트 필드의 첫 번째 300 개 문자는 고유해야하고, 그 후 어떤 차이가 무시 될 것이다.

  12. ==============================

    12.이 같은 사용

    이 같은 사용

    @Id
    @Column(name = "userEmailId", length=100)
    private String userEmailId;
    
  13. ==============================

    13.당신은 인덱싱 VARCHAR 또는 정수로 열 유형을 변경해야합니다.

    당신은 인덱싱 VARCHAR 또는 정수로 열 유형을 변경해야합니다.

  14. ==============================

    14.MySQL의 편집 VARCHAR (45)에 테이블 -> 변경 열 유형으로 이동합니다.

    MySQL의 편집 VARCHAR (45)에 테이블 -> 변경 열 유형으로 이동합니다.

  15. ==============================

    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부터 사용되지 않습니다 (이 버전에서 옵션을 제거)입니다.

  16. from https://stackoverflow.com/questions/1827063/mysql-error-key-specification-without-a-key-length by cc-by-sa and MIT license