#MySQL# 文章列表 MySQL:简介 Ubuntu 安装 MySQL MySQL:官方文档地址 MySQL:DDL、DQL、DML、DCL的含义 MySQL:Mac 中启动 关闭 MySQL 服务 MySQL:有哪些好用的管理工具? MySQL:命令行工具 mycli MySQL:CHAR类型 MySQL:VARCHAR类型 MySQL:整型数字 MySQL:datetime 类型 MySQL:时间戳 MySQL:创建和删除数据库 MySQL:切换和查看数据库 MySQL:创建和删除表 MySQL:在表中增加、删除、修改列 MySQL:创建和删除主键 MySQL:使用 rename 修改表名 MySQL:修改自增主键id的类型 MySQL:如何创建一个相同的表 MySQL:修改表的字符编码 MySQL:增删查改 MySQL:插入数据 MySQL:插入多行数据 MySQL:使用 insert set 插入数据 MySQL:大小写和反引号 MySQL:字符串类型值的大小写 MySQL:SQL注释 MySQL:不要使用utf8 MySQL:NULL的判等 MySQL:InnoDB存储引擎的限制 MySQL:if和case的使用 MySQL:使用 load data 快速导入数据 MySQL:使用 select into outfile 导出数据 MySQL:查询和设置 sql_mode MySQL:严格模式 MySQL:NOT NULL 字段不插入数据,会发生什么? MySQL:无符号整数列插入负数会发生什么? MySQL:关于 null 的那些事 MySQL:大表行数查询 MySQL:自动生成创建时间、更新时间;自动更新更新时间 MySQL:insert ignore MySQL:字符集排序规则 MySQL:如果连续更新一个字段两次,结果是? MySQL:字符串转数字 MySQL:尾部空格 MySQL:添加和删除索引 MySQL:唯一索引与NULL MySQL:唯一索引的单列长度限制 MySQL:InnoDB 索引 MySQL:字符集排序规则对唯一索引的影响 MySQL:唯一索引冲突消耗主键 ID MySQL 使用 index hint 指定索引:ignore index、force index、use index MySQL:查看客户端连接信息 MySQL:查看表的状态 show table status MySQL:如何治理连接数 ? MySQL:如何监控和处理慢查询与长事务 ? MySQL:自定义函数 MySQL:now() 函数 MySQL:unix_timestamp() 函数 MySQL:from_unixtime() 函数 MySQL:version() 函数 MySQL:current_timestamp() 函数 MySQL:cast 函数 MySQL:convert 函数 MySQL:使用 greatest、least 函数获取行最大值、最小值 MySQL:使用 group_concat 函数连接多行数据为一个字符串 MySQL:获取版本号 MySQL:Java 类型映射 MySQL下创建只能有一行记录的table 关于MySQL的字符集 理解数据库中的undo日志、redo日志、检查点 ubuntu下源码安装MySQL MySQL:JOIN解惑 如何快速更新数据库中的百万条数据

MySQL:InnoDB存储引擎的限制


#MySQL#


https://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html 给出了 5.6 版本的限制。注意,不同版本 MySQL 的限制可能略有不同。

这里列出 InnoDB 存储引擎的部分限制:

  • 一张表最多可以有 1017 列。
  • 一张表最多64个二级索引。(说明:主键是一级索引,也可以叫做「聚集索引」;除了主键外的其他索引,是二级索引,或者说是「非聚集索引」。)
  • 对于string类型(如char、varchar、text等)的列,在用它做索引时,只会用字符串前面的部分做索引。
    • 对CHAR、 VARCHAR、BINARY 和 VARBINARY 类型的列,创建索引时候,可以指定用前面的多少字符做索引,也可以不指定,InnoDB会自动做限制(但会用尽可能多的字符做索引)。
    • 对 BLOB 和 TEXT 类型的列,必须指定用前面的多少字符做索引。
  • 一列能索引的字节不能超过 767 。若启用了innodb_large_prefix ,一列能索引的字节不能超过 3072 。 innodb_large_prefix 默认未启用。
    • 所以,对于使用utf8mb4字符集的表,TEXT、VARCHAR、CHAR等类型的列,只能用前面的 191 个字符做索引,因为 191×4=764,192×4=768。
  • 页大小(page size)默认为16KB,对应的,一个索引(联合索引也算一个索引)最多支持 3072 个字节。页大小是在创建MySQL实例(可以理解为安装MySQL)时指定的。若页大小设置为8KB,则一个索引最多支持 1536 个字节;若设置为4KB,则一个索引最多支持 768 个字节。
  • 一个联合索引,最多可含有16列。
  • 行的大小(row size)不能超过 65535 字节。否则创建表的时候胡报错,例如:
mysql> CREATE TABLE t (a VARCHAR(10000), b VARCHAR(10000),
       c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
       f VARCHAR(10000), g VARCHAR(6000)) ENGINE=InnoDB CHARACTER SET latin1;
ERROR 1118 (42000): Row size too large. The maximum row size for the used 
table type, not counting BLOBs, is 65535. This includes storage overhead, 
check the manual. You have to change some columns to TEXT or BLOBs

latin1 字符集中每个字符1字节。根据报错信息,可以看出 65535 的限制是在去除 TEXT、BLOB 之后。所以下面的不会报错:

mysql> CREATE TABLE t (a VARCHAR(10000), b VARCHAR(10000),
       c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
       f VARCHAR(10000), g TEXT(6000)) ENGINE=InnoDB CHARACTER SET latin1;
Query OK, 0 rows affected (0.02 sec)
  • 除去变长列(VARBINARY, VARCHAR, BLOB and TEXT)),行的长度(row length)应略小于页的大小的一半。也的默认大小是16KB。这个限制,在创建表的时候不会报错,在插入数据时可能报错,例如:
create table test_table (
    c1 CHAR(255),
		c2 CHAR(255),
		c3 CHAR(255),
		c4 CHAR(255),
		c5 CHAR(255),
		c6 CHAR(255),
		c7 CHAR(255),
		c8 CHAR(255),
		c9 CHAR(255),
		c10 CHAR(255),
		c11 CHAR(255),
		c12 CHAR(255),
		c13 CHAR(255),
		c14 CHAR(255)
) engine = InnoDB character set = utf8mb4;

表创建成功,使用 utf8mb4 字符集。

插入数据:

-- @you255 含有255个'你'
set @you255 = '你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你你'

insert into test_table (c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14) values(
@you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255, @you255
)

报错:

(1118, u'Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.')
  • SHOW TABLE STATUS给出的信息是不精确的。
  • 在 Windows 上,数据库名和表名,都以小写的形式存储。
  • 这些名称的大小写都不能当做列名,因为MySQL内部会用到:DB_ROW_ID, DB_TRX_ID, DB_ROLL_PTR, DB_MIX_ID 。
  • 表内部不会存储有多少行数据,需要用SELECT COUNT(*)查询得到。
  • AUTO_INCREMENT 类型的列必须被索引。注意,主键也是一种索引。

( 本文完 )