mysql是怎样运行的-从根儿上理解mysql学习笔记(一)

MySQL 是怎样使用的:从零蛋开始学习 MySQL 来来来,你什么都不用会,真正的从零蛋开始系统又轻松地学习MySQL。 阅读详情

说明

本文是《MySQL是怎样运行的-从根儿上理解MySQL》的学习笔记,文中的图全部来自于这本书,强烈建议买一本看看,对MySQL理解会特别深入,非常感谢作者"小孩子4919"。

第四章 InnoDB记录存储结构

InnoDB将数据划分成若干页,以页为作为磁盘和内存之间交互的基本单位。InnoDB中页的大小一般为16KB,也就是说一般情况下,一次最少从磁盘中读取16KB的数据到内存中,一次最少把内存中16KB的内容刷新到磁盘中。

InnoDB行格式

InnoDB行格式分类

  • compack
  • redundant
  • dynamic
  • compressed

指定行格式语法

CREATE TABLE 表名(列的信息) ROW_FORMAT=行格式名称;
ALTER TABLE 表名 ROW_FORMAT=行格式名称;

compack行格式详情

首先创建一个表,行格式设定为compack

CREATE TABLE record_format_demo( 
c1 VARCHAR(10), 
c2 VARCHAR(10) NOT NULL, 
c3 CHAR(10),
c4 VARCHAR(10))
CHARSET=ascii ROW_FORMAT=COMPACT;

这里创建了名为record_format_demo的表,并将行格式指定为"COMPACT",可以看到行格式是"表级别"的,同时设置表的字符集为"ascii",然后向其插入两条记录

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

现在,表中的记录如表4-0

表4-0 record_format_demo表中字段信息
c1c2c3c4
aaaabbbccd
eeeefffNULLNULL

准备工作完成后,接下来可以看COMPACT的行格式了,如图4-1
在这里插入图片描述

图4-1 COMPACT行格式示意图

COMPACT行格式内容

  • 记录的额外信息
    • 变长字段列表
      varchar(M)、varbinary(M)、text、blog这些数据类型的类称为变长字段,变长字段存储多少字节是不固定的,变长字段占用的存储空间分为"真正的数据内容"以及"该数据占用的字节数"两部分。在COMPACT行格式中,所有变长字段的真实数据占用字节数都存放在开头位置,从而形成一个变长字段列表,各变长字段的真实数据占用的字节数按照列的顺序逆序存放。
    • NULL值列表
    • 记录头信息
  • 记录的真实数据
变长字段列表

以上文的record_format_demo记录为例,变长字段内容长度信息如表4-1

表4-1 第一条记录变长字段内容长度
列名存储内容内容长度(10进制表示)内容长度(16进制)
c1aaaa40x04
c2bbb30x03
c4d10x01

注意:由于c3是char(10)类型,在COMPACT行格式下属于定长类型,因此没有列举在表格中。同样第二条记录的变长信息也很容易计算出来,这里给出两条记录存储格式的对比,如图4-3

图4-3 两条记录存储格式对比

再次提醒,变长字段长度列表是根据表中列的顺序逆序存放的,对于第一条记录来说,c1、c2、c3的长度是04 03 01,因此变长字段长度列表为"01 03 04",第二条记录同理。

NULL值列表

一条记录某些列可能为NULL,如果将NULL值存放在记录中会占用较大的存储,因此COMPACT行格式把一条记录中为NULL的列统一管理起来,存储到NULL值列表中。

  • 统计表中哪些列允许为NULL值
    主键列和NOT NULL修饰的列是不允许存储NULL值的。record_format_demo的3个列c1,c3,c4都允许存储NULL值,而c2列使用NOT NULL进行了修饰,因此不允许存储NULL值。

  • 如果表中没有允许为NULL值的列,则NULL值列表也就不存在了,否则将每个允许存储NULL的列对应一个二进制位,二进制位按照列的顺序逆序排列。二进制位值为1代表该列值为NULL,否则代表该列不为NULL。

  • MySQL规定NULL值列表必须用整数个字节的位表示,如果使用的二进制位个数不是整数个字节,则在字节高位补0。
    表record_format_demo的效果如图4-5所示

在这里插入图片描述

图4-5 字节高位补0效果

如果一个表中有9个值允许为NULL列,则这个表的NULL值列表就需要2个字节来存储了。record_format_demo表中两条记录填充NULL值列表后的情况如图4-8所示

图4-8 两条记录在填充了NULL值列表后的示意图
记录头信息

除了变长字段长度列表、NULL值列表外,记录的额外信息中还存储了头信息,头信息由固定长度的5个字节表示,用于描述一些属性,不同的位代表不同的含义,如图4-9所示

图4-9 记录头信息示意图

他们的含义如表4-2

表4-2 记录头信息中各二进制位代表的详细信息
名称大小(位)描述
预留位11未使用
预留位21未使用
deleted_flag1标记该条记录是否被删除
min_rec_flag1B+树每层非叶子节点中最小的目录项记录都会添加该标记
n_owned4一个页面中的记录会被分成若干组,每个组中有一条记录是”带头大哥“,其余记录是”小弟“。”带头大哥“记录的n_owned值代表该组中所有的记录条数,”小弟“记录的n_owned值都为0
heap_no13表示当前记录在页面堆中的相对位置
record_type3表示当前记录的类型,0表示普通记录;1表示B+树非叶子节点的目录项记录;2表示Infimum记录;3表示Supremum记录
next_record16表示下一条记录的相对位置

在这里插入图片描述

图4-10 记录头信息详情
记录真实数据

对于record_format_demo表来说,记录的真是数据除了c1、c2、c3、c4这几个自定义的列外,MySQL还会为每条记录默认添加一些列(隐藏列),具体情况如表4-3

表4-3 MySQL为每个记录默认添加的列
列名是否必须占用空间(字节)描述
db_row_id否6行ID,唯一标识一条记录,用户没有定义主键且表中没有NOT NULL 的UNIQUE键
db_trx_id是6事务ID
db_roll_pointer是7回滚指针

在这里插入图片描述

图4-11 记录真实数据

第五章 InnoDB数据页结构

数据页结构及功能

InnoDB设计了多种不同类型的页,包括存放Change Buffer信息的页,存放INODE信息的页,存放记录的索引页,用户的数据就存放在索引页中,为了方便,这里将索引页称为数据页,图5-1给出了数据页的结构
在这里插入图片描述

图5-1 InnoDB数据页的结构

各结构的大小及作用如表5-1

表5-1 InnoDB数据页结构
名称中文名占用空间大小(字节)描述
File Header文件头部38页的通用信息
Page Header页面头部56数据页专有的信息
Infimum+Supremum页面最小记录和最大记录26两个虚拟记录
User Records用户记录不确定用户存储的记录内容
Free Space空闲空间不确定页中尚未使用的空间
Page Dictionary页目录不确定页中某些记录的相对位置
File Trailer文件尾部8校验页是否完整

记录在页中的存储

用户的记录会存放到User Records部分,但是一开始生成页的时候是没有这部分的,每当插入一条记录时,都会从Free Space申请一个记录大小的空间,然后将记录存进去,这部分内容就划到User Records了,当Free Space空间全部用完后,意味着整个页就用完了,如果此时还想继续插入,就需要申请新的页。

记录头信息

为了方便叙述,这里新创建一个表

CREATE TABLE page_demo(
c1 INT,
c2 INT,
c3 varchar(1000),
PRIMARY KEY (c1))
CHARSET=ascii ROW_FORMAT=COMPACT;

page_demo表主键是c1,行格式设置为COMPACT。这里向表中插入4条记录

INSERT INTO page_demo VALUES(1, 100, 'aaa'),
(2, 200, 'bbbb'),
(3, 300, 'cccc'),
(4, 400, 'dddd');

插入4条记录后User Records存储结构如图5-5所示
在这里插入图片描述

图5-5 记录在页的User Records部分存储结构

其中,有几个关键的属性需要再次强调。

  • heap_no
    用户向表中插入记录本质上都是放到数据页的User Records部分,这些记录一条一条紧密排列着,InnoDB将这样的结构称为堆。为了方便管理堆,InnoDB将一条记录在堆中的相对位置称为heap_no。在页面前边的heap_no相对较小,在页面后边的heap_no相对较大,每申请一条记录的存储空间时,该条记录比物理位置在它前面的那条记录的heap_no值大1。图5-5中heap_no依次是2、3、4、5。InnoDB给每个页加了两条记录,称为伪记录或虚拟记录。一条代表页中最小的记录(写作Infimum记录),另一条代表最大记录(写作Supremum),这两条记录也是堆中的一部分,而且这两条记录是在页申请好空间即插入,比用户记录插入页早很多,因此它们在堆中的heap_no值最小。记录的大小就是比较主键的大小,InnoDB规定,任何用户记录都比Infimum记录大,比Supremum记录小,如图5-8所示。
    在这里插入图片描述
图5-8 记录存放方式
  • record_type(表示当前记录类型)

    • 0(普通记录)
    • 1(B+树非叶子节点的目录项记录)
    • 2(Infimum记录)
    • 3(Supremum记录)
  • next_record
    表示从当前记录的真实数据到下一条记录的真实数据的距离。如果该属性值为正数,则表示下一条记录在当前记录的后面;如果该属性值为负数,则表示下一条记录在当前记录的前面;如果该属性值为0,则表示没有下一条记录(Supremum记录或已被删除的记录)。从图5-8中可以看到,第一条记录的next_record=32,意味着从第一条记录的真实数据地址往后找32字节便是下一条记录的真实数据。再比如第4条记录的next_record=-111,意味着从第4条记录的真实数据地址往前找111字节便是下一条记录的真实数据。为了更形象展现next_record的作<用,用箭头替代next_record的值,如图5-9所示。
    在这里插入图片描述

图5-9 使用箭头替代next_record的值
从图5-9中可以看到记录从小到大形成了一个单向链表。如果从表中删除一条记录,则单向链表也会跟着变化,比如
DELETE FROM page_demo WHERE c1=2;

删除第2条记录后如图5-10所示。

在这里插入图片描述

图5-10 删除第2条记录后的示意图

从图5-10中可以看到删除之后发生了这些变化:

  1. 第2条记录并没有从存储空间移除,而是把它的deleted_flag值置为1;
  2. 第2条记录的next_record值变为0,意味着该记录没有下一条记录了;
  3. 第1条记录的next_record指向了第3条记录;
  4. Supremum记录的n_owned值从5变成了4。

另外,之前一直提到的next_record指向的是记录头信息和真实数据之间的位置。这个位置向做读取就是记录头信息,向右读取就是真实数据。前面还说到,变长字段长度列表、NULL值列表都是逆序存放的,也是为了能够快速定位到需要的信息。
刚刚讨论了删除第2条记录的情形,如果此时再执行插入,会有什么变化呢?

INSERT INTO page_demo VALUES(2, 200, 'bbbb');

重新插入之后的情况如图5-11所示。
在这里插入图片描述

图5-11 再次插入第2条记录后记录的存储情况

从5-11中也可以看到,InnoDB并没有因为新记录的插入而重新分配空间,而是直接复用了原来被删除记录的存储空间。

Page Directory(页目录)

上文介绍了记录在页中是按照主键由小到大顺序串联成一个单向链表,如果想根据主键查询页的记录,比如下面的语句

SELECT * FROM page_demo WHERE c1 = 3;

会怎么查找呢?显然,页中主键是有序的,按照顺序查找不可取,InnoDB为了加速查找的过程,制定了如下的规则:

  1. 将所有正常的记录(包括Infimum和Supremum记录,但不包括已删除的记录)划分成几组。
  2. 每组的最后一条记录(也就是最大的记录)相当于"带头大哥",组内其他记录相当于"小弟"。"带头大哥"记录头信息中的n_owned表示该组内共有几条记录。
  3. 将每组最后一条记录在页面中的地址偏移量单独提取出来,按顺序存储到页尾部的地方,这个地方就是图5-1中的Page Directory。页目录中这些地址偏移量称为槽,每个槽占用2个字节,页目录就是由多个槽组成的。
    在这里插入图片描述
图5-12 page_demo表中记录排列方式

如图5-12所示,一共有2个槽,也就是说这个页中共有两组。槽0地址偏移量是99,也就是说从页面的0字节开始数99字节就是第一组最后一条记录的地址,InnoDB规定第一组只能有一条记录,即Infimum记录。槽1的偏移量是112,从页面的0字节开始数112字节就是第二组最后一条记录的地址,这里第二组最后一条记录时Supremum记录,这条记录中n_owned=5,表明在这组中共有5条记录(包括自己)。99、112这样的地址偏移量不太直观,可以改为指针,如图5-14所示。
在这里插入图片描述

图5-14 使用指针代替槽的偏移量

注意图5-14中所有的指针都是指向记录头信息和记录真实数据信息中间的部分。这里只展示了2个槽,如果插入多条记录,情况又有什么不同呢?

INSERT INTO page_demo VALUES
(5, 500, 'eeee'),
(6, 600, 'ffff'),
(7, 700, 'gggg'),
(8, 800, 'hhhh'),
(9, 900, 'iiii'),
(10, 1000, 'jjjj'),
(11, 1100, 'kkkk'),
(12, 1200, 'llll'),
(13, 1300, 'mmmm'),
(14, 1400, 'nnnn'),
(15, 1500, 'oooo'),
(16, 1600, 'pppp')

c在这里插入图片描述

图5-15插入多条记录后槽的情况

现在page_demo表中共有18条记录,包括16条用户记录和两条默认记录,一共分配了5个槽,槽0永远是只有Infimum记录的那个组。以图5-15为例说明查找主键为11的记录,步骤如下:

  1. 计算中间槽位置,low=0,high=4,mid=(low+high)/2=2,槽2对应的主键为8<11,low=mid+1=3。
  2. mid=(low+high)/2=3,槽3对应主键为11<12,而槽2对应主键为8<11,因此主键为11的这条记录一定在槽3所在的组,则从槽2最后一条记录出发,遍历槽3的记录,直到找到主键为11的那条记录。

每一个数据页都有指向上一个数据页的FIL_PAGE_PREV指针和指向下一个数据页的FIL_PAGE_NEXT指针,这样,数据页就形成了一个双向链表结构,如图5-16。
在这里插入图片描述

图5-16数据页组成的双向链表

第六章 B+树索引

本章主要介绍索引。在介绍之前,先新建一个表:

CREATE TABLE index_demo(
c1 INT,
c2 INT,
c3 CHAR(1),
PRIMARY KEY(c1))
ROW_FORMAT = COMPACT;

为了更直观窥探记录的存储样式,这里省去了上文中介绍的记录头信息,只保留几个简短的信息,并将其竖着排列,如图6-3所示。
在这里插入图片描述

图6-3 竖放记录的效果

在这里插入图片描述

图6-4 记录放到页里面的示意图

这里往表中插入几条记录。

INSERT INTO index_demo VALUES
(1, 4, 'u'),
(3, 9, 'd'),
(5, 3, 'y');

INSERT INTO index_demo VALUES(4, 4, 'a');

这里的插入分成两部分,第一次插入3条记录,第二次插入一条记录。假设每个数据页最多只能存放3条用户记录(实际可以存放的好多记录,这里只是方便叙述)。
在这里插入图片描述

图6-6 为记录分配新页

刚开始3条记录按照主键的顺序插入的10号页中,后来又插入了一条id=4的记录,由于一个页只能存放3条记录,因此第4条记录需要新分配一个页(号码为28),这里也可以看到分配的页并不是连续的。在新分配页之后还要保证后面的页所有的记录都大于前面的页的记录,这里id=4显然不满足这条规则,因此需要调整,调整过程如图6-7所示。
在这里插入图片描述

图6-7 为记录分配新页的过程

图6-7中可以看到,在对页进行增删改操作过程中,必须通过记录移动的操作来始终保证这样的状态:下一个数据页中用户记录的主键值必须大于上一个页中用户记录的主键值。这个过程也叫页分裂。
由于数据页编号可能并不连续,在向index_demo表中插入多条记录后,可能形成多个离散的页,不过它们通过pre和next指针联系起来。如果想从这么多页中根据主键值快速定位某些记录所在的页,就需要给它们编制一个目录,每个目录包括两部分:

  1. 页的用户记录中最小的主键值,用key表示;
  2. 页号,用page_no表示。

这样的结构如图6-9所示。
在这里插入图片描述

图6-9为页编制目录

以页28为例,它对应目录项2,key=5表示页28中最小的主键值是5,也就是(5,3,‘y’)这条记录。如果想要查找主键值为20的记录,在目录项中发现12<20<209,于是确定主键为20的记录可能在page_no为9的页中,然后再到页9中根据槽二分查找到(20,2,‘e’)这条记录。
InnoDB设计者发现目录项的数据结构跟用户记录很像,只不过目录项的前两列是主键和页号而已,于是目录项复用了用户记录页,这里称表示目录项的记录成为目录项记录。那么,InnoDB是怎么区分一条记录是普通的用户记录还是目录项记录呢?record_type=1就表示目录项记录(0:普通的用户记录;2:Infimum记录;3:Supremum记录)。
于是,将前面的目录项放到数据页中,结果如图6-10所示。
在这里插入图片描述

图6-10将目录项放到数据页中的效果

从图6-10中可以看到,InnoDB新分配了一个page_no=30的页存储目录项记录,目录项记录和用户记录不同点在于:

  1. 目录项记录的record_type=1,用户记录的record_type=0;
  2. 目录项记录只有主键值和page_no两列,而普通用户记录是用户自定义的,可能包含很多列,另外还有InnoDB自己添加的隐藏列;
  3. 记录的头信息中有个名为min_rec_flag属性 ,只有目录项记录的min_rec_flag值才可能为1,普通用户记录的min_rec_flag值均为0;

一个页的大小为16KB,随着目录项记录插入越来越多,总有一天页的空间被用完,此时就需要申请一个新的页,如图6-12所示。
在这里插入图片描述

图6-12,生成存储更高级目录项纪录的数据页

图6-12的数据结构,就是B+树。无论是目录项记录页还是用户记录页,它们都是B+树的一个节点。真正的用户记录都存放在B+树的叶子节点上,B+树最上边的节点称为根节点。从图6-12也可以看到,一个B+树可以分为好多层。如果B+树有4层,可以存放100亿的数据,因此一般的B+树都不超过4层。所以根据主键查找时最多搜寻4层,比不建索引性能提升太多。

索引的分类

  • 聚簇索引
    上文中介绍的B+树本身就是一个目录,或者说就是一个索引,它的节点是按照主键从小到大排序好的结构,非叶子节点存储目录信息,叶子节点存储完整的用户记录信息,将具有完整信息并根据主键从小到大排序好的B+树称为聚簇索引。在InnoDB中,聚簇索引就是数据的存储方式,也就是所谓的"索引即数据,数据即索引"。

  • 二级索引
    上文介绍的聚簇索引只能在搜索条件是主键值时才能发挥作用,如果想以别的列作为搜索条件,该如何处理呢?仿照聚簇索引,这里也可以对其他列根据排序规则建立一个B+树索引,如图6-14就是在c2列上建立索引。
    在这里插入图片描述

    图6-14在c2列上建立索引的情况
    在c2列上建立的二级索引有以下几个特点
    • 页内的所有记录都是按照c2从小到大排列成单向链表,页内被划分为若干组,每组c2列最大的记录在页的偏移量会当做槽放到页目录中;
    • 各个存放用户记录的页也是根据c2列大小排列成一个双向链表;
    • 存放目录项记录的页分为不同层级,同一层级的页也是根据c2列大小组成双向链表;
    • B+树种叶子节点存储的并不是完整的用户记录,而是c2列+主键这两个列的值;
    • 目录项记录不再是主键+页号 的搭配,而是c2列+主键+页号的搭配;

    假设这里需要查找c2=4的记录,就可以使用刚刚建立的索引,不过c2=4的记录可能有多条,因此只需要定位到B+树种叶子节点第一条满足c2=4的那条记录,然后沿着记录一直 向后扫描到不符合条件的记录。搜索完成后取出所有的主键id,再使用主键id在聚簇索引中查找完整的记录,根据主键id在聚簇索引中查找完整记录的过程称为回表。
    这里为什么需要回表呢?因为二级索引只存储了c2列和主键id的值,并没有存储其他列,因此查询其他列需要进行回表操作。为什么不在c2列的索引上也存储完整的用户记录呢?这样做太占空间了,相当于每建一个索引都需要将用户记录完整复制一遍。

  • 联合索引
    有了上文聚簇索引和二级索引的介绍,联合索引就比较好理解了,联合索引是对多个列建立索引,比如对c2、c3两列建立联合索引,建立规则是各个记录首先按照c2列排序,如果c2列相同,再按照c3列排序。需要注意的是联合索引是一个B+树,这里要和在c2、c3两个列建立二级索引区分开。

总结

  1. 每个索引对应一棵B+树,B+树分为好多层,最下边一层是叶子节点,其余是内节点。所有用户记录存储在叶子节点上,所有目录项记录都存储在内节点。
  2. InnoDB会自动为主键建立聚簇索引(如果没有显示指定主键或没有生命不允许存储NULL的UNIQUE建,它会自动添加主键),聚簇索引的叶子节点包含完整的用户记录。
  3. 可以为感兴趣的列建立二级索引,二级索引的叶子节点包含用户记录索引列和主键组成。如果想通过二级索引查找完整的用户记录,需要执行回表操作。
  4. 可以为多个列建立联合索引,比如对c2列和c3列建立联合索引idx_c2_c3(c2, c3),那么该索引中页面记录按照 c2列的值进行排序,如果c2值相同,按照c3进行排序。
MySQL是怎样运行的(仅限学习使用) 立即下载

相关推荐

我们都是小青蛙MYSQL系列

MYSQL的一些经验

从小孩子(初学者)的角度,从用户的角度探究MySQL是怎样运行的,把MySQL讲明白了

孩子从小就有一个疑惑:为什么我在接触一门新课程的时候总是觉得它很高大上,并且学的过程也比较痛苦,但是当我真正学会它的时候,又会觉得这玩意儿也就那样,没什么了不起的,但是为啥学的时候就不能很轻松呢?有时候我们走了很久,却忘记自己为什么出发,类似的,大人长大后就忘记了自己作为小孩时的样子,一个满腹经纶的技术专家对于初学者所面临的问题往往是无法切身体会的,所以这份手册以小孩子(初学者)的角度,从用户的角度出发去解决同志们在学习过程中面临的痛点MySQL应该是国内互联网公司使用最为广泛的数据库。

老男孩的架构路 563

MySQL 是怎样运行的:从根儿上理解 MySQL(下).pdf

MySQL 是怎样运行的:从根儿上理解 MySQL(下).pdf

mysql学习-Innodb行格式compact行记录解析

一、Innodb四种行格式 COMPACT 紧凑型行格式 REDUNDANT 字段长度偏移类型 DYNAMIC 动态行格式 COMPRESSED 压缩行格式 二、COMPACT行格式示意图 三、变长字段长度列表 1.目的 针对于变长字段列入VARCHAR,VARBINARY,TEXT,BLOB等变长字段类型,由于存储的字段长度不固定,如果不记录该字段的真实长度,那么就无法计算出这一行的准确长度,那么就无法进行行与行的切分。 所以变长字段会占用两部分空间,第一部分是数据的长度,另一部分是该数据所占用的字

欢谷悠扬 2579

MySQL 是怎样运行的:从根儿上理解 MySQL(上).pdf

MySQL 是怎样运行的:从根儿上理解 MySQL(上).pdf

元数据及数据仓库相关概念

文章目录元数据(metadata)的概念Data about Data定义技术元数据业务元数据总结数据仓库ODS简单的理解为 Operational Data Store, 运营数据仓储 数据整合层(也叫做数据缓冲层)EDW简单理解为 Enterprise Data Warehouse, 企业数据仓库ODS与EDW之间的差异使用角色数据来源数据获取性能和及时性数据架构数据共享能力数据系统提供应用数...

frone的专栏 3137

MySQL 是怎样运行的:从根儿上理解 MySQL

MySQL 是怎样运行的:从根儿上理解 MySQL小孩子 著12 小时 · 25 小节从根儿上理解 MySQL,让 MySQL 不再是一个黑盒小册内容小册介绍MySQL...

codehole_的博客 9668

银河麒麟v10(x86_64)升级openssh实操成功

本文详细介绍了在银河麒麟V10系统上将OpenSSH从8.2p1升级至9.9p2版本的全过程。主要内容包括:系统环境确认、安装telnet备用连接、备份配置、卸载旧版本、安装新版本、服务配置与验证等关键步骤。特别强调了安全注意事项,如必须安装telnet作为备用连接、重要配置备份等。升级后提供了安全加固建议,包括修改SSH端口、禁用root登录等。文章还包含详细的故障排查方法和恢复方案,确保升级过程安全可靠。通过本教程,用户可以顺利完成OpenSSH版本升级,提升系统安全性。

淘淘小窝 1088

mysql是怎样运行的 从根儿 百度云_MySQL 是怎样运行的:从根儿上理解 MySQL|完结|百度云下载...

-代码开始-/MySQL 是怎样运行的:从根儿上理解 MySQL [13.8M]┣━━[天下无鱼][shikey.com]0万里长征第一步(非常重要) —— 如何愉快的阅读本小册(01).md [9.8K]┣━━[天下无鱼][shikey.com]0万里长征第一步(非常重要) —— 如何愉快的阅读本小册(02).pdf [617.3K]┣━━[天下无鱼][shikey.com]10条条大路通罗马 ...

weixin_35203997的博客 7326

跟着Cell学单细胞转录组分析(五):单细胞转录组marker基因鉴定及细胞群注释

书接上回(跟着Cell学单细胞转录组分析(四):单细胞转录组测序UMAP降维聚类)。完成数据降维和细胞聚类后,最主要的环节和工作就是确定各个细胞群,明确是什么类型的细胞,正群的细胞定群很关键,涉及到整个研究,所以这一步宁愿多费时间,也不要出错。当然,这也不是一蹴而就的,需要反复的确认。 要确定各个群是什么细胞,首先需要了解细胞群的marker基因,因为不同类型的细胞突出 表达的基因也是不同的。这里使用FindAllMarkers鉴定各个细胞群的高表达基因。 DefaultAssay(scedata)

qq_42090739的博客 1万+

IWR6843ISK+DCA1000EVM 本人遇到的所有报错和解决方案

本文详解了初次使用DCA1000EVM和mmave studio遇到的一系列的问题以及解决方法

2301_77883976的博客 3298

MySQL 是怎样运行的:从根儿上理解 MySQL(上)

MySQL 是怎样运行的:从根儿上理解 MySQL(上) 【下载地址】MySQL是怎样运行的从根儿上理解MySQL上 《MySQL 是怎样运行的:从根儿上理解 MySQL(上)》是一份深入浅出的教程,全面剖析了MySQL数据库的运行原理。本教程以通俗易懂的语言,帮助读者从源头理解MySQL,为之后的学习和实践打下坚实基础...

gitblog_06708的博客 479

IPMItool 控制风扇转速

然后手动设置风扇,最后一位0x1e为设置30%的转速(16进制)。最后4位 0x0f 表示15%,0x0a,表示10%,不建议小于10%,因为10%已经很静音了 如果再小怕不能控温,烧毁硬件。首先停止服务器的自动风扇控制,最后一位0x00表示停止自动风扇控制,0x01为开启自动风扇控制。首先开启主板上的ipmi 设置好 用户名密码。此过程可以在网上搜索,有很多的资料可以参考。解压只有在目录里面有ipmltool。下面是一些常用的修改温度命令。

m0_37970303的博客 5058

MySQL 是怎样运行的:从根儿上理解 MySQL(下)

MySQL 是怎样运行的:从根儿上理解 MySQL(下) 【下载地址】MySQL是怎样运行的从根儿上理解MySQL下 《MySQL 是怎样运行的:从根儿上理解 MySQL(下)》是一份深入浅出的学习资料,帮助读者全面理解 MySQL 数据库的内部工作原理。内容涵盖存储引擎、索引原理与优化、SQL 语句执行过程、事务与锁的...

gitblog_06749的博客 472

11.3 海岛微电网与工业园区的构网应用

海岛微电网与工业园区配电网是构网技术下沉应用的两大典型场景。海岛微电网以构网型储能为核心,解决孤岛系统稳定性问题,需具备黑启动、多能源协调和故障穿越能力;工业园区则侧重电能质量治理、并离网无缝切换和经济优化运行。两类场景均需解决多机并联稳定性、故障特性适配和分层协同控制等关键技术。构网型变流器的电压源构建能力、自适应控制策略及飞轮储能等特殊应用,为构建高可靠性、高经济性的分布式能源系统提供了创新解决方案。

技术工作者 1083

思科模拟器CIsco Packet Tracer利用三层交换机实现VLAN间路由

版权声明:如果对大家有帮助,大家可以自行转载的。 1.技术原理: 三层交换机具备网络层的功能,实现 VLAN 相互访问的原理是:利用三层交换机的路由功能,通过识别数据包的 IP 地址,查找路由表进行选路转发,三层交换机利用直连路由可以实现不同 VLAN 之间的相互访问。三层交换机给接口配置 IP 地址。采用 SVI(交换虚拟接口)的方式实现 VLAN 间互连。SVI 是指为交换机中的VLAN 创建...

qq_37992321的博客 1万+

MySQL是怎样运行的:从根儿上理解MySQL | 锁

文章目录前言:本博文是对MySQL是怎样运行的:从根儿上理解MySQL这本书的归纳和总结第25章 工作面试老大难-锁1.解决并发事务带来问题的两种基本方式1.1 并发事务访问相同记录的情况的三种情况 前言:本博文是对MySQL是怎样运行的:从根儿上理解MySQL这本书的归纳和总结 第25章 工作面试老大难-锁 1.解决并发事务带来问题的两种基本方式 1.1 并发事务访问相同记录的情况的三种情况 ...

光看不点赞的博客 5969

基于QT与STM32的电力参数采集系统(华为云IOT)(211)

本项目构建一款集多功能于一体的电力参数采集系统,该系统以高性能、低功耗的STM32F103RCT6微控制器为核心,集成多种传感器与通信模块,实现对电力设施如电压、电流、功率、电能及环境温度等关键参数的实时精确采集,并通过GPS模块获取设备地理位置信息,满足了电力设备状态全面监控的需求。

2901

【亲测免费】 《MySQL是怎样运行的:从根儿上理解MySQL》PDF下载

《MySQL是怎样运行的:从根儿上理解MySQL》PDF下载 【下载地址】MySQL是怎样运行的从根儿上理解MySQLPDF下载 《MySQL是怎样运行的:从根儿上理解MySQL》是一本深入解析MySQL数据库内部机制的书籍,适合希望从底层原理到实际应用全面掌握MySQL的读者。本书详细介绍了MySQL的架构设计、存储引...

gitblog_06714的博客 1388

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

终于有一本书能把MySQL讲明白了,豆瓣评分9.4,而且还很有趣

三四十万字,几百篇插图,辞了工作,没有收入,专心写作。成就了一本《MySQL是怎样运行的:从根儿上理解 MySQL》。 MySQL应该是国内互联网公司使用最为广泛的数据库。很多朋友在研究MySQL、学习MySQL的过程中,或多或少都会遇到这样一些困难: 网上MySQL的资料不系统,多而杂; 有的书偏应用,比较浅,底层原理没有讲; 有的书语言比较晦涩,比较难懂。 如果你真的遇到这样些困难,推荐大家看下这本《MySQL是怎样运行的:从根儿上理解 MySQL》 读这本书一定要逐章学习本书,千万.

人邮异步社区 8255

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

转:MySQL 是怎样运行的:从根儿上理解 MySQL

转:MySQL 是怎样运行的:从根儿上理解 MySQL

baidu_37307156的博客 9181

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MySQL是怎样运行的从根儿上理解MySQL下:深入掌握数据库核心奥秘

MySQL是怎样运行的从根儿上理解MySQL下:深入掌握数据库核心奥秘 【下载地址】MySQL是怎样运行的从根儿上理解MySQL下 《MySQL 是怎样运行的:从根儿上理解 MySQL(下)》是一份深入浅出的学习资料,帮助读者全面理解 MySQL 数据库的内部工作原理。内容涵盖存储引擎、索引原理与优化、SQL 语句执行过...

gitblog_06713的博客 433
上一篇: libevent深入浅出
下一篇: 计算机组成原理-指令是如何被执行的
spencersong
博客等级 码龄9年 11粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值