1.innodb的存储引擎表类型

如果在创建表时没有显示的定义主键,则innodb存储引擎会按如下方式选择或创建主键

a.首先表中是否有非空的唯一约束(Unique not null)如果有,则该列即为主键

b.不符合上述条件,innodb存储引擎自动创建一个6个字节大小的指针

2.innodb逻辑存储结构

结构和oracle大致相同,所有数据被逻辑的存放在一个空间中,称之为表空间

表空间由 段 区 页 组成,页在一些文档中有时也称为块(block),innodb存储引擎的逻辑存储结构如下图

启用innodb_file_per_table 参数,每张表的表空间内存放的只是数据,索引和插入缓冲

其他数据:撤销信息,系统事务信息、二次写缓冲等还是存在原来的共享表空间内(ibdata1),这也就说明:

即使在启用了参数innodb_file_per_table 之后,共享表空间还是会不断地增加其大小

mysql> show variables like 'innodb_file_per_table'\G;
*************************** 1. row ***************************
Variable_name: innodb_file_per_table
Value: ON
1 row in set (0.05 sec)

ERROR:
No query specified

mysql> system ls -lh /opt/mysql25/data/ib*
-rw-rw----. 1 mysql mysql 76M May 26 21:06 /opt/mysql25/data/ibdata1
-rw-rw----. 1 mysql mysql 48M May 26 21:06 /opt/mysql25/data/ib_logfile0
-rw-rw----. 1 mysql mysql 48M May 26 21:06 /opt/mysql25/data/ib_logfile1
mysql>

共享表空间的大小为76M

mysql> set autocommit=0;

mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | OFF |
+---------------+-------+
1 row in set (0.00 sec)

mysql> update mytest set name='xianyu' where name='zhuchenghan';
Query OK, 2097152 rows affected (16.97 sec)
Rows matched: 2097152 Changed: 2097152 Warnings: 0

update 后发现ibdata已经增长到了 140MB 这就说明了共享表空间包含undo信息

mysql> system ls -lh /opt/mysql25/data/ib*;
-rw-rw----. 1 mysql mysql 140M May 26 22:21 /opt/mysql25/data/ibdata1
-rw-rw----. 1 mysql mysql 48M May 26 22:21 /opt/mysql25/data/ib_logfile0
-rw-rw----. 1 mysql mysql 48M May 26 22:21 /opt/mysql25/data/ib_logfile1
mysql>

mysql> rollback;
Query OK, 0 rows affected (17.35 sec)

rollback后 大小还是为140M

mysql> system ls -lh /opt/mysql25/data/ib*
-rw-rw----. 1 mysql mysql 140M May 26 22:24 /opt/mysql25/data/ibdata1
-rw-rw----. 1 mysql mysql 48M May 26 22:24 /opt/mysql25/data/ib_logfile0
-rw-rw----. 1 mysql mysql 48M May 26 22:23 /opt/mysql25/data/ib_logfile1

因此很可能的一种情况是再次执行上述的update语句后,会发现ibdata1 不会再增大了

数据段为 B+树的的页节点,索引段为B+树的非索引节点,表空间是由分散的页和段组成

启用参数 Innodb_file_per_table 后 创建的表的大小是96KB,区是64个连续的页,

那创建的表的大小至少是 1MB 才对,其实是因为在每个段开始时,先有32个页大小的碎片页来存放数据,

当这些页使用完之后才是64个连续页的申请

页是innodb磁盘管理的最小单位

数据页

Undo页

系统页

事务数据页

插入缓冲位图页

插入缓冲空闲列表页

未压缩的二进制大对象页

压缩的二进制大对象列

innodb存储引擎是面向行的,也就是说数据库存放按照行进行存放

innodb 的物理结构

从物理意义上来看,innodb表由共享表空间,日志文件组,表结构定义文件组成

若将innodb_file_per_table 设置为ON 则每个表将独立地产生一个表空间文件

以ibd 结尾,数据,索引,表的内部数据字典信息都将保存在独立的表空间中.

表结构以frm结尾,这个与存储引擎无关,任何存储引擎的表结构定义都为.frm文件

innodb行记录格式

记录是以行形式存储.

意味着页中保存着表中一行行的数据.

innodb行格式记录

Compact Redundant

mysql> show table status like 'mytest' \G;
*************************** 1. row ***************************
Name: mytest
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 2092230
Avg_row_length: 40
Data_length: 85573632
Max_data_length: 0
Index_length: 0
Data_free: 7340032
Auto_increment: NULL
Create_time: 2017-05-26 20:48:09
Update_time: NULL
Check_time: NULL
Collation: latin1_swedish_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.01 sec)

数据库实例的一个作用就是读取页中存放的行记录,如果我们知道规则,也可以读取其中的记录

Compact行记录格式

5.0被引入,设计目的是高效存放数据.

Compact 行记录格式如下方式进行存储

Compact格式的 varchar和 char的 null都不占用空间

Redundant 行记录格式

redundant是mysql5.0版本前Innodb的行记录存储方式,是为了向前兼容性

redundant行格式下 的varchar不占用任何存储空间

行溢出数据

Innodb存储引擎可以将一条记录中的某些数据存储在真正的数据页面之外,即作为溢出数据

一般认为BLOB、LOB这类的大对象列类型的存储会把数据存放在数据页面之外

Mysql的varchar数据类型可以存放65535个字节,但是这需要论述

mysql> create table test3 (a varchar(65535)) charset=latin1 engine=innodb;
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 hav

从错误消息可以看到,Innodb存储引擎并不支持65535的varchar,因为还有别的开销,因此实际能存放长度为65532

mysql> create table test3 (a varchar(65532)) charset=latin1 engine=innodb;
Query OK, 0 rows affected (0.11 sec)

如果做上述例子的时候并没有将sql_mode设置为严格模式,则可能会出现可以建立表,但是会有警告信息

警告信息提示了 之所以可以创建是因为mysql自动将varchar转换成了TEXT 类型.如果我们看test的表结构,

会发现mysql自动将varchar类型转换成了MEDIUTEX 类型

需要注意的是上述创建varchar长度为65535的表其实是 latin1 的如果换成GBK 或utf8会怎么样

这次即使创建65532也会报错,但是两次报错对于max值的提示是不同的,因此我们应该理解varchar(N)中,N指的是字符的长度,

varchar类型最大支持65535指的是65535 个字节

此外,mysql官方手册中定义的65535长度是指VARCHAR列的长度总和,

如果列的长度总和超出这个长度,依然无法创建

3个列长度总和是66000,因此Innodb 存储引擎再次报了同样的错误,即使我们能存放65532个字节了,但是INNODB 存储引擎的页为16KB

即16384 个字节,怎么能存放65532个字节呢?

一般情况数据都存储在 B-TREE Node 的页类型中,但是当发生溢出时,则这个存放行溢出的页类型为 Uncompress BLOB Page

mysql> create table t3(a varchar(65532));
Query OK, 0 rows affected (0.04 sec)

mysql>
mysql> insert into t3 select repeat('a',65532);
Query OK, 1 row affected (0.09 sec)
Records: 1 Duplicates: 0 Warnings: 0

可以看到一个B-tree Node页类型,另外4个为Uncompressed BLOB Page

这些页中才真正存放了65532个字节的数据,既然实际存放的数据都放到BLOB中,数据页放的什么呢

通过hexdump来读取表空间文件

.......

可以看到,对于行溢出数据,存储方式如下

mysql> create table t4 (a varchar(9000));
Query OK, 0 rows affected (0.06 sec)

mysql>
mysql>
mysql> insert into t4 select repeat('a',9000);
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0

但是如果可以在一个页中至少放入两行的数据,那varchar就不会放到blob页中

这个阀值的长度为8098

innodb 表的更多相关文章

  1. MySQL InnoDB表--BTree基本数据结构

    MySQL InnoDB表是索引组织表这一点应该是每一个学习MySQL的人都会首先学到的知识,这代表这表中的数据是按照主键顺序存储,也就是说BTree的叶子节点存储了所有该行的数据. 我最开始是搞Or ...

  2. Innodb 表空间传输迁移数据

    在mysql5.5之前,mysql实例中innodb引擎表的迁移是个头疼的问题,要么使用mysqldump导出,要么使用物理备份的方法,但是在mysql5.6之后的版本中,可以使用一个新特性,方便地迁 ...

  3. [MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键

    我们先了解下InnoDB引擎表的一些关键特征: InnoDB引擎表是基于B+树的索引组织表(IOT): 每个表都需要有一个聚集索引(clustered index): 所有的行记录都存储在B+树的叶子 ...

  4. Innodb 表空间卸载、迁移、装载

    从MySQL的Innodb特性中我们知道,Inndob的表空间有共享和独享的特点,如果是共享的.则默认会把表空间存放在一个文件中(ibdata1),当开启独享表空间参数Innodb_file_per_ ...

  5. Innodb之拷贝InnoDB表从一服务器到另一台服务器2

    本章节阐述将表移动到不同server上的技术.如可以将整个Mysql 实例转移到更大.更快的Server上:也可以拷贝整个实例到Slave上:也可以拷贝单个表或某些表到其他Server上(数据仓库). ...

  6. Innodb 表修复(转)

    摘要:      突然收到MySQL报警,从库的数据库挂了,一直在不停的重启,打开错误日志,发现有张表坏了.innodb表损坏不能通过repair table 等修复myisam的命令操作.现在记录下 ...

  7. 14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器

    14.8.4 Moving or Copying InnoDB Tables to Another Machine 移动或者拷贝 InnoDB 表到另外机器 这个章节描述技术关于移动或者复制一些或者所 ...

  8. 14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构

    14.8.3 Physical Row Structure of InnoDB Tables InnoDB 表的物理行结构 一个InnoDB 表的物理行结构取决于在创建表指定的行格式 默认, Inno ...

  9. 14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用

    14.8.2 Role of the .frm File for InnoDB Tables InnoDB 表得到 .frm文件的作用 Vsftp:/data01/mysql/zjzc# ls -lt ...

  10. 14.8.1 Creating InnoDB Tables 创建InnoDB 表

    14.8.1 Creating InnoDB Tables 创建InnoDB 表 创建一个InnoDB表,使用CREATE TABLE 语句,你不需要指定ENGINE=InnoDB 子句 如果Inno ...

随机推荐

  1. shell 检查文件夹是否包含文件,或者只是空文件

    empty_dir_check(){ check_dir=$ if [ -d $check_dir ];then file_list=` -maxdepth -type f` if [ $file_l ...

  2. Windows进程调度相关

    结构体所在环境: Windows XP Version 2600 (Service Pack 3) UP Free x86 compatible EPROCESS: ntdll!_EPROCESS + ...

  3. 2019-7-15-WPF-测试触摸设备发送触摸按下和抬起不成对

    title author date CreateTime categories WPF 测试触摸设备发送触摸按下和抬起不成对 lindexi 2019-7-15 9:3:51 +0800 2019-0 ...

  4. WSGI——python-Web框架基础

    1. 简介 WSGI ​ WSGI:web服务器网关接口,这是python中定义的一个网关协议,规定了Web Server如何跟应用程序交互.可以理解为一个web应用的容器,通过它可以启动应用,进而提 ...

  5. Deployment的使用

    RC和RS的功能基本上是差不多的,唯一的区别就是RS支持集合的selector. RC|RS是Kubernetes的一个核心概念,当我们把应用部署到集群之后,需要保证应用能够持续稳定的运行,RC|RS ...

  6. Centos6.5升级安装openssh7.7p1

    Centos6.5升级安装openssh7.7p1  关于OpenSSH漏洞   2016年1月14日OpenSSH发布官方公告称, OpenSSH Client 5.4~7.1 版本中未公开说明的功 ...

  7. 关于sublime使用中写less代码高亮显示问题

    一开始在没有配置的情况下在sublime中写less代码是不会有高亮显示的.下面说一下配置过程 一.安装Less2Css模块 打开sublime,ctrl+shift+p,输入package cont ...

  8. wordpress翻译插件gtranslate

    https://www.gdstautoparts.com/

  9. jQuery 事件 click() 方法,dblclick() 方法

    click() 方法 当点击元素时,会发生 click 事件. 当鼠标指针停留在元素上方,然后按下并松开鼠标左键时,就会发生一次 click. click() 方法触发 click 事件,或规定当发生 ...

  10. 如何打造7*24h持续交付通道?阿里高级技术专家的5点思考

    我们对于研发效能的讨论,本质上是提高整个技术生态中的协同效率.如果仅从研发角度出发,技术团队要实现的终极目标是7*24小时的灵活发布窗口,以及更快的业务迭代能力. 7*24小时发布窗口的实现其实并不简 ...