美文网首页
20191011-MySQL建索引的强约束

20191011-MySQL建索引的强约束

作者: zhangsanzhu | 来源:发表于2019-10-11 10:01 被阅读0次

问题:

[42000][1071] Specified key was too long; max key length is 3072 bytes
[42000][1071] Specified key was too long; max key length is 767 bytes

创建表出现上述错的原因是什么?

正文:

Utf8 1~3byte=1字符;Utf8mb4 1~4byte=1字符

mysql 从5.7.17 默认是严格模式,单个列的索引长度不能超过767byte==255.5位(推荐varchar(255)的原因),
启用innodb_large_prefix选项,就可以将单个列约束项扩展至3072byte,
非严格模式下非唯一索引的建立将不会报错,而是自动截取。
联合索引长度不能超过3072byte(在innodb_large_prefix=off也一样),非严格也是自动截取。

为什么是3072 ?

InnoDB一个page的默认大小是16k。由于是Btree组织,
要求叶子节点上一个page至少要包含两条记录(否则就退化链表了)。
所以一个记录最多不能超过8k。又由于InnoDB的聚簇索引结构,
一个二级索引要包含主键索引,因此每个单个索引不能超过4k (极端情况,pk和某个二级索引都达到这个限制)。
由于需要预留和辅助空间,扣掉后不能超过3500,取个“整数”就是(1024*3)。 

如何超越3072 ?

MySQL 索引只支持767个字节,utf8mb4 每个字符占用4个字节,
所以索引最大长度只能为191个字符,即varchar(191),若想要使用更大的字段,
mysql需要设置成支持数据压缩,并且修改表属性 row_format ={DYNAMIC|COMPRESSED}

MySQL中sql mode 中STRICT_ALL_TABLES和STRICT_TRANS_TABLES的区别

只要有他们就是严格模式。默认都是严格模式。

对于事务表,当启用STRICT_ALL_TABLES或STRICT_TRANS_TABLES模式时,
如果语句中有非法或丢失值,则会出现错误。语句被放弃并滚动。

对于非事务表,如果插入或更新的第1行出现坏值,两种模式的行为相同。
语句被放弃,表保持不变。如果语句插入或修改多行,并且坏值出现在第2或后面的
行,结果取决于启用了哪个严格选项:

对于STRICT_ALL_TABLES,MySQL返回错误并忽视剩余的行。但是,在这种情况
下,前面的行已经被插入或更新。这说明你可以部分更新,这可能不是你想要的。要
避免这点,最好使用单行语句,因为这样可以不更改表即可以放弃。


 对于STRICT_TRANS_TABLES,MySQL将非法值转换为最接近该列的合法值并插入
调整后的值。如果值丢失,MySQL在列中插入隐式 默认值。在任何情况下,MySQL
都会生成警告而不是给出错误并继续执行语句。

mysql row_format 说明

在 msyql 5.7.9 及以后版本,默认行格式由innodb_default_row_format变量决定,它
的默认值是DYNAMIC,也可以在 create table 的时候指定
ROW_FORMAT=DYNAMIC。用户可以通过命令 SHOW TABLE STATUS 
LIKE'table_name' 来查看当前表使用的行格式,其中 row_format 列表示当前所使用的行记录结构类型。

ROW_FORMAT

命令:

show variables like 'sql_mode'; //查看sql mode
select version(); //
show variables like 'innodb_large_prefix'; //
show table status like  'book_info_22'; //查看row_format
set global innodb_large_prefix=1;
set global innodb_file_format=BARRACUDA

参考:官方文档

相关文章

  • 20191011-MySQL建索引的强约束

    问题: 正文: 为什么是3072 ? 如何超越3072 ? MySQL中sql mode 中STRICT_ALL_...

  • sql基本语法

    DML/DDL/DCL、增删改查、建表、约束、序列sequence、索引index、游标cursor、plsql块...

  • day04 索引 约束 触发器

    1 索引 什么是索引 索引的分类 创建索引 删除索引 合理使用索引提升查询效率 2 约束 什么是约束 约束的类型 ...

  • 索引、视图

    索引 主键和UNIQUE约束字段会自动添加索引。 约束字段会自动添加索引。 因此根据主键查询效率较高。尽量根据主键...

  • sql 添加索引,外键约束

    索引 外键约束

  • 五、SQL—索引/约束①

    在数据库系统中解决问题的技术就是索引与约束。索引用来提高数据的检索速度约束则用来保证数据的完整性 索引 索引是建立...

  • MySQL—— 约束&索引

    约束 对表中字段(值)进行一定的约束限制,以保证数据的完整性、一致性、有效性约束的分类(2中基本约束)一、 (NO...

  • Postgresql 创建外键约束不会自动建索引

    RT

  • 17/12/13约束

    17/12/13约束 约束命名规则 表明_列名 _约束类型 unique约束(唯一约束) constraint(建...

  • Oracle索引

    索引具有两个功能:强制实施主键约束和唯一约束、提高性能。 索引的必要性: 主键和具有唯一性约束的列都会自动...

网友评论

      本文标题:20191011-MySQL建索引的强约束

      本文链接:https://www.haomeiwen.com/subject/iwftmctx.html