mysql在创建数据库的时候,字符集设置的不是utf8而是utf9mb4,在导入sql脚本的时候,发现提示如下错误:
从上图中,我们可以看出,使用的是innodb及字符集。错误提示是长度太长了:Specified key was too long; max key length is 767 bytes
来查看下创建表的语句:
CREATE TABLE `xxl_job_registry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`registry_group` varchar(50) NOT NULL,
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
varchar的长度明明设置的是255啊。怎么会报出767 bytes的错误呢?
我们在看看错误提示:
[Err] 1071 - Specified key was too long; max key length is 767 bytes。
这个就是因为联合所以长度限制的。
我们来看看MySql InnoDB引擎对索引长度的限制:
mysql单索引限制:
在默认情况下,InnoDB对单一的字段索引长度限制最大为767个字节。
这个长度怎么来的呢 ?当mysql创建数据库的时候,字符集使用的是UTF-8的时候,我们知道UTF-8每个字符使用三个字节来存储的。即:256*3-1=767了。这个767字符大小的限制就是从这里来的。
联合索引(前缀索引)限制:
同样的,mysql对前缀索引也有同样的限制。根据字符集不同,长度限制也不同。
字符集使用utf8的时候长度限制是:767个
使用uft8mb4的时候长度限制是:3072个
但是,在文章一开始,凯哥就强调了,凯哥数据库使用的字符集是:utf8mb4。我们也知道,utf8mb4编码的每个字符使用四个字节来存储的。我们来计算下:256*4-1>767。
从凯哥的sql脚本可以看出:KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`) 使用到了联合索引(前缀索引)。
随意凯哥数据库的字符集使用的不是utf8,但是mysql系统变量innodb_large_prefix未开启(因为凯哥使用的是默认配置)。如果系统变量innodb_large_prefix开启了,就会对使用dynamic或者是comperssed行格式的InnoD表,索引键长度限制为3072个字节了。如果没有开启这个,InnoDB会对,无论什么表索引键长度限制都是767了。
解决方案有两种:
1:mysql系统变量innodb_large_prefix开启。
需要修改配置,重启mysql服务等等。。。太麻烦了。凯哥这里使用了第二种方案
2:修改联合主键中每个字段的长度
联合主键的三个字段如下:
`registry_group` varchar(50) NOT NULL,
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
将varchar(255)的修改为varchar(100)后(注:这里的长度根据自己需求进行设置。如果非要用255个字符以上,请选择使用第一种解决方案),sql脚本就执行成功。如下图:
延伸知识点:
当遇到如下错误:
错误信息是3072的时候,说明开启了系统变量,但是还是超长了。这个时候,可以采用同样的方案来处理。
本文来源:凯哥Java(kaigejava)
相关推荐
当此选项开启时,单个索引的长度可以增加到3072字节,但联合索引的总长度仍然受限于3072字节。在MySQL 5.7及更高版本中,默认情况下`innodb_large_prefix`是启用的,而在MySQL 8.0中,这个选项已被移除,意味着更大...
但该索引可以包含多个列(联合索引)。 非聚集索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同,一个表可以包含多个非聚集索引。 ### MySQL 索引的分类 MySQL 索引包括普通索引、惟一性索引、全文索引、单列...
同时,禁止使用MySQL保留字,并且建议命名长度不超过32个字符,各部分之间使用下划线连接。对于临时库和备份库,也有相应的前缀和后缀的命名规则。 基础规范强调了数据库的存储引擎、字符集、主键设计、注释添加...
- 联合索引命名时按创建顺序列出字段名,限制不超过3个字段。 - 索引名称长度不得超过30个字符。 **2.7 包命名** - 包命名根据用途区分: - 功能模块包命名格式为`PKG+_+模块名`。 - 个人功能或数据处理包命名...
- 索引列长度有限制,InnoDB中索引列最大200个字符。 - 选择性高且经常被查询的列优先考虑作为索引。 - 联合索引中,选择性高的列放在前面,小的列也优先,以提高查询效率。 **建立索引策略:** - 根据业务需求和...
MySQL 相关知识点总结 MySQL 存储引擎基于表的创建时,默认使用 InnoDB,从 5.5 版本开始,之前的默认存储引擎是 MyISAM。InnoDB 支持事务、行锁、外键约束,保证数据的...联合索引可以存在多个查询条件,建议使用。
- **`max_connections=最大连接数`**: 最大连接数的设定,用于限制同时连接到MySQL服务器的客户端数量。 **启动与停止MySQL服务**: - `net stop/start mysql服务名`: 分别用于停止和启动MySQL服务。 - `mysql -h ...
- `explain`结果含义包括:`table`(表名)、`type`(连接类型)、`possible_keys`(可能使用的索引)、`key`(实际使用的索引)、`key_len`(索引使用部分的长度)、`ref`(显示列名字或const)、`rows`(MySQL认为...
- `%` 表示匹配任意长度的字符串,例如 `'%a%'` 匹配包含 `a` 的任何字符串。 #### 三、表结构修改 - **添加列**: - `alter table tabelName add column fieldName dateType;` 可以向表中添加新列。 - 添加多...
- **联合索引**:合理创建联合索引,如(a, b, c)相当于(a), (a, b), (a, b, c)。 #### 七、SQL编写规范 - **限制IN子句值的数量**:SQL语句中IN子句包含的值不应过多,建议不超过500个。 - **避免使用LIMIT**:...
- **优化查询语句**:简化查询逻辑,避免使用不必要的子查询或联合查询。 - **使用适当的索引**:为常用的查询条件创建索引。 - **定期维护数据库**:包括重新组织索引、优化表结构等。 #### 五、应用优化 除了...
- 最左匹配原则:联合索引在`WHERE`子句中需按索引顺序使用列。 - 避免函数操作索引列:如`WHERE lower(column)=value`会导致索引失效。 4. **Char和Varchar的区别**: - Char是定长,Varchar是变长,Char适合...
MySQL以YYYY-MM-DD格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列 4.CHAR(M) 型:定长字符串类型,当存储时,总是是用空格填满右边到指定的长度 5.BLOB TEXT类型,最大长度为(2^16-1)个字符。 6...
- VARCHAR是变长字符串,只存储实际长度的字符,节省空间。 - CHAR是定长字符串,无论内容是否填满,都会占用指定的字符数。 10. **MySQL组成部分**: - MySQL由服务器、客户端、存储引擎、网络协议等部分组成,...
1. 库名、表名和字段名应使用小写字母,并用下划线分隔,长度限制在12个字符以内,以保持一致性和可读性。 2. 使用有意义的名词,避免动词,以便于理解表的用途。 3. 推荐使用InnoDB存储引擎,它支持事务处理和行级...
3. 数据类型:MySQL支持多种数据类型,如数值类型(INT、FLOAT、DECIMAL)、字符串类型(VARCHAR、TEXT)、日期时间类型(DATE、TIME、DATETIME)等。 二、数据库管理 1. 创建与删除:使用CREATE DATABASE语句创建...