引言

我们都知道,mysql中的索引,事务,锁等都是作为开发人员要重点掌握的知识面,但要想掌握理解好这些知识却并非易事。

其中原因之一就是这些概念都过于抽象,事实上如果都不懂mysql数据是以一种怎样结构存储的,就直接去学习索引等模块,如此理解起来自然是事倍功半的。

因此本文的目的有两点:

  • 揭露数据存储的格式
  • 说明Mysql是如何读取数据

在正文开始之前要先明确一点,Mysql有很多存储引擎,不同的存储引擎对于数据的存放格式是不一样的,目前Mysql的存储引擎默认是InnoDB,因此本文主要以InnoDB的角度去讲解。

行格式

我们经常会说往表中插入一条数据,实际上InnoDB数据存储的基本单位其实就是一条数据。这行数据在磁盘上存储的格式就叫做行格式。

InnoDB设计了4种行格式,分别是Compact、Redundant、Dynamic和Compressed行格式,接下来我们会重点讲解Compact,同时它也是最常用的行格式。

COMPACT行格式

直接先看一张图:

看图说话,Compact行格式可以分为两大块:

  • 额外信息
  • 真实数据

所谓真实数据自然就是我们要存放的值,而额外信息存储的是对这行记录的一些描述。

其中额外信息包括变长字段长度列表,NULL值列表,记录头信息。

变长字段长度列表

在Mysql有一些数据类型,比如VARCHAR(M)、TEXT等,它们是属于支持变长的数据类型,实际使用的字节数是不固定的。所以Mysql需要把这些类型的列实际使用了多少字节数给记录下来,记录的地方就是在变长字段长度列表

在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放。

举个例子,我们创建个表

CREATE TABLE record_format_demo (
-> c1 VARCHAR(10),
-> c2 VARCHAR(10) NOT NULL,
-> c3 CHAR(10),
-> c4 VARCHAR(10)
-> )

可以看到c1,c2,c4列都是变长的,此时我们插入一条数据

INSERT INTO record_format_demo(c1, c2, c3, c4) VALUES('aaaa', 'bbb', 'cc', 'd')

我们假定内容占用的字节为

列名 存储内容 占用字节(十六进制表示)
c1 'aaaa' 0x04
c2 'bbb' 0x03
c4 'd' 0x01

所以这条记录的存储格式就为

可以看到变长字段长度列表是逆序(c4->c2->c1)排放的。

因此要计算1个变长字段到底占用了多少空间要计算两部分:

  • 真实数据占用的空间
  • 记录真实数据占用空间所使用的字节数

以列C1为例:

占用字节数='aaaa'(4字节)+ '0x04'(1字节)

NULL值列表

我们知道表中的某些列可能存储NULL值,如果把这些NULL值都放到记录的真实数据中存储会很占地方,所以Compact行格式把这些值为NULL的列统一管理起来,存储到NULL值列表中。

每个允许存储NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列,,二进制位表示的意义如下:

  • 二进制位的值为1时,代表该列的值为NULL。
  • 二进制位的值为0时,代表该列的值不为NULL。

我们在来插入一条记录

INSERT INTO record_format_demo(c1, c2, c3, c4) VALUES('aaaa', 'bbb', null, null)

因此这条记录的null值列表就是:

行格式就是:

可以看到二进制110就是十进制的6.

记录头信息

记录头信息,它是由固定的5个字节组成。5个字节也就是40个二进制位,不同的位代表不同的意思。本文不会细讲,在后续的文章中有涉及再说讲解。

真实数据

真实数据除了c1、c2、c3、c4这几个我们自己定义的列的数据以外,其实MySQL会为每个记录默认的添加一些列(也称为隐藏列),具体的列如下:

transaction_id和roll_pointer的作用将会在后面提及。

而row_id这个列只有在表没有自定义主键并且Unique键的情况下才会添加,作为表的主键。

以上就是InnoDb存储数据的行格式,下一篇文章将会介绍页的概念。

Mysql综述(1)数据是如何读存的的更多相关文章

  1. Mysql综述--数据是如何读存的?(2)

    页的结构 页是一种InnoDB管理存储空间的基本单位,它一般大小在16kb左右.实际上存在着许多不同类型的页,我们这次主要介绍的页是用来存储数据的,也叫做索引页. 接下来看看索引页的结构图: 比较重要 ...

  2. CentOS6 更改Mysql数据库的数据存放位置

    mysql使用yum安装时,默认的数据是存储在/var/lib/mysql下.一般情况下,为了数据的安全性,建议将mysql数据库的数据文件存储在系统的第二块磁盘上的目录下可以按照以下步骤进行操作: ...

  3. php查询mysql返回大量数据结果集导致内存溢出的解决方法

    web开发中如果遇到php查询mysql返回大量数据导致内存溢出.或者内存不够用的情况那就需要看下MySQL C API的关联,那么究竟是什么导致php查询mysql返回大量数据时内存不够用情况? 答 ...

  4. 大数据学习day33----spark13-----1.两种方式管理偏移量并将偏移量写入redis 2. MySQL事务的测试 3.利用MySQL事务实现数据统计的ExactlyOnce(sql语句中出现相同key时如何进行累加(此处时出现相同的单词))4 将数据写入kafka

    1.两种方式管理偏移量并将偏移量写入redis (1)第一种:rdd的形式 一般是使用这种直连的方式,但其缺点是没法调用一些更加高级的api,如窗口操作.如果想更加精确的控制偏移量,就使用这种方式 代 ...

  5. [转] MySql 优化 大数据优化

    一.我们可以且应该优化什么? 硬件 操作系统/软件库 SQL服务器(设置和查询) 应用编程接口(API) 应用程序 ------------------------------------------ ...

  6. 快速的mysql导入导出数据(load data和outfile)

    1.load data: ***实际应用:把日志生成的xls文件load到MySQL中: mysql_cmd = "iconv -c -f utf-8 -t gbk ./data/al_ve ...

  7. redis作为mysql的缓存服务器(读写分离,通过mysql触发器实现数据同步)

    一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录 ...

  8. Ubuntu系统下MySQL读取文件数据ERROR解决

    博文链接:http://haoyuanliu.github.io/2016/04/29/mysql/ 对,我是来骗访问量的!O(∩_∩)O~~ 在使用MySQL进行文件数据读取的时候,在终端敲入命令行 ...

  9. 用python批量向数据库(MySQL)中导入数据

    用python批量向数据库(MySQL)中导入数据 现有数十万条数据,如下的经过打乱处理过的数据进行导入 数据库内部的表格的数据格式如下与下面的表格结构相同 Current database: pyt ...

随机推荐

  1. .Net基础篇_学习笔记_第五天_流程控制while循环003

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. Vector和Arrarlist的异同;Hashtanle和HashMap的异同

    Vector和ArrayList的异同 实现原理相同,功能相同,可以互用 主要区别: Vector线程安全,ArrayList重速度,轻安全,线程非安全. 长度需要增长时,Vector默认增长一倍,A ...

  3. java对象排序(Comparable)详细实例

    对象实现Comparable接口 public class Field implements Comparable<Field>{ private String name; private ...

  4. 巨杉Tech | Hbase迁移至SequoiaDB 实战

    背景 在传统银行 IT 架构中,联机交易与统计分析系统往往采用不同的技术与物理设备,通过定期执行的 ETL 将联机交易数据向分析系统中迁移.而作为数据服务资源池,同一份数据可能被不同类型的微服务共享访 ...

  5. 去掉first li 的list图标

    ul中,第一个 li 前的小图标,默认情况下为小圆点,在这种情况下,给 first li 设置 list-style-type: none;可以成功去除前面的小圆点的. 当给 li 设置了 list ...

  6. Django跳转到不同的页面的方法和实例–使用Django建立你的第一个网站

    1 前记 这次记录的这些东西,主要是自己在搭建个人网站的时候遇到的一些问题记录,不算严格意义上的教程和使用说明.按照目前自己的web水平,去写这方面的教程无疑是误人子弟.因为自己虽然做程序员很多年,但 ...

  7. .NET Conf 2019 大会上发布.NET Core 3.0

    北京时间今天凌晨如期在.NET Conf 上发布.NET Core 3.0,Keynotes 由Scott Hunter 主演,主要围绕.NET Core 3.0的新特性和社区展开. 多功能性是.Ne ...

  8. python excel to mysql

    import sys import xlrd import pymysql import math import json from collections import OrderedDict # ...

  9. Hibernate4之JPA规范配置详解

    @Table Table用来定义entity主表的name,catalog,schema等属性. 属性说明: name:表名 catalog:对应关系数据库中的catalog schema:对应关系数 ...

  10. APP稳定性测试

    APP稳定性测试-monkey测试     第一篇-App稳定性测试-Monkey(基本操作) 准备工作 1.首先下载好adb工具 2.使用数据线连接电脑,打开usb调试 3.使用win+R打开运行, ...