Home > Database > Mysql Tutorial > body text

MySQLInnoDB存储引擎之表(一)_MySQL

WBOY
Release: 2016-06-01 13:01:01
Original
1783 people have browsed it

主要介绍InnoDB存储引擎表的逻辑存储以及实现。重点介绍数据在表中是如何组织和存放的。

1.索引组织表(index organized table)

在InnoDB存储引擎中,表都是根据主键顺序组织存放的,这种存储方式的表叫索引组织表。在InnoDB存在引擎表中,每张表都有个主键(Primary key),如果在创建表时没有显示定义主键,则会按照如下方式选择或者创建主键:a.判定是否有非空的唯一索引(unique not null),如果有则该列即为主键。若果有多个,则选择建表是第一个定义的非空位于索引为主键。注意:主键的选择根据的是定义索引的顺序,而不是建表时的列的顺序。 b.如果不存在唯一索引,InnoDB存储引擎字段创建一个6字节大小的指针。

2.InnoDB逻辑存储结构
在InnoDB存储引擎中,所有的数据都被逻辑地存放在一个空间中,称之为表空间(tablespace)。表空间又由段(segment)、区(extent)、页(page)组成。页在一些文档中有时也称之为块(block)。InnoDB存储引擎的逻辑存储结构如下图。
vc/M2Mri0tS689TavenJ3KGjts62vMrH0v3H5tfUye253MDttcShozxicj4KICAgIEMux/g8YnI+CiAgICAgICAgx/jKx9PJwazQ+NKz1+mzybXEv9W85KGjSW5ub0RCtOa0otL9x+bSs7XEtPPQoc6qMTZLQqOs0ru49sf409A2NLj2wazQ+LXE0rPX6bPJo6zL+dLUw7+49sf4tcS089ChtrzKxzFNQqGjSW5ub0RCIDEuMC54sOaxvr+qyrzS/cjr0bnL9dKzo6y8tMO/uPbSs7XEtPPQob/J0tTU2r2ose3Ksc2ouf2yzsr9a2V5X2Jsb2NrX3NpemXJ6NbDzqoyS6GiNEuhojhLo6zS8rTLw7+49sf4ttTT2tKztcTK/cG/vs3OqjUxMqGiMjU2oaIxMjaho0lubm9EQiAxLjIuWLDmsb7QwtT2ss7K/Wlubm9kYl9wYWdlX3NpemW9q8SsyM/Ss7XEtPPQocno1sPOqjRLoaI4S6OstavKx9Kz1tC1xMr9vt2yu8rH0bnL9aOs1eLKx8f41tC1xMr9wb/NrNH5zqoyNTahojEyOKGj0ru+5Luwo6yyu8Lbwta1xLTz0KHU9cO0seS7r6Osx/i1xLTz0KGyu7HkMU2ho7WrysfT0NXi0fnSu7j2zsrM4qO61Nq/qsb0tsDBorHtv9W85NauuvOjrLS0vai1xLHtxKzIz7Tz0KHKxzk2S6Osx/jW0MrHNjS49sGs0Pi1xNKzo6y0tL2otcSx7b/VvOTTprjDyscxTbLFttTRvaO/1eLKx9LyzqrU2sO/uPa2zrXEv6rKvMqxo6zPyNPDMzK49tKztPPQobXEy+nGrNKzKGZyYWdtZW50CiBwYWdlKcC0saO05sr9vt2jrNTayrnTw83q1eLQqdKz1q6687LFysc2NLj2wazQ+LXE0rO1xMnqx+uho9Xi0fnX9srHttTT2tK70KnQobHtu/LV33VuZG/V4sDgtcS2zqOsv8nS1NTav6rKvMqxyerH673Pydm1xL/VvOSjrL3ayqG0xcXMyN3Bv7XEv6rP+qGjPGJyPgogICAgRC7Sszxicj4KICAgICAgICDSs8rHSW5ub0RCtMXFzLncwO21xNfu0KG1pc67oaPErMjPtPPQoc6qMTZLo6y/ydLUzai5/Wlubm9kYl9wYWdlX3NpemW9q9KztcS089ChyejWw86qNEuhojhLoaIxNkujrNTyy/nT0LHt1tDSs7XEtPPQoba8zqrJ6NbDJiMyMDU0MDujrLK7v8nS1LbUxuTU2bTO0N64xKGjs/23x82ouf1teXNxbGR1bXC1vMjrus21vLP2stnX98C0svrJ+tDCtcS/4qGjs6O8+7XE0rO1xMDg0M3T0DrK/b7d0rMoQi10cmVlIE5vZGUpoaJ1bmRv0rModW5vZCBMb2cgUGFnZSmhos+1zbPSsyhTeXN0ZW0gUGFnZSmhosrCzvHK/b7d0rMoVHJhbnNhY3Rpb24gc3lzdGVtIFBhZ2UpoaKy5cjru7qz5b/Vz9DB0LHt0rMoSW5zZXJ0IEJ1ZmZlciBGcmVlIExpc3QpoaLOtNG5y/W1xLb+vfjWxrTzttTP89KzKFVuY29tcHJlc3NlZAogQkxPQiBQYWdlKaGi0bnL9bXEtv69+NbGttTP89KzKGNvbXByZXNzZWQgQkxPQiBQYWdlKTxicj4KICAgIEUu0NA8YnI+CiAgICAgICAgSW5ub0RCtOa0otL9x+bKx8Pmz/LQ0LXEKHJvdy1vcmllbnRlZCmjrNKyvs3Kx8u1yv2+3crHsLTQ0L340NC05rfFtcSho8O/uPbSs7Tmt8W1xNDQvMfCvNKyysfT0NOy0NS2qNLltcSjrNfutuDUy9DQtOa3xTE2Sy8yLTIwMNDQtcS8x8K8o6y8tDc5OTLQ0LzHwryhozwvcD4KCjxwPjMuSW5ub0RC0NC8x8K8JiMyNjY4NDvKvTxicj4KICAgIElubm9EQrTmtKLS/cfmtcS8x8K8ysfS1NDQtcTQzsq9tOa0orXEo6zV4r7Nse3D99Kz1tCxo7Tm18Wx7dbQ0rvQ0NDQtcTK/b7doaPG5MDg0M3T0FJFRFVOREFOVKGiIENPTVBBQ1ShokNPTVBSRVNToaJEWU5BTUlDy8TW1qGjv8nS1M2ouf1zaG93ICB0YWJsZSBzdGF0dXM7wLSy6b+0tbHHsL/i1tDDv9XFse21xMr9vt0mIzI2Njg0O8q9yOfPws28Ojxicj4KICAgPGltZyBzcmM9"http://www.bitsCN.com/uploadfile/Collfiles/20141202/20141202092356171.jpg" alt="\">
A.COMPACT
在MySQL 5.0中引入,其设计目标是高兴的存储数据。也就是一个页中存放的行数据越多,其性能越高。compact行记录的存放方式:

\
有图可知,compact行记录格式的首部是一个非NULL变长字段长度列表,并且其是按照列的顺序逆序放置的,其长度为:
若列的长度小于255个字节,用1字节表示;
若大于255个字节,用2字节表示。
变长字段之后的第二个部分是NULL标志位,该位置指示了该行数据中是否有NULL值,有这用1表示。该部分占1个字节。接下来就是占用5个字节的记录头信息(record header),每位的含义如下图:

\
最后的部分就是实际存储每列的数据。注意NULL不占该部分的任何空间,也就是说NULL除了占有NULL标志位,实际存储不占任何空间。每行除了用户定义的列外,还有2个隐藏列(事务ID列(6字节)和回滚指针列(7字节))。若InnoDB表没有定义主键,还会增加一个6字节的rowid列。不管是char类型还是varchar类型,在compact格式下NULL值都不占用任何存储空间。
COMPACT行格式特点:
每个也记录都有5字节长度域,用于指向下一个连续的页,并且可用于实现行锁
有个变长域,存储页中有多少可能为NULL的字段数,长度为 CEILING(N/8)字节,同时也需要用1~2字节存储边长字段所需长度
所有非NULL的变长字段,用1~2字节存储其长度信息
行记录头部域之后,紧跟着就是所有非NULL的字段
UTF8字符集的CHAR(N)字段,优先删除末尾空格,尝试用N字节存储,并且再预留N个字节用于后续数据更新,避免产生碎片
B.REDUNDANT
redundant是MySQL 5.0版本之前InnoDB的行记录存储方式。如图:

\ redundant行记录格式的首部是一个字段长度偏移列表,同样是按照列的顺序逆序放置的。若列的长度小于255字节,用1字节表示;若大于255字节,用2字节表示。第二个部分记录头信息(record header)。如下图:

最后的部分就是时间存储的每个列的数据。
REDUNDANT行格式特点:
每个页包含6字节ROWID,用于指向下一个连续的页,并且可用于实现行锁
聚集索引中包含所有字段,并且包含额外的6字节TRX_ID,和7字节ROLL_PTR
如果没显式主键,则使用隐含的6字节ROWID作为主键
行记录中存储指向全部字段的指针,字段长度小于128字节时,该指针占用1字节,否则需要2字节
类似CHAR的定长类型字段,也采用固定宽度存储,并且不删除末尾的空格
类似VARCHAR变长类型字段中NULL不会占用实际存储空间,而CHAR定长类型字段中,NULL则占用相应的字节数
C.行溢出数据
InnoDB存储引擎可以将一条记录中的某些数据存储在正在的数据页之外。一般认为BLOB、LOB这类的大对象类型的存储会把数据存放在数据页面之外。这个理解有点偏差,BLOB等可以不将数据房子溢出页面,而且即使是varchar列数据类型依然有可能被存放为行溢出数据。这个主要取决于实际存放的数据。
D.COMPRESS和DYNAMIC
innodb 1.0.x版本引入了新的文件格式(file format),以前支持的compact和redundant格式称为Antelope文件格式,而新的文件格式称为Barracuda文件格式。其Barracuda包括两种新的行记录格式:Compressd和Dynamic。新的两种记录格式对呀存放在BLOB中的数据采用完全的行溢出的方式,在数据页中只存放20个字节的指针,时间的数据存放在Off Page中。而之前的Compact和Redundant会存放钱768个前缀字节
COMPACT与REDUNDANT的区别
COMPACT相比REDUNDANT约可节省20%左右, COMPRESS相比COMPACT约可节省50%左右,但会导致CPU消耗增加,TPS可能只有原来的10%
类似CHAR的定长类型,也采用固定宽度存储,并且不删除末尾的空格(VARCHAR则会删除空格)
所有辅助索引存储了那些在主键定义中存在,但不在辅助索引中存在字段(提高辅助索引检索效率)
DYNAMIC、COMPRESSED格式中,长字段只存储20字节,其余全部off-page(实际长度40字节以内的,则不会发生off-page,哪怕是text/blob)

未完待续。。。

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template