持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
问题描述
相信很多同学在日常开发中都接触过JPA或者Mybatis。有的偏爱JPA有的偏爱Mybatis。
它们其中一个不同点就是JPA在项目启动时支持配置DDL策略。但是在项目开发中偶尔出现配置了DDL,但是没按照自己预期生成表结构的,此时需要检查控制台异常,看具体报错内容。今天示范的是ddl-auto配置的update,但是在启动项目后,新增的表结构并没有自动写入指定数据库中。报错时提示Specified key was too long; max key length is 1000 bytes。
相关知识
DDL策略
create每次启动项目都是新建表(表中原来的数据会被清空)create-drop启动项目时新建表结构,销毁项目时删除表结构(表中原来的数据会被清空)update启动项目时创建数据库中没有的表结构(原本存在的表数据和结构不发生删减只有新增)validate将数据库中的表结构和代码中的字段进行校验,不对实际表结构产生影响,校验失败会报错(表中原来数据无影响)none启动时没有任何操作
综上,在生产环境中应用最多的就是update,要慎用create和create-drop,防止正式环境数据被删除。
MySQL字符集所占用的字节
- 使用
SELECT * FROM information_schema.CHARACTER_SETS;查看一下数据库具体编码方式和对应的位数。 - 一般使用的是utf8、utf8mb4,一般项目大多选择后者,后者可以存储的范围更大,可以存储如表情包、日文、韩文的字符串,而如果使用前者的话会出现乱码的情况。
问题分析
指定的键长度太大,但是我看了下执行语句,主键长度就255。而所使用的数据库默认是utf8mb4,所以当字段类型是varchar(255)类型时,它实际所占用的字节为255*4>1000。
解决方案
找到问题后就有3种解决方案
- 修改编码方式
- 修改索引最大长度
- 修改引擎
使用语句
SELECT@@global.innodb_large_prefix;查看innodb引擎是否开启允许索引列最大长度达到3072 如果没有开启,则执行语句SET GLOBAL innodb_large_prefix = ON;开启 我选择的是修改语句默认引擎,所以在JPA的配置文件中增加配置
spring:
jpa:
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
将默认引擎修改为innodb