MySQL之从一条记录说起 【InnoDB 记录结构上篇】

news2025/1/17 3:03:25

前言

本文章收录在MySQL性能优化+原理+实战专栏,点击此处查看开篇介绍。

本文摘录自 ▪ 小孩子4919《MySQL是怎样运行的:从根儿上理解MySQL》

在这里插入图片描述到现在为⽌,MySQL对于我们来说还是⼀个⿊盒,我们只负责使⽤客户端发送请求并等待服务器返回结果,表中的数据到底存到了哪⾥?以什么格式存放的?MySQL是以什么⽅式来访问的这些数据?这些问题我们统统不知道?
之前的文章我们大致知道MySQL服务器上负责对表中数据的读取和写⼊⼯作的部分是存储引擎,⽽服务器⼜⽀持不同类型的存储引擎,⽐如InnoDB、MyISAM、Memory等,不同的存储引擎⼀般是由不同的⼈为实现不同的特性⽽开发的,真实数据在不同存储引擎中存放的格式⼀般是不同的,甚⾄有的存储引擎⽐如Memory都不⽤磁盘来存储数据,也就是说关闭服务器后表中的数据就消失了。由于InnoDB是MySQL默认的存储引擎,也是我们最常⽤到的存储引擎,所以本文带你了解InnoDB存储结构。当我们熟悉了⼀个存储引擎的数据存储结构之后,其他的存储引擎都是依葫芦画瓢。

目录

  • 一、InnoDB⻚简介
  • 二、InnoDB⾏格式
  • 三、指定行格式的语法
  • 四、Compact⾏格式
    • 4.1 记录的额外信息
      • 4.1.1 变⻓字段⻓度列表
      • 4.1.2 NULL值列表
      • 4.1.3 记录头信息
    • 4.2 记录的真实数据
    • 4.3 CHAR(M)列的存储格式

一、InnoDB⻚简介

InnoDB是⼀个将表中的数据存储到磁盘上的存储引擎,所以即使关机后重启我们的数据还是存在的。⽽真正处理数据的过程是发⽣在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写⼊或修改请求的话,还需要把内存中的内容刷新到磁盘上。⽽我们知道读写磁盘的速度⾮常慢,和内存读写差了⼏个数量级,所以当我们想从表中获取某些记录时,InnoDB采取的⽅式是:将数据划分为若⼲个⻚,以⻚作为磁盘和内存之间交互的基本单位,InnoDB中⻚的⼤⼩⼀般为 16K,也就是在⼀般情况下,⼀次最少从磁盘中读取16KB的内容到内存中,⼀次最少把内存中的16KB内容刷新到磁盘中。

二、InnoDB⾏格式

我们平时是以记录为单位来向表中插⼊数据的,这些记录在磁盘上的存放⽅式也被称为⾏格式或者记录格式。设计InnoDB存储引擎到现在为⽌设计了4种不同类型的⾏格式,分别是:

  • Compact
  • Redundant
  • Dynamic
  • Compressed

随着时间的推移,他们可能会设计出更多的⾏格式,但是不管怎么变,在原理上⼤体都是差不多

三、指定行格式的语法

create table表名 (列的信息) row_format=⾏格式名称
or
alter table 表名 row_format=⾏格式名称
比如我们在testdb库中创建一张学习的表demo,可以这样指定它的行格式

mysql> use testdb;
Database changed
mysql> create table demo1( c1 varchar(10), c2 varchar(10) not null, c3 char(10), c4 varchar(10), c5 varchar(1024)) charset=ascii row_format=compact;
Query OK, 0 rows affected (0.01 sec)

可以看到我们刚刚创建的这个表的⾏格式就是compact,我们还指定了这个表的字符集为ascii,因为ascii字符集只包括空格、标点符号、数字、⼤⼩写字⺟和⼀些不可⻅字符。我们现在向这个表中插⼊两条记录

mysql> insert into demo1 values('aaaaa','bbbb','ccc','dd','e');
Query OK, 1 row affected (0.00 sec)

mysql> insert into demo1 values('eeeee','ffff',null,null,'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz');
Query OK, 1 row affected (0.01 sec)

现在表中的记录就是这个样⼦的

mysql> select * from demo1;
+-------+------+------+------+------------------------------------------------------------------------------------------------------------------------------------+
| c1    | c2   | c3   | c4   | c5                                                                                                                                 |
+-------+------+------+------+------------------------------------------------------------------------------------------------------------------------------------+
| aaaaa | bbbb | ccc  | dd   | e                                                                                                                                  |
| eeeee | ffff | NULL | NULL | abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz |
+-------+------+------+------+------------------------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

演示表的内容也填充好了,现在我们就来看看各个⾏格式下的存储⽅式到底有啥不同吧

四、Compact⾏格式

在这里插入图片描述
如图,⼀条完整的记录其实可以被分为记录的额外信息记录的真实数据两⼤部分,下边我们详细看⼀下这两部分的组成

4.1 记录的额外信息

这部分信息是服务器为了描述这条记录添加的⼀些信息,这些额外信息分为3类,分别是变⻓字段⻓度列表NULL值列表记录头信息,我们分别看⼀下

4.1.1 变⻓字段⻓度列表

我们知道MySQL⽀持⼀些变⻓的数据类型,⽐如varchar(M)varbinary(M)各种TEXT类型各种BLOB类型,我们也可以把拥有这些数据类型的列称为变⻓字段,变⻓字段中存储多少字节的数据是不固定的,所以我们在存储真实数据的时候需要顺便把这些数据占⽤的字节数也存起来,这样才不⾄于把MySQL服务器搞懵,所以这些变⻓字段占⽤的存储空间分为两部分:

  • 真正的数据内容
  • 占⽤的字节数

在Compact⾏格式中,把所有变⻓字段的真实数据占⽤的字节⻓度都存放在记录的开头部位,从⽽形成⼀个变⻓字段⻓度列表,各变⻓字段数据占⽤的字节数按照列的顺序逆序存放

我们拿demo1表中的第⼀条记录来举个例⼦。因为demo1表的、c1c2c4c5列都是变⻓的数据类型,所以这四个列的值的字节⻓度都需要保存在记录开头处,我们来看⼀下第⼀条记录各变⻓字段内容字节的⻓度:

列名存储内容字节长度(十进制)内容长度(十六进制)
c1‘aaaaa’50x05
c2‘bbbb’40x04
c4‘dd’20x02
c5‘e’10x01

⼜因为这些⻓度值需要按照列的逆序存放,所以最后变⻓字段⻓度列表的字节串⽤⼗六进制表示,效果就是:01 02 04 05,把这个字节串组成的变⻓字段⻓度列表填⼊上边的示意图中的效果如下:

在这里插入图片描述
我们也可以查看底层存储文件:demo1.ibd,用16进制编辑器打开,我这里使用的是Notepad++和他的HEX-Editor插件。可以找到如下的数据域(可能会有其中 mysql 生成的行数据不一样,但是我们创建的行数据内容应该是一样的,而且数据长度应该是一摸一样的,可以搜索01 02 04 05字符,找到这些数据):

在这里插入图片描述
由于第⼀⾏内容占⽤的字节数⽐较⼩,⽤1个字节就可以表示,但是如果变⻓列的内容占⽤的字节数⽐较多,可能就需要⽤2个字节来表示。具体⽤1个还是2个字节来表示真实数据占⽤的数,InnoDB有它的⼀套规则,这里我们⾸先声明⼀下W、M和L的意思:

假设某个字符集中表示⼀个字符最多需要使⽤的字节数为W

也就是使⽤show charset语句的结果中的Maxlen列,⽐⽅说utf8mb4字符集中W就是4,utf8字符集中的W就是3,gbk字符集中的W就是2,ascii字符集中的W就是1

对于变⻓类型varchar(M)来说,这种类型表示能存储最多M个字符,所以这个类型能表示的字符串最多占⽤的字节数就是M×W。

假设它实际存储的字符串占⽤的字节数是L

所以确定使⽤1个字节还是2个字节表示真正字符串占⽤的字节数的规则就是这样:

  • 如果M×W <= 255,那么使⽤1个字节来表示真正字符串占⽤的字节数

  • 如果M×W > 255,则分为两种情况:

    • 如果L <= 127,则⽤1个字节来表示真正字符串占⽤的字节数
    • 如果L > 127,则⽤2个字节来表示真正字符串占⽤的字节数

也就是如果该可变字段允许存储的最⼤字节数(M×W)超过255字节并且真实存储的字节数(L)超过127字节,则使⽤2个字节,否则使⽤1个字节。
另外需要注意的⼀点是,变⻓字段⻓度列表中只存储值为⾮NULL 的列内容占⽤的⻓度,值为 NULL的列的⻓度是不储存的

我们查看第二行数据,第二行数据c5,它的字符串最多占⽤的字节数是1024,实际存储的字符串占用的字节是130,所以要用两个字节来表示长度,按照逆序存放 就是 82 80 04 05

如130*1转换成16进制为 0x82 也就是 0x02 + 0x80,最高位标识1之后,就是 0x82 + 0x80,对应咱们的变长字段长度列表的开头

在这里插入图片描述所以两行数据示意图如下:

在这里插入图片描述

4.1.2 NULL值列表

我们知道表中的某些列可能存储NULL值,如果把这些NULL值都放到记录的真实数据中存储会很占地⽅,所以Compact⾏格式把这些值为NULL的列统⼀管理起来,存储到NULL值列表中,它的处理过程是这样的

  • ⾸先统计表中允许存储NULL的列有哪些

我们前边说过,主键列、被NOT NULL修饰的列都是不可以存储NULL值的,所以在统计的时候不会把这些列算进去。⽐⽅说表demo1的4个列c1、c3、c4、c5 都是允许存储NULL值的,⽽c2列是被NOT NULL修饰,不允许存储NULL值。

  • 如果表中没有允许存储 NULL 的列,则 NULL值列表也不存在了,否则将每个允许存储NULL的列对应⼀个⼆进制位,⼆进制位按照列的顺序逆序排列,⼆进制位表示的意义如下

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

    因为表demo1有4个值允许为NULL的列,所以这4个列和⼆进制位的对应关系就是这样:

在这里插入图片描述

  • MySQL规定NULL值列表必须⽤整数个字节的位表示,如果使⽤的⼆进制位个数不是整数个字节,则在字节的⾼位补0。

对于第⼀条记录来说,c1、c3、c4、c5 这4个列的值都不为NULL,所以它们对应的个二进制位,不足一个字节,所以在字节的高位补0,效果就是这样:

在这里插入图片描述

所以第⼀条记录的NULL值列表⽤⼗六进制表示就是:0x00,以此类推,如果一个表中有9个允许为NULL,那这个记录的NULL值列表部分就需要2个字节来表示了

在这里插入图片描述
第二条数据c3、c4为值都为NULL,所以这4个列对应的⼆进制位的情况就是:

在这里插入图片描述

所以第⼆条记录的NULL值列表⽤⼗六进制表示就是:0x06,查看文件

在这里插入图片描述
所以这两条记录在填充了NULL值列表后的示意图就是这样:

在这里插入图片描述

4.1.3 记录头信息

除了变⻓字段⻓度列表、NULL值列表之外,还有⼀个⽤于描述记录的记录头信息,它是由固定的5个字节组成。5个字节也就是40个⼆进制位,不同的位代表不同的意思,如图:
在这里插入图片描述
这些⼆进制位代表的详细信息如下表:

名称⼤⼩(单位:bit)描述
预留位11没有使⽤
预留位21没有使⽤
delete_mask1标记该记录是否被删除
min_rec_mask1B+树的每层⾮叶⼦节点中的最⼩记录都会添加该标记
n_owned4表示当前记录拥有的记录数
heap_no13表示当前记录在记录堆的位置信息
record_type3表示当前记录的类型,0表示普通记录,1表示B+树⾮叶⼦节点记录,2表示最⼩记录,3表示最⼤记录
next_record16表示下⼀条记录的相对位置

我们查看demo1.ibd存储文件:

在这里插入图片描述
根据推理,很容易可以得到demo1数据表两条记录的记录头信息如下所示

第一行:00 00 10 00 3a
第二行:00 00 18 ff bb

根据记录头的构成,将上面的记录由十六进制转换为二进制分析
第一行:00000000 00000000 00010000 00000000 00110111
第一行:00000000 00000000 00011000 11111111 10111011

根据这些二进制数据,将数据按照记录头结构切分可以得到如下信息

预留位1(1b)预留位2(1b)delete_mask(1b)min_rec_mask(1b)n_owned(4b)heap_no(13)record_type(3b)next_record(16b)
第一行0000000000000000 00010(2)00000000000 00110111(55)
第一行0000000000000000 00011(3)00011111111 10111011(65467)

所以这两条记录在填充了记录头信息后的示意图就是这样:

在这里插入图片描述

4.2 记录的真实数据

对于demo1表来说,记录的真实数据除了c1、c2、c3、c4、c5这⼏个我们⾃⼰定义的列的数据以外,MySQL会为每个记录默认的添加⼀些列(也称为隐藏列),具体的列如下:

列名是否必须占⽤空间描述
row_id6字节⾏ID,唯⼀标识⼀条记录
transaction_id6字节事务ID
roll_pointer7字节回滚指针

小提示:
实际上这⼏个列的真正名称其实是:DB_ROW_ID DB_TRX_IDDB_ROLL_PTR,为了美观才写成了row_idtransaction_idroll_pointer,这⾥需要提⼀下InnoDB表对主键的⽣成策略:优先使⽤⽤户⾃定义主键作为主键,如果⽤户没有定义主键,则选取⼀个Unique键作为主键,如果表中连Unique键都没有定义的话,则InnoDB会为表默认添加⼀个名为row_id的隐藏列作为主键。所以我们从上表中可以看出:InnoDB存储引擎会为每条记录都添加DB_TRX_ID和DB_ROLL_PTR这两个列,但是row_id是可选的(在没有自定义主键以及Unique键的情况下才会添加该列)。这些隐藏列的值不用我们操心,InnoDB存储引擎会自己帮我们生成的。

因为表demo1并没有定义主键,所以MySQL服务器会为每条记录增加上述的3个列。

在这里插入图片描述
我们看看第一行内容的文件:

在这里插入图片描述
我们给第一行记录加上的真实数据,如下

在这里插入图片描述
参考ASCII码对照表:16进制的61对应a 62对应b 63对应c 20对应空格(char以外的7个字节的统统都用空格字符填充) 64对应d 65对应e,懵逼了吧

4.3 CHAR(M)列的存储格式

demo1表的c1c2c4c5列的类型是VARCHAR(10),而c3列的类型是CHAR(10)demo1表采用的是ascii字符集,这个字符集是一个定长字符集,也就是说表示一个字符采用固定的一个字节,如果采用变长的字符集(也就是表示一个字符需要的字节数不确定,比如gbk表示一个字符要1~2个字节、utf8表示一个字符要1~3个字节等)的话,c3列的长度也会被存储到变长字段长度列表中。

对于CHAR(M)类型的列来说,当列采用的是定长字符集时,该列占用的字节数不会被加到变长字段长度列表,而如果采用变长字符集时,该列占用的字节数也会被加到变长字段长度列表。

小提示:
变长字符集的CHAR(M)类型的列要求至少占用M个字节,而VARCHAR(M)却没有这个要求。比方说对于使用utf8字符集的CHAR(10)的列来说,该列存储的数据字节长度的范围是10~30个字节。即使我们向该列中存储一个空字符串也会占用10个字节,这是怕将来更新该列的值的字节长度大于原有值的字节长度而小于10个字节时,可以在该记录处直接更新,而不是在存储空间中重新分配一个新的记录空间,导致原有的记录空间成为所谓的碎片。

我们创建一张demo2表来看一下:

mysql> create table demo2( c1 varchar(10), c2 varchar(10) not null, c3 char(10), c4 varchar(10), c5 varchar(1024)) charset=utf8 row_format=compact;
Query OK, 0 rows affected, 1 warning (0.03 sec)

mysql> insert into demo2 values('aaaaa','bbbb','ccc','dd','e');
Query OK, 1 row affected (0.01 sec)

这里就不唠叨了,直接打开demo2.ibd文件查看

在这里插入图片描述
示意图中的效果如下:

在这里插入图片描述我们在插入一条数据

mysql> insert into demo2 values('一一一一一','一一 一','测试测试测试测测试','dd','e');

这条数据的字节数如下:5*3=15 3*3+1=10 3*9=27 2 1对应16进制逆序存放 01 02 1b oa of ,这里就不画图了,我们直接看demo2.ibd文件

在这里插入图片描述
这篇文档到此结束了,后面在讲其他的行格式,行溢出。本篇概念性有点强,大家可以慢慢理解。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/501103.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Go编程语言】 Go语言基础语法

Go语言基础语法 文章目录 Go语言基础语法一、注释1.单行注释2.多行注释 二、变量1.变量的定义2.变量的初始化3.理解变量&#xff08;内存地址&#xff09;4.变量交换5.匿名变量6.变量的作用域 三、常量1.常量的定义&#xff1a; const2.iota&#xff08;特殊常量&#xff09; 四…

HLS直播与延迟时长的来源与超低延迟直播

1.HLS直播延迟时长&#xff08;HTTP Live Streaming&#xff09; HTTP Live Streaming&#xff08;简称 HLS&#xff09;是一个基于 HTTP 的视频流协议&#xff0c;由 Apple 公司实现&#xff0c;Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS&…

Kmeans++ 算法对随机数据样本聚类

一、算法简介 K-means算法是一种常见的无监督学习聚类算法&#xff0c;其基本思想是将n个样本划分为k个簇&#xff0c;每个簇内的样本之间的相似度要尽可能的大&#xff0c;而不同簇之间的相似度要尽可能的小&#xff0c;通过最小化各个簇内点与该簇中心点的距离和来实现。 二…

API接口对程序员的帮助有哪些,参考值简要说明

API接口对程序员的帮助有哪些 提高开发效率&#xff1a;通过API接口&#xff0c;程序员能够在不用重复编写代码的情况下&#xff0c;直接获取其他应用程序提供的服务或数据&#xff0c;极大地提高了开发效率。 减少错误率&#xff1a;使用API接口可以避免手动输入数据容易出现…

(LDR6020)双USBType-C口快充头适配器方案(PD快充 支持功率动态分配,只需要一颗芯片完成所需功能)

6月7日&#xff0c;欧盟公布了“在欧盟境内统一使用USB Type-C接口用于移动设备充电”的法规。在同一天&#xff0c;苹果公司发布了自己的35W双USB Type-C口充电器。可以看到&#xff0c;多USB Type-C口&#xff08;下文简称:C口&#xff09;快充充电器将成为市场趋势。LDR6020…

thinkphp+vue+html高校固定资产管理系统维修 租借4h80u

本高校资产管理系统采用的数据库是Mysql&#xff0c;使用thinkphp框架开发。在设计过程中&#xff0c;充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。运行环境:phpstudy/wamp/xammp等 开发语言&#xff1a;php 后端框…

经验总结:(Nginx 快速入门)

为什么需要Nginx 一个普通web项目刚刚上线不久时,用户使用的少,并发度低,所以在一个服务器上用一个jar包启动应用就可以了,然后内部Tomcat返回内容给用户。但是慢慢的,用户量上来了,并发量逐渐增大,这时候一台服务器就满足不了我们的需求了。于是采用横向扩展,即增加服务器的数…

MySQL调优系列(三)——存储引擎的选择

一、什么是存储引擎 关系型数据库的数据是存在表里的&#xff0c;可以将表理解为由行和列组成的表格&#xff0c;类似于Excel的电子表格的形式&#xff0c;每个表格就是一个数据。 表是在存储数据的同时&#xff0c;还要组织数据的存储结构&#xff0c;而这些数据的组织结构就…

tomcat启动web项目报错汇总

tomcat启动web项目报错汇总 前言问题java: 找不到符号 符号: 方法 getType() 位置: 类型为com.mtwl.vehicle.carflow.p背景解决方案 java: -source 7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)背景问题解决 前言 简单记录一下tomcat部署web项…

【刷题记录】关于二叉树的OJ题

文章目录 1.根据二叉树创建字符串2.二叉树的层序遍历3.二叉树的最近公共祖先4.二叉搜索树与双向链表5. 从前序与中序遍历序列构造二叉树6.二叉树的遍历 1.根据二叉树创建字符串 题目链接&#xff1a;606. 根据二叉树创建字符串 - 力扣&#xff08;LeetCode&#xff09; 题干&…

DS200TCQCG1BKG什么是控制模式,控制模式如何分类?

​ DS200TCQCG1BKG.什么是控制模式&#xff0c;控制模式如何分类&#xff1f; 控制回路的功能是在受控变量偏离该值时将其恢复到其设定值&#xff0c;从而将过程保持在所需条件下。实现这一点的动作称为控制模式。 控制方式分为两类 连续模式包括比例、积分和微分模式。 什么…

企业短信遭疯狂盗用,可能是没配置验证码

手机短信作为一种快捷的通讯方式被广泛应用。不仅在个人日常生活中&#xff0c;企业也习惯使用手机短信来进行验证和提醒&#xff0c;以保证业务的正常进行。随着数字化的发展&#xff0c;手机短信也成为了不法分子滥用的目标之一&#xff0c;给个人和企业带来不同经济损失。 个…

百度AI,和“吴文俊奖”同行的十二年、千丈山、万里路

今天&#xff0c;AI正作为一个科技发展周期的轴心&#xff0c;成为万众瞩目的焦点。与历史上数次技术革命和AI浪潮所不同的是&#xff0c;这次AI的全球领先阵营里&#xff0c;有了中国的身影。 从一个学术灵感&#xff0c;到一项全球领先的专利技术&#xff0c;从一篇顶会论文到…

MySQL基础(十)创建和管理表

1. 基础知识 1.1 一条数据存储的过程 存储数据是处理数据的第一步。只有正确地把数据存储起来&#xff0c;我们才能进行有效的处理和分析。否则&#xff0c;只能是一团乱麻&#xff0c;无从下手。 那么&#xff0c;怎样才能把用户各种经营相关的、纷繁复杂的数据&#xff0c…

关于如何对VS的C++项目进行完全重命名

很多人一个开始在VS编写C项目的时候&#xff0c;第一个项目名称都是系统默认名称或者HelloWorld这类的名字&#xff0c;一看就比较小白。 一段时间以后&#xff0c;项目已经进行了一段时间了&#xff0c;这时候想要对项目名称进行重命名。但是&#xff0c;偏偏VS的重命名功能做…

【homeassistant中ESPHome无法正常添加新设备指导操作】

【homeassistant中ESPHome无法正常添加新设备指导操作】 1. 在ESPHome添加设备1.1 问题显示1.2 添加NEW DEVICE1.3 烧录初始化固件2. 编辑主板的代码并录入3. 进行设备编译4. 编译完成后尝试亮灯5. ip地址的设置1. 在ESPHome添加设备 1.1 问题显示 点击添加设备,然后continu…

【网络】传输层协议-UDP协议

文章目录 传输层TCP/UDP预备知识:端口号的理解端口号的范围 关于端口号的相关问题netstat命令pidof命令 UDP协议所处的位置UDP协议格式UDP的特点UDP的缓冲区基于UDP的应用层协议 传输层TCP/UDP 回忆数据发送到网络的过程 之前在学习HTTP等应用层协议时为了方便理解:我们简单的认…

液晶显示控制驱动器HD61202介绍

液晶显示控制驱动器HD61202的特点 HD61202液晶显示控制驱动器是一种带有驱动输出的图形液晶显示控制器&#xff0c;它可直接与8位微处理器相连&#xff0c;它可与HD61203配合对液晶屏进行行、列驱动。HD61202是一种带有列驱动输出的液晶显示控制器&#xff0c;它可与行驱动器HD…

Docker 进阶实战:数据管理、网络

文章目录 Docker 进阶实战&#xff1a;数据管理、网络数据管理Volume创建数据卷挂载数据卷共享数据卷删除数据卷 Bind mountstmpfs mounts 网络端口映射容器互联Docker 内部网络Docker linkDocker Networking Docker 进阶实战&#xff1a;数据管理、网络 数据管理 默认情况下…

基于simulink使用麦克风阵列的声波束成形

一、前言 此示例演示如何对麦克风阵列接收到的信号进行波束化&#xff0c;以在嘈杂环境中提取所需的语音信号。 二、模型的结构 该模型模拟在 10 元件均匀线性麦克风阵列 &#xff08;ULA&#xff09; 上接收来自不同方向的三个音频信号。在接收器处添加热噪声后&#xff0c;应…