写点什么

InnoDB(4,java 中级工程师面试题

用户头像
Java高工P7
关注
发布于: 2 小时前

索引组织表

**在 InnoDB 存储引擎中,表中的数据都是根据主键顺序组织存放的,这种


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


存储方式的表称为索引组织表**


所以在 InnoDB 存储的引擎表中,都必须有个主键(primary key),如果在创建表时没有显示地定义主键,则 InnoDB 存储引擎会按照下面的方式选择或者创建主键


  • 首先判断表中是否有非空的唯一索引,即 unique key not null,如果有,那么该列就会变为主键(rowid)

  • 如果有多个非空的唯一索引,则会选择建表时第一个定义的非空唯一索引作为主键(rowid)

  • 如果不符合上述条件,InnoDB 存储引擎将自动创建一个 6 字节大小的指针(rowid)


举个栗子


CREATE TABLE z(


a INT NOT NULL,


b INT NULL,


c INT NOT NULL,


d INT NOT NULL,


UNIQUE KEY(b),


UNIQUE KEY(c),


UNIQUE KEY(d)


)ENGINE=INNODB,CHARSET=utf8;


从建表上看,可以看到 b、c、d 列都有唯一索引,但 b 可以为 NUll,故不可以充当主键,而第一个非空唯一索引是 c 列,所以 c 将会充当主键。


//插入几条数据


INSERT INTO z SELECT 1,2,3,4;


INSERT INTO z SELECT 1,3,4,5;


INSERT INTO z SELECT 1,4,5,6;


INSERT INTO z SELECT 1,5,6,7;


//查询情况,_rowid 可以判断主键是哪一列


SELECT a,b,c,d,_rowid FROM z;


结果如下所示



可以看到**_rowid**跟 c 列一模一样,所以可以确定 c 列成为了主键


但是**_rowid**只可以看单个列作为主键的情况,如果使用多个列作为主键是查询不了的


//当遇到下面的建表语句是无法使用 rowid 查询的


CREATE TABLE z2(


a INT NOT NULL,


b INT NOT NULL,


c INT NOT NULL,


PRIMARY KEY(a,b)


)ENGINE=INNODB,CHARSET=utf8;

InnoDB 逻辑存储结构

从 InnoDB 存储的逻辑存储结构看,所有数据都被逻辑地存放在一个空间里面,称之为表空间(tablespace)。而表空间又由段(segment)、区(extent)、页(page)组成,页有时也会被成为块。


其实是段里面的是区,区里面的是页,页里面还有行


表空间

前面的 InnoDB 存储文件提到过,所有的数据都是存放在表空间里面的,默认会有一个表空间 ibdata1,即所有的数据都会在该表空间里面,不过前面也提到过,如果开启了参数 innodb_file_per_table,则每张表内的数据可以单独放到一个表空间内,不过单独的表空间里面只存放的数数据、索引和插入缓冲 Bitmap 页,其他信息,比如插入缓冲的索引页,回滚信息,锁信息,二次写缓冲等还是存放在原来的共享表空间里面。


这同时也说明了一个问题,即使开启了参数 innodb_file_per_table,共享表空间也是会不断增加其大小的,会继续膨胀

表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等。


数据段其实就是 InnoDB 索引底层实现结构的 B+树的叶子结点(leaf node segment),索引段即为 B+树的非索引结点(Non-leaf node segement),回滚段则比较特殊,后面在介绍


在 InnoDB 存储引擎中,对段的管理都是由引擎自身所完成的,用户没有权限去进行管理,同时也没有必要去管理。

区是由连续页组成的空间,任何情况下,区的大小都为 1MB( 2 10 K B 2^{10}KB 210KB),为了保证区中页的连续性(因为页是存储真正数据的,为了让页的存放可以连续,不要断开到另一个区),所以 InnoDB 存储引擎一次从磁盘申请 4~5 个区在默认情况下,InnoDB 存储引擎页的大小为 16KB( 2 6 K B 2^6KB 26KB),即一个区中一共有 64( 2 8 K B 2^8KB 28KB)个连续的页


InnoDB 中可以使用 InnoDB_page_size 参数去控制每页的大小,可以设置为 4K、8K(默认为 16K),这样的话,区中存放的页的数量就会相应的变为 256 和 128,但区的大小仍然为 1MB,这是雷打不动的


SHOW VARIABLES LIKE "innodb_page_size";

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
InnoDB(4,java中级工程师面试题