MySQL: 22 写入数据库的一行数据,在磁盘上是怎么储存的

Posted 鮀城小帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL: 22 写入数据库的一行数据,在磁盘上是怎么储存的相关的知识,希望对你有一定的参考价值。

1. 为什么不能直接更新磁盘上的数据

因为来一个请求就直接对磁盘文件进行随机读写,然后更新磁盘文件里的数据,虽然技术上是可以做到的,但是那必然导致执行请求的性能极差。

因为磁盘随机读写的性能是最差的,所以直接更新磁盘文件,必然导致数据库完全无法抗下任何稍微高并发一点的场景。

所以mysql才设计了如此复杂的一套机制,通过内存里更新数据,然后写redo log以及事务提交,后台线程不定时刷新内存里的数据到磁盘文件里。

通过这种方式保证,每个更新请求,尽量就是更新内存,然后顺序写日志文件。

而更新内存的性能是极高的,然后顺序写磁盘上的日志文件的性能也是比较高的,因为顺序写磁盘文件,它的性能要远高于随机读写磁盘文件。

也正是通过这套机制,才能让MySQL数据库在较高配置的机器上,每秒可以抗下几千的读写请求。

2.MySQL中引入数据页概念的原因

当我们要执行update之类的SQL语句的时候,必然涉及到对数据的更新操作,而此时对数据的更新不能直接就去更新磁盘文件,而是要先把磁盘上的一些数据加载到内存里来,然后对内存里的数据进行更新,同时写redo log到磁盘上去。

 而不是每次都把磁盘里的一条数据加载到内存里去进行更新。

因为每次都是一条数据一条数据的加载到内存里去更新,效率是很低的。也正是因为如此,所以innodb存储引擎在这里引入了一个数据页的概念,也就是把数据组织成一页一页的概念,每一页有16kb,然后每次加载磁盘的数据到内里的时候,是至少加载一页数据进去,甚至是多页数据进去。

案例:假设有一次要更新一条 id=1 的数据: update xxx set xxx=xxx where id=1.

那么此时他会把id=1这条数据所在的一页数据都加载到内存里去,这一页数据里,可能还包含了id=2,id=3等其他数据。

然后更新完id=1的数据之后,接着更新id=2的数据,此时就不用再次读取磁盘里的数据量,因为 id=2本身就跟 id=1在一页里,之前这一页数据就加载到内存里去了,可以直接更新内存里的数据页中的 id=2 这条数据。

3.涉及MySQL物理数据存储格式:一行数据在磁盘上是如何存储的?

对于数据页中的每一行数据他们在磁盘上的存储,涉及到一个概念,就是行格式。可以对一个表指定它的行存储的格式是什么样的,比如有一个 COMPACT格式。

CREATE TABLE table_name(columns)ROW_FORMAT=COMPACT ALTER TABLE table_name ROW_FORMAT=COMPACT

在建表的时候,就制定一个行存储的格式,也可以后续修改行存储的格式。这里制定了一个COMPACT行存储格式,对应的每一行数据实际存储的时候,大概格式类似下面这样:

变长字段的长度列表,null值列表,数据头,column01的值,column02的值,column0n的值

对于每一行数据,它存储的时候都会有一些头字段对这行数据进行一定的描述,然后再放上它这一行数据每一列的具体的值,这就是所谓的行格式。

以上是关于MySQL: 22 写入数据库的一行数据,在磁盘上是怎么储存的的主要内容,如果未能解决你的问题,请参考以下文章

MySQL:26 每一行的实际数据在磁盘上是如何存储的?

一文讲清,MySQL数据库一行数据在磁盘上是怎么存储的?

Mysql中每一行的实际数据在磁盘上是如何存储的?

Mysql中每一行的实际数据在磁盘上是如何存储的?

MySQL:24 一行数据中的多个NULL字段值在磁盘上怎么存储

如何优化mysql写入速