字符和字节一定要区分开 ,不要混淆
CREATE TABLE `biao` (
`name` varchar(16383) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `biao2` (
`name` varchar(21844) CHARACTER SET utf8mb3 COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
在biao中 name字段 utf8mb4的格式 能存储16383 字符长度
在biao2中 name字段 utf8mb3的格式 能存储21844 字符长度
使用show charset 可以查看字符集存储的最大字节数
16383*4=65532(字节)
21844*3=65532 (字节)
65536(字节)/1024(字节)=64kb 也就是4个页,1个页是16kb
也就是说varchar最大字节长度 不会超过4个页
varchar的字符长度根据字符集不同,存储的长度也不一样
如果name字段的varchar 已经设置了最大长度,那么就不能在添加其他的字段了
通过报错可以看到 行大小太大。所用表类型(不包括BLOB)的最大行大小为65535。这包括存储开销,请参阅手册。您必须将某些列更改为TEXT或BLOB。
查看行记录格式
show table status
Name就是表名
Engine:存储引擎
Row_format: 存储行记录的格式
Rows: 当前一共有多少行记录
Data_length: 存储多少个字节,16384就是16kb,也就是在磁盘行中存储一页数据
index_length: 索引存储的字节数
Auto_increment: 就是当前主键自增到哪里了
Collation: 表的字符集格式
Dynamic行格式
行记录的额外信息
可变的字段长度列表:varchar,text,blob,记录这些字段的长度,占2个字节
null值列表:记录当前行那些列是null,如果所有列都是not null,那么不需要这一列,占1个字节
记录头信息:用来记录一些预留位,标志位,比如说数据删除之后不会立马从磁盘删除,而是先打一个删除标记,后面在删除,占5个字节
行记录的真实信息
隐藏列
roll_pointer:回滚指针,用于undolog版本链回滚到上一个版本
trx_id:事务id,用于undolog每一个版本的id
row_id:隐藏主键,当表没有设置主键,和唯一索引,那么会创建一个隐藏的id当做主键
真实列
就是表里面的所有字段
行溢出
如果varchar这个字段超过了16kb,也就是1页数据,那么当前页只存储20个字节的页指针
所有的数据在其他页,页指针指向其他页的数据,但是会经过多次的磁盘io,因为需要去多个页读写数据,所以效率比较低,所以为啥在select *from biao的时候,不使用*字段 去查询,就是为了减少磁盘io的查询
行记录最大值
行记录最大值是不包含隐藏列和记录头的,所以
name字段的字节长度+null值列的字节长度+可变长度字段的列表字节=行记录的最大值
65532+2+1=65535,这也就是上面弹框提示,行大小为65535