--- tags: jpa, error, mysql, MySQL5InnoDBDialect --- JPA erorr - Specified key was too long; max key length is 1000 bytes === Entity에 적힌 필드들로 테이블을 create 후, 이후에 alter로 unique 를 잡아줄때 다음과 같은 에러가 발생했다. ``` alter table account add constraint UK_gex1lmaqpg0ir5g1f5eftyaa1 unique (username)" via JDBC Statement org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL " 중략... Caused by: java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 1000 bytes ``` > 대략 uk 키의 최대 크기는 1000바이트 라는 뜻이다. JPA에서 `spring.jpa.hibernate.ddl-auto=create` 옵션으로 자동으로 테이블을 생성할때 MyISAM 캐릭터셋이 utf8mb4 만들더라. utf8 이면 1글자당 3바이트 인 반면, utf8mb4는 **4바이트 이다.** 따라서 기본으로 생성해주는 varchar(255) 는 255*4 가 1020 을 잡게되어 1000바이트를 초과하면서 위와 같은 에러가 발생한 것이다. 몇가지 해결방법을 찾아봤는데 다음과 같다. ## 해결방법 아래의 셋중 하나만 해결되어도 에러를 잡을수 있다. 1. `length = 250` 을 설정해서 1000 바이트 이하로 생성 되게 한다 2. 테이블 캐릭터셋을 utf8로 바꾼다 3. **테이블 엔진을 MyISAM -> InnoDB로 바꾼다** 사실상 1,2번은 적절치 못하다. 심지어 3번은 InnoDB 자체가 대세라 당연하게 설정을 하게 될 것이다. 결론적으로 3번만 봐도 해결이 되겠지만, 학습을 위해 각 해결방법을 통해 원리를 이해해 보자. ### 1. length = 250 요즘 mysql 기본 생성되는 캐릭터셋은 4바이트를 차지하는 utf8mb4 로 만들어 진다. > 내가 처음에 디비 입문할땐 utf8 이었고 100년 200년은 쓸수있는 캐릭터셋이라고 어디서 들었던것 같은데.. 참 빠르다. 덕분에 4바이트인 이모지를 표현할 수가 있다. 다만 문제는 JPA가 테이블 생성시 String 값에 length 를 안넣으면 VARCHAR(255) 로 생성을 하는데 255 * 4 가 1000바이트를 넘게되어 발생한 문제이다. VARCHAR(250) 으로 적용 해주면 에러가 발생하지 않는다. ### 2. 테이블 캐릭터셋을 utf8로 바꾼다 1번에서 얘기 했지만 utf8mb4는 이모지를 표현할 차세대 버전 인것 같다. 캐릭터셋은 바꾸지 않고 써보도록 하자. ### 3. 테이블 엔진을 MyISAM -> InnoDB로 바꾼다 1000 바이트 제하는 MyISAM 에만 해당한다. InnoDB가 최대 몇바이트 까지인지는 모르겠지만, VARCHAR(2000) 까진 해봤던적이 있다. JPA 는 기본적으로 테이블 엔진의 설정을 MyISAM 으로 생성하는데, InnoDB로 바꾸는 방법은 아래 설정을 application.properties 에 넣어주면 된다. ``` spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect ``` InnoDB도 방언 인가보다 ㅎㅎ Mysql만 해서그런가 뭐가 방언이고 표준인지 구분하는게 모호할때가 많다. JPA를 쓰면서 좀더 확인할수 있을것 같다. ### 결론 엔진을 굳이 MyISAM 을 쓸 필요가 없다면 InnoDB 로 바꿔서 쓰도록 하자.