《MySQL数据库》MySQL InnoDB详解
前言:以下内容均为MySQL5.7版本为准,在MySQL5.7版本中innodb是默认的存储引擎。
innodb结构
事务性表和非事务性表(Innodb,MyISAM )。 MyISAM 没有commit 和rollback。
创建表的时候指定存储引擎
CREATE TABLE `user` ( `id` int(64) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
innodb有页为单位存储数据。一页的大小为16KB,除了修改源码,不能修改。
查询MySQL也大小 show GLOBAL STATUS like 'Innodb_page_size'; --显示Innodb页大小。
特点:innodb创建哈希索引会自动转换成Btree索引,也就是说,Innodb其实没有哈希索引。
然后由N页存放一个表的数据,并且这些页之间关联,主键索引,最终组成N个B+树。
MySQL 中一页是16KB, 一个主键bigint字段暂用空间(8+6)个字节,8是bigint的大小,6是指针大小,假设每一行数据大小为1K。公式如下:
可以存储的数据 = (16*1024/(8+6)) * (16*1024/(8+6)) * 16K/1K = 21902400。 两千多万条数据。
B+树结构的好处:降低I/O 操作(B树一般三次I/O 即可),减少内存使用(不需要读取全部索引到内存)。
B+树的原理和使用Java实现了一颗B+树,详细说明:https://www.cnblogs.com/jssj/p/12897709.html。
B+树的普通索引:建立方式一致:有一点区别,先通过字段上的普通索引获取主键索引,然后再根据主键索引获取该列的全部数据,并且为最左优先。
B+树的叶子节点中存在了每一张的数据,这些数据如何存储的呢?
行格式
create table test1( name VARCHAR(65535) ) charset = ASCII Row_format=Compact
上面错误创建表会报错:提示:MySQL一列的除了BLOB 以外最多只能有65535个字节。为什么还报错呢,应该MySQL还有3个字节用于记录字段是否可以为空,是否可变长度。故实际最大只能65532个字节。
Mysql 目前有4种行格式:Redundant、Compact、Dynamic、Compressed
1. Compact
变长字段:采用1-2个字节来表示一个字段的长度,逆序,字段最大长度<= 255字节用1个字节表示;大于255字节,但是实际使用字节<=127,也使用1个字节来表示;其他情况使用2个字节来表示。
NULL标记:逆序,存储每条记录中允许为NULL的字段,将实际为NULL的字段用1表示,实际不为NULL的字段用0表示;每一列不是用一个字节来表示,而是用一个位来表示。
记录头信息:使用5个字节来表示;主要包含:该记录是否被删除,记录类型,下一条记录的相对偏移量。
列信息:就是你存放数据的信息。
2. Dynamic
与Compact行格式很像,差异在于页面溢出的处理上。 数据溢出,则新开一页存放每一行的溢出数据和指向之前行的信息。
3. Compressed
在于Dynamic使用了压缩算法。
4. Redundant (没有NULL标记)
字段长度偏移列表,用来记录每列的结束位置;真实数据(整条记录)<=127B 用1个字节记录,其他使用2个字节;
是使用1个字节还是2个字节来存储,该信息放在记录头的(1byte_offs_flag属性上),每个列记录的第一个bit 使用来表示该列是否位NULL。
总结
show table status like 'ic_base'; -- 查询表ic_base的创建信息
红框是我们熟悉的信息。 表名, 存储引擎,行格式。
MySQL的Innodb存储最终是为了查询效率服务的。