【MySQL】深入理解B+树索引

news2024/12/25 14:45:16

文章目录

  • 1. 前言
  • 2. 索引方案
  • 3. InnoDB的索引方案
  • 4. 索引的分类
    • 4.1 聚簇索引
    • 4.2 二级索引
    • 4.3 联合索引
  • 5. InnoDB中的B+树索引的注意事项
    • 5.1 内节点中目录项记录的唯一主
    • 5.2 一个页至少容纳2条记录
  • 6. MyISAM中的索引⽅案简单介绍

1. 前言

索引,是MySQL快速查询的秘籍。

如果没有索引,是怎么查询记录的呢?

首先,假如表中记录比较少,所有记录都可以存放在一个页中。

那么可以根据搜索条件,分为两种情况:

  • 以主键为搜索条件,这种就可以通过页目录使用二分法快速定位到相应的槽,接着遍历槽中的记录,就可以快速找到指定记录了。
  • 以其他列作为搜索条件,因为页中没有为非主键建立所谓的页目录,所以无法通过二分法定位槽的方式查找。只能从Infimum记录开始依次遍历单项链表的每条记录,然后对比是否符合搜索条件。(效率最低)

如果表中记录很多,就需要用比较多的页存储这些记录

那么,就需要两个步骤:

  1. 定位记录所在页
  2. 从所在页内查找相应记录。

由于没有索引,无论是根据主键列还是其他列,都不能快速定位记录所在页,需要从第一页开始往下找,在每一页中使用二分法查找指定记录。很显然,这种方式非常消耗时间。


2. 索引方案

就以这个t_index_demo这个表为例

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

该表指定了使用COMPACT为行格式,并且列c1为主键。

行格式示意图简化如下:

image-20230103154414952

以及记录存放在页中的示意图如下:

image-20230103154449496

先往表中插入数据

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

这些记录就会按照主键值的大小形成一个单向链表

image-20230103154615764

这时候,新插入一条数据。

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

这里假设每个页最多只能存放3条记录,再插入一条记录,就需要重新分配一个页了。

image-20230103155100593

理论应该像上图所示,但是如果是这样的话,页10的最大主键值为5,页25的一条记录的主键值为4,5>4。

不符合下一条数据页中用户记录的主键必须大于上一页中用户记录的主键值,因此需要将主键值为4的记录进行一次记录移动。

怎么移动呢?

  • 先将主键值为5的记录移动到页28
  • 再将主键值为4的记录插入到页10中

image-20230103155456823

这个过程,可以称为页分裂

在每次进行表记录的增删改操作的时候,都必须通过记录移动操作来保证这个规则一直成立。

这样插入数据的操作就完成了。

那么,怎么快速定位查找的记录在哪些数据页呢?

其实和查找用户记录类似,查找用户记录的时候,MySQL为了根据根据主键值快速定位一条记录而设立了页目录。所以也可以为快速定位记录所在的数据⻚⽽建⽴⼀个别的⽬录,但是建这个⽬录必须完成下边这些事⼉:

  • 下⼀个数据⻚中⽤户记录的主键值必须⼤于上⼀个⻚中⽤户记录的主键值
  • 给所有的页创建一个目录项

这个目录项,由两部分组成

  • ⻚的⽤户记录中最⼩的主键值,我们⽤key来表示。
  • ⻚号,我们⽤page_no表示。

image-20230103160348584

如上图所示,我们将几个目录项在物理内存中连续存储,比如放在一个数组中,就能实现根据主键值快速查找某条记录的功能了。

比如需要查找主键值为20的数据。

  • 现在目录项目根据二分查找确定主键值为20的记录在目录项3中。而目录项3中对应的就是页9
  • 接着在根据二分法在页9中就可以快速确认主键值为20的数据的具体记录了。

这种目录,就是我们常用的索引!!!!


3. InnoDB的索引方案

上述的是一种简单的索引方案,并不是真正的InnoDB索引方案。

在InnoDB中,由于这些目录项和用户记录长得很像,所以在InnoDB中复用了之前存储用户记录的页来存储目录项。

同时,InnoDB为了区分是目录项还是普通的用户记录,将目录项的记录头信息的record_type属性设置为1。

在这里,就可以知道record_type的所有含义了

  • 0:普通用户记录
  • 1:⽬录项记录
  • 2:最⼩记录
  • 3:最⼤记录

image-20230103161342140

这里总结一下⽬录项记录和普通的⽤户记录的不同点:

  1. ⽬录项记录的record_type值是1,⽽普通⽤户记录的record_type值是0。
  2. ⽬录项记录只有主键值和⻚的编号两个列,⽽普通的⽤户记录的列是⽤户⾃⼰定义的,可能包含很多列,另外还有InnoDB⾃⼰添加的隐藏列
  3. 只有在存储⽬录项记录的⻚中的主键值最⼩的⽬录项记录min_rec_mask值为1, 其他别的记录的min_rec_mask值都是0。

并且,需要注意的是,由于目录项使用的是和存储用户记录的页是一样的数据结构。

因此目录项实际是一个双向链表!!!!!而不是上面提到的目录项是连续空间!!!!

因此目录项实际是一个双向链表!!!!!而不是上面提到的目录项是连续空间!!!!

因此目录项实际是一个双向链表!!!!!而不是上面提到的目录项是连续空间!!!!

还有就是,InnoDB中一个页只有16kb大小,当表的数据太多,一个数据页已经不足以存放所有目录项的话,就需要多整一个存储目录项的页了。(这里假设了一个页最多存放4条记录)

image-20230103162014990

因此,在InnoDB中,如果需要查询一条用户记录的话,就需要三个步骤

  1. 确定⽬录项记录⻚
  2. 通过⽬录项记录⻚确定⽤户记录真实所在的⻚。
  3. 在真实存储⽤户记录的⻚中定位到具体的记录。

但是问题又来了,当一个表的数据非常多的时候,这也会产生非常多的目录项,那么怎么根据主键值快速定位一个目录项呢?

很简单,为这些存储⽬录项记录的⻚再⽣成⼀个更⾼级的⽬录,就像是⼀个多级⽬录⼀样,⼤⽬录⾥嵌套⼩⽬录,⼩⽬录⾥才是实际的数据。

image-20230103162322859

而这种结构,就是大名鼎鼎的B+树了

不论是存放⽤户记录的数据⻚,还是存放⽬录项记录的数据⻚,我们都把它们存放到B+树这个数据结构中了

我们也称这些数据页为B+树的节点,并且我们真正的用户记录其实存放在B+树最底层的节点上。

这些节点也被称为叶⼦节点或叶节点,其余⽤来存放⽬录项的节点称为⾮叶⼦节点或者内节点,其中 B+树最上边的那个节点也称为根节点。

image-20230103162615048

MySQL规定最下边的那层,也就是存放我们⽤户记录的那层为第0层,之 后依次往上加。

⼀般情况下,我们⽤到的B+树都不会超过4层,那我们通过主键值去查找某条记录最多只需要做4个⻚⾯内的查找 (查找3个⽬录项⻚和⼀个⽤户记录⻚)。

之前有提到的Page Header部分的一个PAGE_LEVEL属性,它记录的就是这个数据页作为节点在B+树所在的层级。


4. 索引的分类

这里探讨的索引主要有

  • 聚簇索引
  • 二级索引
  • 联合索引

4.1 聚簇索引

B+树本身是一个目录,或者说本身是一个索引。具有以下两个特点:

  1. 使⽤记录主键值的⼤⼩进⾏记录和⻚的排序
    1. ⻚内的记录是按照主键的⼤⼩顺序排成⼀个单向链表。
    2. 各个存放⽤户记录的⻚也是根据⻚中⽤户记录的主键⼤⼩顺序排成⼀个双向链表。
    3. 存放⽬录项记录的⻚分为不同的层次,在同⼀层次中的⻚也是根据⻚中⽬录项记录的主键⼤⼩顺序排成⼀个双向链表。
  2. B+树的叶⼦节点存储的是完整的⽤户记录。
    1. 所谓完整的⽤户记录,就是指这个记录中存储了所有列的值(包括隐藏列)。

具有这两种特性的B+树称为聚簇索引,所有完整的⽤户记录都存放在这个聚簇索引的叶⼦节点处。

这种聚簇索引并不需要我们在MySQL语句中显式的使⽤INDEX 语句去创建,InnoDB存储引擎会⾃动的为我们创建聚簇索引。

另外有趣的⼀点是,在InnoDB存储引擎中,聚簇索引就是数据的存储 ⽅式(所有的⽤户记录都存储在了叶⼦节点),也就是所谓的索引即数据,数据即索引。


4.2 二级索引

二级索引可以说就是另外一个B+树,这个B+树不再以主键的值进行排序。而是索引中指定的某个列作为大小作为数据页、页中记录的排序规则等等。

image-20230103211236326

这个B+树与上边介绍的聚簇索引有⼏处不同

  1. 使⽤记录c2列的⼤⼩进⾏记录和⻚的排序
    1. ⻚内的记录是按照c2列的⼤⼩顺序排成⼀个单向链表
    2. 各个存放⽤户记录的⻚也是根据⻚中记录的c2列⼤⼩顺序排成⼀个双向链表。
    3. 存放⽬录项记录的⻚分为不同的层次,在同⼀层次中的⻚也是根据⻚中⽬录项记录的c2列⼤⼩顺序排成⼀个双向链表。
  2. B+树的叶⼦节点存储的并不是完整的⽤户记录,⽽只是c2列+主键这两个列的值。
  3. 目录项记录中不再是主键+⻚号的搭配,⽽变成了c2列+⻚号的搭配。

比方说需要查找c2=4的列,这样的记录会有很多条,但是我们只需要在该 树的叶子节点处定位到第一条满足搜索条件 c2斗的那条记录,然后沿着自记录组成的单向链表一直向后扫描即可。

另外,各个叶子节点 组成了双向链表,搜索完了本页面的记录后可以很顺利地跳到下一个页面中的第一条记录,然 后继续沿着记录组成的单向链表向后扫描,查找过程如下。

  1. 确定第一条符合 c2=4条件的目录项记录所在的页
  2. 通过第一条符合 c2=4条件的目录项记录所在的页面确定第一条符合 c2=4条件的用 户记录所在的页
  3. 在真正存储第一条符合 c2=4条件的用户记录的页中定位到具体的记录。
  4. 但是这个B+树的叶⼦节点中的记录只存储了c2和c1(也就是主键)两个列,所以我们必须再根据主键值去聚簇索引中再查找⼀遍完整的⽤户记录这个通过携带主键信息到聚簇索引中重新定位完整的用户记录的过程也称为回表。

为什么还需要一次回表操作呢?直接把完整的用户记录放到时子节点不就好了么?

确实可以这样,但是太占内存,相当于每建一个B+树都需要将所有用户记录复制一遍,这样太浪费内存了。

因为这种按照⾮主键列建⽴的B+树需要⼀次回表操作才可以定位到完整的⽤户记录,所以这种B+树也被称为⼆级索引(英⽂名secondary index),或者辅助索引。

由于我们使⽤的是c2列的⼤⼩作为B+树的排序规则,所以我们也称这个B+树为为c2列建⽴的索引。

我们把上面聚簇索引或者二级索引的叶子节点中的记录称为用户记录

为了区分,也把聚簇索引叶子节点中的记录称为完整的用户记录

把二级索引叶子节点中的记录称为不完整的用户记录


4.3 联合索引

我们也可以同时以多个列的⼤⼩作为排序规则,也就是同时为多个列建⽴索引,这种就叫联合索引

⽐⽅说我们想让B+树按照c2和c3列的⼤⼩进⾏排序,这个包含两层含义:

  1. 先把各个记录和⻚按照c2列进⾏排序。
  2. 在记录的c2列相同的情况下,采⽤c3列进⾏排序

image-20230103212403565

但是注意的是以c2和c3列的⼤⼩为排序规则建⽴的B+树称为联合索引,本质上也是⼀个⼆级索引。

它的意思与分别为c2和c3列分别建⽴索引的表述是不同的

  1. 建⽴联合索引只会建⽴如上图⼀样的1棵B+树。
  2. 为c2和c3列分别建⽴索引会分别以c2和c3列的⼤⼩为排序规则建⽴2棵B+树。

5. InnoDB中的B+树索引的注意事项

B+树索引不是先把存储⽤户记录的叶⼦节点都画出来,然后接着画存储⽬录项记录的内节点,实际上B+树的形成过程 是这样的:

  1. 每当为某个表创建⼀个B+树索引(聚簇索引不是⼈为创建的,默认就有)的时候,都会为这个索引创建⼀个根节点⻚⾯。最开始表中没有数据的时候,每个 B+树索引对应的根节点中既没有⽤户记录,也没有⽬录项记录。
  2. 随后向表中插⼊⽤户记录时,先把⽤户记录存储到这个根节点中。
  3. 当根节点中的可⽤空间⽤完时继续插⼊记录,此时会将根节点中的所有记录复制到⼀个新分配的⻚,⽐如⻚a中,然后对这个新⻚进⾏⻚分裂的操作,得到另⼀ 个新⻚,⽐如⻚b。这时新插⼊的记录根据键值(也就是聚簇索引中的主键值,⼆级索引中对应的索引列的值)的⼤⼩就会被分配到⻚a或者⻚b中,⽽根节点便 升级为存储⽬录项记录的⻚。

需要注意的是,⼀个B+树索引的根节点⾃诞⽣之⽇起,便不会再移动

这样只要我们对某个表建⽴⼀个索引,那么它的根节点的⻚号便会被记录到某个地⽅,然后凡是InnoDB存储引擎需要⽤到这个索引的时候,都会从那个固定的地⽅取出根节点的⻚号,从⽽来访问这个索引


5.1 内节点中目录项记录的唯一主

就以为t_index_demo这个表的数据来说

c1c2c3
11‘u’
31‘d’
51‘y’
71‘a’

如果⼆级索引中⽬录项记录的内容只是索引列 + ⻚号的搭配的话,那么为c2列建⽴索引后的B+树应该⻓这样:

image-20230103215110757

如果此时插入一个c1为9,c2为1,c3为’c’的记录,那么由于原来每个页的记录的c2列均为1,那么新插入的数据就会不知道应该放到页4还是页5。

为了让新插⼊记录能找到⾃⼰在那个⻚⾥,我们需要保证在B+树的同⼀层内节点的⽬录项记录除⻚号这个字段以外是唯⼀的。所以对于⼆级索引的内节点的⽬录 项记录的内容实际上是由三个部分构成的:

  1. 索引列的值
  2. 主键值
  3. 页号

image-20230103215411989

这样我们再插⼊记录(9, 1, ‘c’)时,由于⻚3中存储的⽬录项记录是由c2列 + 主键 + ⻚号的值构成的,可以先把新记录的c2列的值和⻚3中各⽬录项记录的c2列 的值作⽐较,如果c2列的值相同的话,可以接着⽐较主键值因为B+树同⼀层中不同⽬录项记录的c2列 + 主键的值肯定是不⼀样的,所以最后肯定能定位唯⼀的 ⼀条⽬录项记录,在本例中最后确定新记录应该被插⼊到⻚5中。

对于二级索引的记录来说,是先按照二级索引列的值进行排序,如果该值相同,再按照主键值进行排序的

所以,为c2列建立索引相当于为(c2, c1)列建立了一个联合索引

而对于唯一二级索引(某列声明为UNIQUE)来说,也可能出现相同值的情况(为NULL),唯一二级索引的内节点的目录项也需要包括记录的主键值。


5.2 一个页至少容纳2条记录

一颗B+树只需要很少的层级就可以轻松存储数亿条记录。

虽然说一个大的目录存放一个子目录看起来也是可以的,但是这样的话层级关系就会很多。因此InnoDB规定,一个数据页至少存放两条记录。


6. MyISAM中的索引⽅案简单介绍

在InnoDB中,索引即数据。也就是聚簇索引的那棵B+树的叶⼦节点中已经把所有完整的⽤户记录都包含了

但是在MyISAM就不一定了。MyISAM的索引⽅案虽然也 使⽤树形结构,但是却将索引和数据分开存储

  • 将表中的记录按照记录的插⼊顺序单独存储在⼀个⽂件中,称之为数据⽂件。这个⽂件并不划分为若⼲个数据⻚,有多少记录就往这个⽂件中塞多少记录就成 了。我们可以通过⾏号⽽快速访问到⼀条记录

image-20230103220448376

由于插入数据的时候没有按照主键大小排序,因此不能使用二分法查找。

  • 使⽤MyISAM存储引擎的表会把索引信息另外存储到⼀个称为索引⽂件的另⼀个⽂件中。MyISAM会单独为表的主键创建⼀个索引,只不过在索引的叶⼦节点中存储的不是完整的⽤户记录,⽽是主键值 + ⾏号的组合。也就是先通过索引找到对应的⾏号,再通过⾏号去找对应的记录!

而InnoDB是只需要根据主键值对聚簇索引进⾏⼀次查找就能找到对应的记录,⽽在MyISAM中却需要进⾏⼀次 回表操作,意味着MyISAM中建⽴的索引相当于全部都是⼆级索引

  • 如果有需要的话,我们也可以对其它的列分别建⽴索引或者建⽴联合索引,原理和InnoDB中的索引差不多,不过在叶⼦节点处存储的是相应的列 + ⾏号。这些索引也全部都是⼆级索引。

MyISAM会直接在索引的叶子节点处存储该条记录在数据文件中的地址偏移量。

而InnoDB是获取主键之后再去聚簇索引中找记录。

所以,MyISAM的回表速度会比InnoDB快。


参考:《MySQL是怎样运行的:从根儿上理解 MySQL》


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

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

相关文章

ARMv8/ARMv9:深入理解MPIDR_EL1寄存器中的affinity

快速链接: . 👉👉👉 个人博客笔记导读目录(全部) 👈👈👈 付费专栏-付费课程 【购买须知】:【精选】ARMv8/ARMv9架构入门到精通-[目录] 👈👈👈官方文档(ARM ARM文档)的介绍如下所示 翻译一下MPIDR_EL1相关的英文,如下所示: 作用: 在多处理器系统中,为调…

Xshell 连接虚拟机(Ubuntu、CentOS)

对于一些linux的初学者来说,在没有自己的服务器时可以选择使用虚拟机来代替(如ubuntu、centos等)进行相关的学习。下面介绍下如何使用xshell来远程连接虚拟机。 注意:下面我以Ubuntu来举例说明。 1、创建虚拟机 虚拟机的创建网络…

1、数据库安装修改root密码管理自启服务

MySQL的下载和安装 登录MySQL官网下载MySQL.zip包 MySQL :: Download MySQL Community Server 下载完毕可自行选择存储位置,进行解压 解压后配置环境变量 完成配置后在MySQL目录下新建一个my.ini配置文件 文件写入以下内容 [client] # 设置mysql客户端默认字符集…

面向对象2(static修饰变量和方法、Javabean类、测试类和工具类、对main方法的理解、继承、子类继承父类构造方法变量和方法)

1、static修饰变量和方法 JDK8以前,静态区在方法区里面,JDK8开始,静态区挪到了堆内存当中 理解: 因为静态方法没有this,而非静态方法是有一个隐含的参数this的,所以想在静态方法里面调用非静态变量或方法就…

电子招标采购系统源码之传统采购模式面临的挑战

采购类型多 采购制度:采购金额、部门、品类的差异导致管理标准不同。 采购流程:从供应商管理、寻源操作到合同签订、订单执行,业务流程长,审批节点多,传统管理透明度低,联动性差。 供应商管理难 寻源&#…

亚马逊云科技 Build On - Serverless助力企业降本增效

亚马逊云科技 Build On - Serverless开启零售新篇章梅开三度活动体验实验问题总结一点建议咖啡案例实验Serverless学习总结梅开三度 Hi,作为一名Builder,这也是第三次参加由AWS&CSDN共同举办的Build On活动,跟前几期一样,活动举办方也是…

Java集合ArrayList-学习笔记

目录 ArrayList 集合和数组的优势对比: 1.1 ArrayList类概述 1.2 ArrayList类常用方法 1.3 ArrayList存储字符串并遍历 1.4 ArrayList存储学生对象并遍历 1.5 查找用户的索引 1.6 判断用户的是否存在 ArrayList 集合和数组的优势对比: 集合长度可…

Ardupilot EKF3核心算法《状态量速度与位置预测方程》

目录 文章目录 目录摘要1. Ardupilot EKF3核心算法《状态量速度预测方程》2. Ardupilot EKF3核心算法《状态量位置预测方程》3. Ardupilot EKF3核心算法《状态量速度与位置预测方程》摘要 本节主要记录Ardupilot EKF3核心算法《状态量速度与位置预测方程》的过程,欢迎批评指正…

mysql生产数据库被误删

23年的头一天上班安装数据库,因为ssh工具来回切换失误,犯下不可饶恕的错误,居然将生产数据库全部删除,工作十几年头一次干这种蠢事,第一时间反应是一世英名毁于一旦,赶紧跑路。第二反应还是想办法看能否挽回…

aws eks 使用 cloudformation 创建并更新自管节点组

参考资料 更新现有自行管理的节点组 使用eks自管节点组能够最大程度控制节点的各项配置和参数,包括并不限于ami,节点类型等 但是使用自管节点也给用户带来了较大的维护和更新成本。对于节点组的更新操作,我们可以使用cloudformation的方式…

速览Visual Studio 2022 中的新增功能

目录 性能改进 Visual Studio 2022 为 64 位 在文件中更快地查找 Git 工具速度更快 生成新式应用 适用于 C、.NET 和热重载的更佳开发工具 Blazor & 的汇报ASP.NET 的 Razor 编辑器 热重载 创新触手可及 Git 多存储库支持和行暂存支持 IntelliCode 改进 为每个…

魔方(15)二、三、四、五阶棋盘魔方

棋盘魔方 这价格实在可恶,于是我拿现成的魔方自己贴贴纸。 二阶棋盘魔方A 有4个角块是3面黑,4个角块是3面白,而6个面都是棋盘色。 只需要2步就可以转化成: 所以任意状态只要转化成这个状态再加2步就能复原了。 二阶棋盘魔方B&a…

【C++函数对象】STL基础语法学习 | 仿函数谓词内建仿函数

目录 ●仿函数 1.概念 2.使用 ●谓词 1.一元谓词 2.二元谓词 ●内建仿函数 1.算数仿函数 2.关系仿函数 3.逻辑仿函数 ●仿函数 1.概念 重载函数调用操作符的类,其对象常称为函数对象。函数对象使用重载的()时,行为类似函数的调用,所…

技术更高,设计更远:华为全屋智能设计大赛的审美之跃

“人生到处知何以?应似飞鸿踏雪泥。泥上偶然留指爪,鸿飞那复计东西。”很多设计师朋友跟我说,苏轼这首《和子由渑池怀旧》是对设计与审美的最高理解。好的设计,应该仅仅留下一点点痕迹,同时在简约的表象下隐含大量的审…

高通平台开发系列讲解(USB篇)USB调试手段汇总说明 - 视频课

文章目录 一、USB AT数据流说明二、BUS Hound 工具说明三、sysfs相关USB调试节点四、USB usbmon工具使用五、USB usbmon日志解析六、UsbTreeView软件的使用七、视频讲解分享沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 碰见USB AT不通怎么办?所以本篇章汇总了高通…

Vue与React中父子组件生命周期的执行顺序?【生命周期详细知识讲解!!!】

文章目录一、 Vue中父子组件生命周期1-1 加载渲染过程1-2 销毁过程1-3 展示案例二、 React中父子组件生命周期2-1 关于React新旧版生命周期介绍2-2 父子组件生命周期2-2-1 父子组件初始化2-2-2 子组件修改自身state2-2-3 父组件修改props2-2-4 卸载子组件一、 Vue中父子组件生命…

卷绕剩余长度计算FC(收放卷应用)

卷径实时计算方法详细内容请参看下面的文章链接: 卷径计算详解(通过卷绕的膜长和膜厚进行计算)_RXXW_Dor的博客-CSDN博客有关卷绕+张力控制可以参看专栏的系列文章,文章链接如下:变频器简单张力控制(线缆收放卷应用)_RXXW_Dor的博客-CSDN博客_收放卷应用张力控制的开闭环…

【EHub_tx1_tx2_E100】Ubuntu18.04 + ROS_ Melodic + LingAo IMU 测试及RVIZ展示

简介:介绍LingAo 的6自由度IMU模块 在EHub_tx1_tx2_E100载板,TX1核心模块环境(Ubuntu18.04)下测试ROS驱动,打开使用RVIZ 查看IMU数据,本文的前提条件是你的TX1里已经安装了ROS版本:Melodic。 关…

Spring Boot+Mybatis+layui框架实现的前后端分离的医院药品管理系统源码+数据库

springboot layui药品管理系统 介绍 前后端分离的药品管理系统。 完整代码下载地址:Spring BootMybatislayui框架实现的前后端分离的医院药品管理系统源码数据库 软件架构 前端:layui框架 后端:Spring BootMybatis 数据库:…

静态库和动态库

(1)什么是库 (2)静态库的制作 汇编 生成对应的.o文件(命令:gcc -c add.c div.c mult.c sub.c)创建静态库(命令:ar rcs libcalc.a add.o div.o mult.o sub.o)…