Skip to content
yihong0618's Blog
Go back

MySQL是怎样跑起来的读书笔记

Updated:

Originally published as GitHub issue #13.

第一份读书笔记每天学到的写在评论里吧


Comments

yihong0618

View comment · 2019-08-01T01:34:28Z

2019.08.01

MySQL大致查询过程

image

储蓄引擎

SHOW ENGINES;
CREATE TABLE 表名(
    建表语句;
) ENGINE = 存储引擎名称;

yihong0618

View comment · 2019-08-02T06:25:31Z

2019.08.02

启动选项和配置文件

mysql> SHOW VARIABLES LIKE 'default_storage_engine';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| default_storage_engine | InnoDB |
+------------------------+--------+
1 row in set (0.01 sec)

mysql> SHOW VARIABLES like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
1 row in set (0.00 sec)

yihong0618

View comment · 2019-08-06T08:50:06Z

2019.08.06

小贴士: 其实准确的说,utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个字符,utf32使用4个字节编码一个字符。更详细的Unicode和其编码方案的知识不是本书的重点,大家上网查查哈~ MySQL中并不区分字符集和编码方案的概念,所以后边唠叨的时候把utf8、utf16、utf32都当作一种字符集对待。

MySQL中的utf8和utf8mb4

我们上边说utf8字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示了。而在MySQL中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以设计MySQL的大叔偷偷的定义了两个概念:

utf8mb3:阉割过的utf8字符集,只使用1~3个字节表示字符。 utf8mb4:正宗的utf8字符集,使用1~4个字节表示字符。

有一点需要大家十分的注意,在MySQL中utf8是utf8mb3的别名,所以之后在MySQL中提到utf8就意味着使用1~3个字节来表示一个字符,如果大家有使用4字节编码一个字符的情况,比如存储一些emoji表情啥的,那请使用utf8mb4。

字符发送过程

image

yihong0618

View comment · 2019-08-07T01:10:18Z

2019.08.07

InnoDB记录存储结构

InnoDB存储引擎需要一条一条的把记录从磁盘上读出来么?不,那样会慢死,InnoDB采取的方式是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16 KB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。 image 这里需要提一下InnoDB表对主键的生成策略:优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个Unique键作为主键,如果表中连Unique键都没有定义的话,则InnoDB会为表默认添加一个名为row_id的隐藏列作为主键。所以我们从上表中可以看出:InnoDB存储引擎会为每条记录都添加 transaction_id 和 roll_pointer 这两个列,但是 row_id 是可选的(在没有自定义主键以及Unique键的情况下才会添加该列)。这些隐藏列的值不用我们操心,InnoDB存储引擎会自己帮我们生成的。

yihong0618

View comment · 2019-08-08T06:39:32Z

2019.08.08

InnoDB数据页结构

image InnoDB为了不同的目的而设计了不同类型的页,我们把用于存放记录的页叫做数据页。

  1. 一个数据页可以被大致划分为7个部分,分别是

File Header,表示页的一些通用信息,占固定的38字节。 Page Header,表示数据页专有的一些信息,占固定的56个字节。 Infimum + Supremum,两个虚拟的伪记录,分别表示页中的最小和最大记录,占固定的26个字节。 User Records:真实存储我们插入的记录的部分,大小不固定。 Free Space:页中尚未使用的部分,大小不确定。 Page Directory:页中的某些记录相对位置,也就是各个槽在页面中的地址偏移量,大小不固定,插入的记录越多,这个部分占用的空间越多。 File Trailer:用于检验页是否完整的部分,占用固定的8个字节。 每个记录的头信息中都有一个next_record属性,从而使页中的所有记录串联成一个单链表。

  1. InnoDB会为把页中的记录划分为若干个组,每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中,所以在一个页中根据主键查找记录是非常快的,分为两步:

通过二分法确定该记录所在的槽。

通过记录的next_record属性遍历该槽所在的组中的各个记录。

  1. 每个数据页的File Header部分都有上一个和下一个页的编号,所以所有的数据页会组成一个双链表。

  2. 为保证从内存中同步到磁盘的页的完整性,在页的首部和尾部都会存储页中数据的校验和和页面最后修改时对应的LSN值,如果首部和尾部的校验和和LSN值校验不成功的话,就说明同步过程出现了问题。

yihong0618

View comment · 2019-08-09T03:35:53Z

2019.08.09

B+树索引

image image

yihong0618

View comment · 2019-08-13T02:21:39Z

2019.08.12

B+树索引的使用

  1. 索引的代价
  1. B+树索引适用的条件
CREATE TABLE person_info(
    id INT NOT NULL auto_increment,
    name VARCHAR(100) NOT NULL,
    birthday DATE NOT NULL,
    phone_number CHAR(11) NOT NULL,
    country varchar(100) NOT NULL,
    PRIMARY KEY (id),
    KEY idx_name_birthday_phone_number (name, birthday, phone_number)
);

image 3. 回表的代价

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

在使用idx_name_birthday_phone_number索引进行查询时大致可以分为这两个步骤:

  1. 如何挑选索引
CREATE TABLE person_info(
    name VARCHAR(100) NOT NULL,
    birthday DATE NOT NULL,
    phone_number CHAR(11) NOT NULL,
    country varchar(100) NOT NULL,
    KEY idx_name_birthday_phone_number (name(10), birthday, phone_number)
);  

yihong0618

View comment · 2019-08-13T02:38:58Z

2019.08.13

MySQL 的数据目录

  1. 如何确定MySQL中的数据目录(数据目录和安装目录是两个概念)
mysql> SHOW VARIABLES LIKE 'datadir';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| datadir       | /usr/local/var/mysql/ |
+---------------+-----------------------+
1 row in set (0.00 sec)
  1. MySQL系统数据库简介

yihong0618

View comment · 2019-08-14T02:13:36Z

2019.08.14

image



Previous Post
普通的一天,不普通的一天
Next Post
Github更持久些