当前位置: 首页 > news >正文

了解M有SQL索引

目录

索引介绍

索引的优缺点

索引底层数据结构选型

Hash表

二叉查找树(BST)

AVL树

红黑树

B 树& B+树

索引类型总结

主键索引(Primary Key)

二级索引

聚簇索引与非聚簇索引

聚簇索引(聚集索引)

聚簇索引介绍

聚簇索引的优缺点

非聚簇索引(非聚集索引)

非聚簇索引介绍

非聚簇索引的优缺点

非聚簇索引一定回表查询吗(覆盖索引)?

覆盖索引和联合索引

覆盖索引

联合索引

最左前缀匹配原则


索引介绍

索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。

索引的作用就相当于书的目录。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。

索引底层数据结构存在很多种类型,常见的索引结构有: B 树, B+树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。

索引的优缺点

优点

  • 使用索引可以大大加快数据的检索速度(大大减少检索的数据量), 减少 IO 次数,这也是创建索引的最主要的原因。
  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

缺点

  • 创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。
  • 索引需要使用物理文件存储,也会耗费一定空间。

但是,使用索引一定能提高查询性能吗?

大多数情况下,索引查询都是比全表扫描要快的。但是如果数据库的数据量不大,那么使用索引也不一定能够带来很大提升。

索引底层数据结构选型

Hash表

哈希表是键值对的集合,通过键(key)即可快速取出对应的值(value),因此哈希表可以快速检索数据(接近 O(1))。

为何能够通过 key 快速取出 value 呢? 原因在于 哈希算法(也叫散列算法)。通过哈希算法,我们可以快速找到 key 对应的 index,找到了 index 也就找到了对应的 value。

hash = hashfunc(key)
index = hash % array_size

但是!哈希算法有个 Hash 冲突 问题,也就是说多个不同的 key 最后得到的 index 相同。通常情况下,我们常用的解决办法是 链地址法。链地址法就是将哈希冲突数据存放在链表中。就比如 JDK1.8 之前 HashMap 就是通过链地址法来解决哈希冲突的。不过,JDK1.8 以后HashMap为了减少链表过长的时候搜索时间过长引入了红黑树。

为了减少 Hash 冲突的发生,一个好的哈希函数应该“均匀地”将数据分布在整个可能的哈希值集合中。

MySQL 的 InnoDB 存储引擎不直接支持常规的哈希索引,但是,InnoDB 存储引擎中存在一种特殊的“自适应哈希索引”(Adaptive Hash Index),自适应哈希索引并不是传统意义上的纯哈希索引,而是结合了 B+Tree 和哈希索引的特点,以便更好地适应实际应用中的数据访问模式和性能需求。自适应哈希索引的每个哈希桶实际上是一个小型的 B+Tree 结构。这个 B+Tree 结构可以存储多个键值对,而不仅仅是一个键。这有助于减少哈希冲突链的长度,提高了索引的效率。关于 Adaptive Hash Index 的详细介绍,可以查看 MySQL 各种“Buffer”之 Adaptive Hash Index 这篇文章。

既然哈希表这么快,为什么 MySQL 没有使用其作为索引的数据结构呢? 主要是因为 Hash 索引不支持顺序和范围查询。假如我们要对表中的数据进行排序或者进行范围查询,那 Hash 索引可就不行了。并且,每次 IO 只能取一个。

试想一种情况:

SELECT * FROM tb1 WHERE id < 500;

在这种范围查询中,优势非常大,直接遍历比 500 小的叶子节点就够了。而 Hash 索引是根据 hash 算法来定位的,难不成还要把 1 - 499 的数据,每个都进行一次 hash 计算来定位吗?这就是 Hash 最大的缺点了。

二叉查找树(BST)

二叉查找树(Binary Search Tree)是一种基于二叉树的数据结构,它具有以下特点:

  1. 左子树所有节点的值均小于根节点的值。
  2. 右子树所有节点的值均大于根节点的值。
  3. 左右子树也分别为二叉查找树。

当二叉查找树是平衡的时候,也就是树的每个节点的左右子树深度相差不超过 1 的时候,查询的时间复杂度为 O(log2(N)),具有比较高的效率。然而,当二叉查找树不平衡时,例如在最坏情况下(有序插入节点),树会退化成线性链表(也被称为斜树),导致查询效率急剧下降,时间复杂退化为 O(N)。

也就是说,二叉查找树的性能非常依赖于它的平衡程度,这就导致其不适合作为 MySQL 底层索引的数据结构。

为了解决这个问题,并提高查询效率,人们发明了多种在二叉查找树基础上的改进型数据结构,如平衡二叉树、B-Tree、B+Tree 等。

AVL树

AVL 树是计算机科学中最早被发明的自平衡二叉查找树,它的名称来自于发明者 G.M. Adelson-Velsky 和 E.M. Landis 的名字缩写。AVL 树的特点是保证任何节点的左右子树高度之差不超过 1,因此也被称为高度平衡二叉树,它的查找、插入和删除在平均和最坏情况下的时间复杂度都是 O(logn)。

AVL 树采用了旋转操作来保持平衡。主要有四种旋转操作:LL 旋转、RR 旋转、LR 旋转和 RL 旋转。其中 LL 旋转和 RR 旋转分别用于处理左左和右右失衡,而 LR 旋转和 RL 旋转则用于处理左右和右左失衡。

由于 AVL 树需要频繁地进行旋转操作来保持平衡,因此会有较大的计算开销进而降低了数据库写操作的性能。并且, 在使用 AVL 树时,每个树节点仅存储一个数据,而每次进行磁盘 IO 时只能读取一个节点的数据,如果需要查询的数据分布在多个节点上,那么就需要进行多次磁盘 IO。 磁盘 IO 是一项耗时的操作,在设计数据库索引时,我们需要优先考虑如何最大限度地减少磁盘 IO 操作的次数。

实际应用中,AVL 树使用的并不多。

红黑树

红黑树是一种自平衡二叉查找树,通过在插入和删除节点时进行颜色变换和旋转操作,使得树始终保持平衡状态,它具有以下特点:

  1. 每个节点非红即黑;
  2. 根节点总是黑色的;
  3. 每个叶子节点都是黑色的空节点(NIL 节点);
  4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
  5. 从任意节点到它的叶子节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。

和 AVL 树不同的是,红黑树并不追求严格的平衡,而是大致的平衡。正因如此,红黑树的查询效率稍有下降,因为红黑树的平衡性相对较弱,可能会导致树的高度较高,这可能会导致一些数据需要进行多次磁盘 IO 操作才能查询到,这也是 MySQL 没有选择红黑树的主要原因。也正因如此,红黑树的插入和删除操作效率大大提高了,因为红黑树在插入和删除节点时只需进行 O(1) 次数的旋转和变色操作,即可保持基本平衡状态,而不需要像 AVL 树一样进行 O(logn) 次数的旋转操作。

红黑树的应用还是比较广泛的,TreeMap、TreeSet 以及 JDK1.8 的 HashMap 底层都用到了红黑树。对于数据在内存中的这种情况来说,红黑树的表现是非常优异的。

B 树& B+树

B 树也称 B-树,全称为 多路平衡查找树 ,B+ 树是 B 树的一种变体。B 树和 B+树中的 B 是 Balanced (平衡)的意思。

目前大部分数据库系统及文件系统都采用 B-Tree 或其变种 B+Tree 作为索引结构。

B 树& B+树两者有何异同呢?

  • B 树的所有节点既存放键(key) 也存放数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。
  • B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。
  • B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节点到叶子节点的过程,叶子节点的顺序检索很明显。
  • 在 B 树中进行范围查询时,首先找到要查找的下限,然后对 B 树进行中序遍历,直到找到查找的上限;而 B+树的范围查询,只需要对链表进行遍历即可。

综上,B+树与 B 树相比,具备更少的 IO 次数、更稳定的查询效率和更适于范围查询这些优势。

在 MySQL 中,MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构,但是,两者的实现方式不太一样。(下面的内容整理自《Java 工程师修炼之道》)

MyISAM 引擎中,B+Tree 叶节点的 data 域存放的是数据记录的地址。在索引检索的时候,首先按照 B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其 data 域的值,然后以 data 域的值为地址读取相应的数据记录。这被称为“非聚簇索引(非聚集索引)”。

MyISAM 引擎中,B+Tree 叶节点的 data 域存放的是数据记录的地址。在索引检索的时候,首先按照 B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其 data 域的值,然后以 data 域的值为地址读取相应的数据记录。这被称为“非聚簇索引(非聚集索引)”。

InnoDB 引擎中,其数据文件本身就是索引文件。相比 MyISAM,索引文件和数据文件是分离的,其表数据文件本身就是按 B+Tree 组织的一个索引结构,树的叶节点 data 域保存了完整的数据记录。这个索引的 key 是数据表的主键,因此 InnoDB 表数据文件本身就是主索引。这被称为“聚簇索引(聚集索引)”,而其余的索引都作为 辅助索引 ,辅助索引的 data 域存储相应记录主键的值而不是地址,这也是和 MyISAM 不同的地方。在根据主索引搜索时,直接找到 key 所在的节点即可取出数据;在根据辅助索引查找时,则需要先取出主键的值,再走一遍主索引。 因此,在设计表的时候,不建议使用过长的字段作为主键,也不建议使用非单调的字段作为主键,这样会造成主索引频繁分裂。

索引类型总结

按照数据结构维度划分:

  • BTree 索引:MySQL 里默认和最常用的索引类型。只有叶子节点存储 value,非叶子节点只有指针和 key。存储引擎 MyISAM 和 InnoDB 实现 BTree 索引都是使用 B+Tree,但二者实现方式不一样(前面已经介绍了)。
  • 哈希索引:类似键值对的形式,一次即可定位。
  • RTree 索引:一般不会使用,仅支持 geometry 数据类型,优势在于范围查找,效率较低,通常使用搜索引擎如 ElasticSearch 代替。
  • 全文索引:对文本的内容进行分词,进行搜索。目前只有 CHARVARCHARTEXT 列上可以创建全文索引。一般不会使用,效率较低,通常使用搜索引擎如 ElasticSearch 代替。

按照底层存储方式角度划分:

  • 聚簇索引(聚集索引):索引结构和数据一起存放的索引,InnoDB 中的主键索引就属于聚簇索引。
  • 非聚簇索引(非聚集索引):索引结构和数据分开存放的索引,二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引。

按照应用维度划分:

  • 主键索引:加速查询 + 列值唯一(不可以有 NULL)+ 表中只有一个。
  • 普通索引:仅加速查询。
  • 唯一索引:加速查询 + 列值唯一(可以有 NULL)。
  • 覆盖索引:一个索引包含(或者说覆盖)所有需要查询的字段的值。
  • 联合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并。
  • 全文索引:对文本的内容进行分词,进行搜索。目前只有 CHARVARCHARTEXT 列上可以创建全文索引。一般不会使用,效率较低,通常使用搜索引擎如 ElasticSearch 代替。

MySQL 8.x 中实现的索引新特性:

  • 隐藏索引:也称为不可见索引,不会被优化器使用,但是仍然需要维护,通常会软删除和灰度发布的场景中使用。主键不能设置为隐藏(包括显式设置或隐式设置)。
  • 降序索引:之前的版本就支持通过 desc 来指定索引为降序,但实际上创建的仍然是常规的升序索引。直到 MySQL 8.x 版本才开始真正支持降序索引。另外,在 MySQL 8.x 版本中,不再对 GROUP BY 语句进行隐式排序。
  • 函数索引:从 MySQL 8.0.13 版本开始支持在索引中使用函数或者表达式的值,也就是在索引中可以包含函数或者表达式。

主键索引(Primary Key)

数据表的主键列使用的就是主键索引。

一张数据表有只能有一个主键,并且主键不能为 null,不能重复。

在 MySQL 的 InnoDB 的表中,当没有显示的指定表的主键时,InnoDB 会自动先检查表中是否有唯一索引且不允许存在 null 值的字段,如果有,则选择该字段为默认的主键,否则 InnoDB 将会自动创建一个 6Byte 的自增主键。

二级索引

二级索引(Secondary Index)的叶子节点存储的数据是主键的值,也就是说,通过二级索引可以定位主键的位置,二级索引又称为辅助索引/非主键索引。

唯一索引,普通索引,前缀索引等索引都属于二级索引。

PS: 不懂的同学可以暂存疑,慢慢往下看,后面会有答案的,也可以自行搜索。

  1. 唯一索引(Unique Key):唯一索引也是一种约束。唯一索引的属性列不能出现重复的数据,但是允许数据为 NULL,一张表允许创建多个唯一索引。 建立唯一索引的目的大部分时候都是为了该属性列的数据的唯一性,而不是为了查询效率。
  2. 普通索引(Index):普通索引的唯一作用就是为了快速查询数据,一张表允许创建多个普通索引,并允许数据重复和 NULL。
  3. 前缀索引(Prefix):前缀索引只适用于字符串类型的数据。前缀索引是对文本的前几个字符创建索引,相比普通索引建立的数据更小,因为只取前几个字符。
  4. 全文索引(Full Text):全文索引主要是为了检索大文本数据中的关键字的信息,是目前搜索引擎数据库使用的一种技术。Mysql5.6 之前只有 MYISAM 引擎支持全文索引,5.6 之后 InnoDB 也支持了全文索引。

二级索引:

聚簇索引与非聚簇索引

聚簇索引(聚集索引)

聚簇索引介绍

聚簇索引(Clustered Index)即索引结构和数据一起存放的索引,并不是一种单独的索引类型。InnoDB 中的主键索引就属于聚簇索引。

在 MySQL 中,InnoDB 引擎的表的 .ibd文件就包含了该表的索引和数据,对于 InnoDB 引擎表来说,该表的索引(B+树)的每个非叶子节点存储索引,叶子节点存储索引和索引对应的数据。

聚簇索引的优缺点

优点

  • 查询速度非常快:聚簇索引的查询速度非常的快,因为整个 B+树本身就是一颗多叉平衡树,叶子节点也都是有序的,定位到索引的节点,就相当于定位到了数据。相比于非聚簇索引, 聚簇索引少了一次读取数据的 IO 操作。
  • 对排序查找和范围查找优化:聚簇索引对于主键的排序查找和范围查找速度非常快。

缺点

  • 依赖于有序的数据:因为 B+树是多路平衡树,如果索引的数据不是有序的,那么就需要在插入时排序,如果数据是整型还好,否则类似于字符串或 UUID 这种又长又难比较的数据,插入或查找的速度肯定比较慢。
  • 更新代价大:如果对索引列的数据被修改时,那么对应的索引也将会被修改,而且聚簇索引的叶子节点还存放着数据,修改代价肯定是较大的,所以对于主键索引来说,主键一般都是不可被修改的。

非聚簇索引(非聚集索引)

非聚簇索引介绍

非聚簇索引(Non-Clustered Index)即索引结构和数据分开存放的索引,并不是一种单独的索引类型。二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引。

非聚簇索引的叶子节点并不一定存放数据的指针,因为二级索引的叶子节点就存放的是主键,根据主键再回表查数据。

非聚簇索引的优缺点

优点

更新代价比聚簇索引要小 。非聚簇索引的更新代价就没有聚簇索引那么大了,非聚簇索引的叶子节点是不存放数据的。

缺点

  • 依赖于有序的数据:跟聚簇索引一样,非聚簇索引也依赖于有序的数据
  • 可能会二次查询(回表):这应该是非聚簇索引最大的缺点了。 当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询。

这是 MySQL 的表的文件截图:

聚簇索引和非聚簇索引:

非聚簇索引一定回表查询吗(覆盖索引)?

非聚簇索引不一定回表查询。

试想一种情况,用户准备使用 SQL 查询用户名,而用户名字段正好建立了索引。

 SELECT name FROM table WHERE name='guang19';

那么这个索引的 key 本身就是 name,查到对应的 name 直接返回就行了,无需回表查询。

即使是 MYISAM 也是这样,虽然 MYISAM 的主键索引确实需要回表,因为它的主键索引的叶子节点存放的是指针。但是!如果 SQL 查的就是主键呢?

SELECT id FROM table WHERE id=1;

主键索引本身的 key 就是主键,查到返回就行了。这种情况就称之为覆盖索引了。

覆盖索引和联合索引

覆盖索引

如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为 覆盖索引(Covering Index)

在 InnoDB 存储引擎中,非主键索引的叶子节点包含的是主键的值。这意味着,当使用非主键索引进行查询时,数据库会先找到对应的主键值,然后再通过主键索引来定位和检索完整的行数据。这个过程被称为“回表”。

覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,而无需回表查询。

如主键索引,如果一条 SQL 需要查询主键,那么正好根据主键索引就可以查到主键。再如普通索引,如果一条 SQL 需要查询 name,name 字段正好有索引,
那么直接根据这个索引就可以查到数据,也无需回表。

我们这里简单演示一下覆盖索引的效果。

1、创建一个名为 cus_order 的表,来实际测试一下这种排序方式。为了测试方便, cus_order 这张表只有 idscorename这 3 个字段。

CREATE TABLE `cus_order` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`score` int(11) NOT NULL,`name` varchar(11) NOT NULL DEFAULT '',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100000 DEFAULT CHARSET=utf8mb4;

2、定义一个简单的存储过程(PROCEDURE)来插入 100w 测试数据。

DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `BatchinsertDataToCusOder`(IN start_num INT,IN max_num INT)
BEGINDECLARE i INT default start_num;WHILE i < max_num DOinsert into `cus_order`(`id`, `score`, `name`)values (i,RAND() * 1000000,CONCAT('user', i));SET i = i + 1;END WHILE;END;;
DELIMITER ;

存储过程定义完成之后,我们执行存储过程即可!

CALL BatchinsertDataToCusOder(1, 1000000); # 插入100w+的随机数据

等待一会,100w 的测试数据就插入完成了!

3、创建覆盖索引并使用 EXPLAIN 命令分析。

为了能够对这 100w 数据按照 score 进行排序,我们需要执行下面的 SQL 语句。

#降序排序
SELECT `score`,`name` FROM `cus_order` ORDER BY `score` DESC;

使用 EXPLAIN 命令分析这条 SQL 语句,通过 Extra 这一列的 Using filesort ,我们发现是没有用到覆盖索引的。

不过这也是理所应当,毕竟我们现在还没有创建索引呢!

我们这里以 score 和 name 两个字段建立联合索引:

ALTER TABLE `cus_order` ADD INDEX id_score_name(score, name);

创建完成之后,再用 EXPLAIN 命令分析再次分析这条 SQL 语句。

通过 Extra 这一列的 Using index ,说明这条 SQL 语句成功使用了覆盖索引。

联合索引

使用表中的多个字段创建索引,就是 联合索引,也叫 组合索引 或 复合索引

以 score 和 name 两个字段建立联合索引:

ALTER TABLE `cus_order` ADD INDEX id_score_name(score, name);

最左前缀匹配原则

最左前缀匹配原则指的是在使用联合索引时,MySQL 会根据索引中的字段顺序,从左到右依次匹配查询条件中的字段。如果查询条件与索引中的最左侧字段相匹配,那么 MySQL 就会使用索引来过滤数据,这样可以提高查询效率。

最左匹配原则会一直向右匹配,直到遇到范围查询(如 >、<)为止。对于 >=、<=、BETWEEN 以及前缀匹配 LIKE 的范围查询,不会停止匹配(相关阅读:联合索引的最左匹配原则全网都在说的一个错误结论)。

假设有一个联合索引(column1, column2, column3),其从左到右的所有前缀为(column1)(column1, column2)(column1, column2, column3)(创建 1 个联合索引相当于创建了 3 个索引),包含这些列的所有查询都会走索引而不会全表扫描。

我们在使用联合索引时,可以将区分度高的字段放在最左边,这也可以过滤更多数据。

我们这里简单演示一下最左前缀匹配的效果。

1、创建一个名为 student 的表,这张表只有 idnameclass这 3 个字段。

CREATE TABLE `student` (`id` int NOT NULL,`name` varchar(100) DEFAULT NULL,`class` varchar(100) DEFAULT NULL,PRIMARY KEY (`id`),KEY `name_class_idx` (`name`,`class`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2、下面我们分别测试三条不同的 SQL 语句。

# 可以命中索引
SELECT * FROM student WHERE name = 'Anne Henry';
EXPLAIN SELECT * FROM student WHERE name = 'Anne Henry' AND class = 'lIrm08RYVk';
# 无法命中索引
SELECT * FROM student WHERE class = 'lIrm08RYVk';

再来看一个常见的面试题:如果有索引 联合索引(a,b,c),查询 a=1 AND c=1会走索引么?c=1 呢?b=1 AND c=1呢?

先不要往下看答案,给自己 3 分钟时间想一想。

  1. 查询 a=1 AND c=1:根据最左前缀匹配原则,查询可以使用索引的前缀部分。因此,该查询仅在 a=1 上使用索引,然后对结果进行 c=1 的过滤。
  2. 查询 c=1 :由于查询中不包含最左列 a,根据最左前缀匹配原则,整个索引都无法被使用。
  3. 查询b=1 AND c=1:和第二种一样的情况,整个索引都不会使用。

MySQL 8.0.13 版本引入了索引跳跃扫描(Index Skip Scan,简称 ISS),它可以在某些索引查询场景下提高查询效率。在没有 ISS 之前,不满足最左前缀匹配原则的联合索引查询中会执行全表扫描。而 ISS 允许 MySQL 在某些情况下避免全表扫描,即使查询条件不符合最左前缀。不过,这个功能比较鸡肋, 和 Oracle 中的没法比,MySQL 8.0.31 还报告了一个 bug:Bug #109145 Using index for skip scan cause incorrect result(后续版本已经修复)。个人建议知道有这个东西就好,不需要深究,实际项目也不一定能用上。

相关文章:

了解M有SQL索引

目录 索引介绍 索引的优缺点 索引底层数据结构选型 Hash表 二叉查找树(BST) AVL树 红黑树 B 树& B树 索引类型总结 主键索引(Primary Key) 二级索引 聚簇索引与非聚簇索引 聚簇索引(聚集索引) 聚簇索引介绍 聚簇索引的优缺点 非聚簇索引(非聚集索引) 非聚簇…...

进程间通信5:信号

引入 我们之前学习了信号量&#xff0c;信号量和信号可不是一个东西&#xff0c;不能混淆。 信号是什么以及一些基础概念 信号是一种让进程给其他进程发送异步消息的方式 信号是随时产生的&#xff0c;无法预测信号可以临时保存下来&#xff0c;之后再处理信号是异步发送的…...

Excel把其中一张工作表导出成一个新的文件

excel导出一张工作表 一个Excel表里有多个工作表&#xff0c;怎么才能导出一个工作表&#xff0c;让其生成新的Excel文件呢&#xff1f; 第一步&#xff1a;首先打开Excel表格&#xff0c;然后选择要导出的工作表的名字&#xff0c;比如“Sheet1”&#xff0c;把鼠标放到“She…...

python oa服务器巡检报告脚本的重构和修改(适应数盾OTP)有空再去改

Two-Step Vertification required&#xff1a; Please enter the mobile app OTPverification code: 01.因为巡检的服务器要双因子认证登录&#xff0c;也就是登录堡垒机时还要输入验证码。这对我的巡检查服务器的工作带来了不便。它的机制是每一次登录&#xff0c;算一次会话…...

微信小程序下拉刷新与上拉触底的全面教程

微信小程序下拉刷新与上拉触底的全面教程 引言 在微信小程序的开发中,用户体验至关重要。下拉刷新和上拉触底是提高用户交互体验的重要功能,能够让用户轻松获取最新数据和内容。本文将详细介绍这两个功能的实现方式,结合实际案例、代码示例和图片展示,帮助开发者轻松掌握…...

第三十九章:Grafana 概述、Docker安装与验证指南

Grafana 概述、Docker安装与验证指南 一、Grafana 概述 Grafana 是一个跨平台的开源可视化分析工具,是目前网络架构和应用分析中最流行的时序数据展示工具。它主要用于大规模指标数据的可视化展示,并支持多种数据源和丰富的可视化插件。Grafana 使用Go语言开发,具备数据监…...

使用go实现流式输出

流式输出的深度剖析 之前一直在调用openai的key&#xff0c;只是照着文档进行流式调用&#xff0c;也只知其确是流式与api有所不同&#xff0c;而未成体系深究其实现原理。 就以openai的官方流式输出为切入。 概述 流式输出&#xff08;Streaming Output&#xff09;是 HTT…...

WebSocket详解、WebSocket入门案例

目录 1.1 WebSocket介绍 http协议&#xff1a; webSocket协议&#xff1a; 1.2WebSocket协议&#xff1a; 1.3客户端&#xff08;浏览器&#xff09;实现 1.3.2 WebSocket对象的相关事宜&#xff1a; 1.3.3 WebSOcket方法 1.4 服务端实现 服务端如何接收客户端发送的请…...

元组部分介绍

元组部分 元组的基本格式与特点 #1.元组 #基本格式&#xff1a; 元组名&#xff08;元素1&#xff0c;元素2&#xff0c;元素3&#xff09; #注意&#xff1a;所有元素包含在小括号内&#xff0c;元素与元素之间用逗号隔开&#xff0c;可以是不同的元素类型 #注意&#xff1a…...

mfc100u.dll是什么?分享几种mfc100u.dll丢失的解决方法

mfc100u.dll 是一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;属于 Microsoft Foundation Classes (MFC) 库的一部分。MFC 是微软公司开发的一套用于快速开发 Windows 应用程序的 C 类库。mfc100u.dll 文件包含了 MFC 库中一些常用的函数和类的定义&#xff0c;这…...

企业数字化转型现状

国家数字经济战略背景 2018年以来&#xff0c;国家政府不断出台政策规范我国企业数字化治理市场。2018年9月颁布《关于发展数字经济稳定并扩大就业的指导意见》&#xff0c;支持建设一批数字经济创新创业孵化机构。积极推进供应链创新与应用&#xff0c;支持构建以企业为主导。…...

数据治理:在企业数据管理中的关键角色与实现路径——《DAMA 数据管理知识体系指南》读书笔记- 第 3 章

文章目录 1. 数据治理的核心内涵与战略价值2. 数据治理的驱动因素&#xff1a;不仅仅是合规3. 数据治理的组织模型&#xff1a;选择适合企业结构的运营模式4. 实施数据治理的关键步骤&#xff1a;战略、制度和文化5. 数据治理工具的选择&#xff1a;支持业务与流程的高效管理6.…...

树莓派2装FreeBSD14.1 Raspberry Pi2 install FreeBSD14.1 00000121:error:0A000086:SSL

树莓派2代的Model B采用Broadcom BCM2836 900MHz的四核SoC&#xff0c;1GB内存&#xff0c;是新一代开拓者&#xff0c;兼容1代B。相比之下&#xff0c;树莓派2的性能比1代提升6倍&#xff0c;内存翻了一番。Raspberry Pi 2不仅能跑全系列ARM GNU/Linux发行版&#xff0c;而且支…...

uniop触摸屏维修eTOP40系列ETOP40-0050

在现代化的工业与商业环境中&#xff0c;触摸屏设备已成为不可或缺的人机交互界面。UNIOP&#xff0c;作为一个知名的触摸屏品牌&#xff0c;以其高性能、稳定性和用户友好性&#xff0c;广泛应用于各种自动化控制系统、自助服务终端以及高端展示系统中。然而&#xff0c;即便如…...

uniapp+vue2重新进入小程序就清除缓存,设备需要重新扫码

代码 app.vue页面 <script>export default {onLaunch: function() {uni.removeStorageSync(equiId)}} </script>...

视频推拉流EasyDSS互联网直播点播平台技术特点及应用场景剖析

在数字科技日新月异的今天&#xff0c;视频直播和点播已经成为互联网内容传播的重要方式之一。而互联网直播点播平台EasyDSS作为功能强大的流媒体直播点播视频能力平台&#xff0c;提供了一站式的视频推拉流、转码、直播、点播、时移回放、存储等视频服务&#xff0c;广泛应用于…...

论文笔记 网络安全图谱以及溯源算法

​ 本文提出了一种网络攻击溯源框架&#xff0c;以及一种网络安全知识图谱&#xff0c;该图由六个部分组成&#xff0c;G <H&#xff0c;V&#xff0c;A&#xff0c;E&#xff0c;L&#xff0c;S&#xff0c;R>。 1|11.知识图 ​ 网络知识图由六个部分组成&#xff0c…...

抓住鸿蒙生态崛起的机遇,拥抱未来开发挑战

随着华为鸿蒙&#xff08;HarmonyOS&#xff09;的持续发展&#xff0c;鸿蒙生态正在迅速崛起&#xff0c;逐步在智能手机、智能穿戴、车载、家居等领域形成完整闭环。它不仅为开发者带来了新的机遇&#xff0c;还带来了技术上的挑战。如何抓住这些机遇并应对挑战&#xff0c;是…...

STM32WB55RG开发(5)----监测STM32WB连接状态

STM32WB55RG开发----5.生成 BLE 程序连接手机APP 概述硬件准备视频教学样品申请源码下载参考程序选择芯片型号配置时钟源配置时钟树RTC时钟配置RF wakeup时钟配置查看开启STM32_WPAN条件配置HSEM配置IPCC配置RTC启动RF开启蓝牙LED配置设置工程信息工程文件设置参考文档SVCCTL_A…...

ArcGIS应用指南:ArcGIS制作局部放大地图

在地理信息系统&#xff08;GIS&#xff09;中&#xff0c;制作详细且美观的地图是一项重要的技能。地图制作不仅仅是简单地将地理数据可视化&#xff0c;还需要考虑地图的可读性和美观性。局部放大图是一种常见的地图设计技巧&#xff0c;用于展示特定区域的详细信息&#xff…...

浅谈网络 | 传输层之TCP协议

目录 TCP 包头格式TCP 的三次握手TCP 的四次挥手TCP 的可靠性与"靠谱"的哲学TCP流量控制TCP拥塞控制 上一章我们提到&#xff0c;UDP 就像我们小时候一样简单天真&#xff0c;它相信“网之初&#xff0c;性本善&#xff0c;不丢包&#xff0c;不乱序”&#xff0c;因…...

‌Kotlin中的?.和!!主要区别

目录 1、?.和!!介绍 2、使用场景和最佳实践 3、代码示例和解释 1、?.和!!介绍 ‌Kotlin中的?.和!!主要区别在于它们对空指针的处理方式。‌ ‌?.&#xff08;安全调用操作符&#xff09;‌&#xff1a;当变量可能为null时&#xff0c;使用?.可以安全地调用其方法或属性…...

【漏洞复现】代付微信小程序系统 read.php 任意文件读取漏洞

免责声明: 本文旨在提供有关特定漏洞的信息,以帮助用户了解潜在风险。发布此信息旨在促进网络安全意识和技术进步,并非出于恶意。读者应理解,利用本文提到的漏洞或进行相关测试可能违反法律或服务协议。未经授权访问系统、网络或应用程序可能导致法律责任或严重后果…...

Python人工智能项目报告

一、实践概述 1、实践计划和目的 在现代社会&#xff0c;计算机技术已成为支撑社会发展的核心力量&#xff0c;渗透到生活的各个领域&#xff0c;应关注人类福祉&#xff0c;确保自己的工作成果能够造福社会&#xff0c;同时维护安全、健康的自然环境&#xff0c;设计出具有包…...

PyQt6+pyqtgraph折线图绘制显示

1、实现效果 2、环境&#xff1a; 确认已经安装pyqtgraph的模块&#xff0c;如果没有安装&#xff0c;使用命令安装&#xff1a; pip install pyqtgraph 3、代码实现&#xff1a; 绘制折线函数&#xff1a; import sys import random from PySide6.QtWidgets import QAppl…...

1-golang_org_x_crypto_bcrypt测试 --go开源库测试

1.实例测试 package mainimport ("fmt""golang.org/x/crypto/bcrypt" )func main() {password : []byte("mysecretpassword")hashedPassword, err : bcrypt.GenerateFromPassword(password, bcrypt.DefaultCost)if err ! nil {fmt.Println(err)…...

C语言菜鸟入门·关键字·union的用法

目录 1. 简介 2. 访问成员 2.1 声明 2.2 赋值 3. 共用体的大小 4. 与typedef联合使用 5. 更多关键字 1. 简介 共用体&#xff08;union&#xff09;是一种数据结构&#xff0c;它允许在同一内存位置存储不同的数据类型&#xff0c;但每次只能存储其中一种类型的…...

leetcode hot100【LeetCode 238.除自身以外数组的乘积】java实现

LeetCode 238.除自身以外数组的乘积 题目描述 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 …...

【测试工具JMeter篇】JMeter性能测试入门级教程(一)出炉,测试君请各位收藏了!!!

一、前言 Apache JMeter是纯Java的开源软件&#xff0c;最初由Apache软件基金会的Stefano Mazzocchi开发&#xff0c;旨在加载测试功能行为和测量性能。可以使用JMeter进行性能测试&#xff0c;即针对重负载、多用户和并发流量测试Web应用程序。 我们选择JMeter原因 是否测试过…...

嵌入式驱动开发详解3(pinctrl和gpio子系统)

文章目录 前言pinctrl子系统pin引脚配置pinctrl驱动详解 gpio子系统gpio属性配置gpio子系统驱动gpio子系统API函数与gpio子系统相关的of函数 pinctrl和gpio子系统的使用设备树配置驱动层部分用户层部分 前言 如果不用pinctrl和gpio子系统的话&#xff0c;我们开发驱动时需要先…...

使用 OpenCV 进行视频中的行人检测

在计算机视觉领域&#xff0c;行人检测是一个重要的研究方向&#xff0c;它在视频监控、自动驾驶、人机交互等领域都有着广泛的应用。本文将介绍如何使用 OpenCV 库来实现视频中的行人检测。 环境准备 首先&#xff0c;我们需要安装 OpenCV 库。可以通过以下命令来安装&#…...

py文件转pyd文件的那些坑

当编译py脚本文件发给客户使用时&#xff0c;为了保密源代码防止反编译&#xff0c;可以将py文件转换为pyd文件&#xff0c;然后使用pyinstaller工具转换为exe应用程序&#xff0c;但有时测试发现&#xff0c;py文件可以正常运行&#xff0c;转换为pyd文件后却有各种错误&#…...

go interface(接口)使用

在 Go 语言中&#xff0c;接口&#xff08;interface&#xff09;是一种抽象类型&#xff0c;它定义了一组方法&#xff0c;但是不实现这些方法。接口指定了一个对象的行为&#xff0c;而不关心对象的具体实现。接口使得代码更加灵活和可扩展。 定义接口 接口使用 type 关键字…...

前端---HTML(一)

HTML_网络的三大基石和html普通文本标签 1.我们要访问网络&#xff0c;需不需要知道&#xff0c;网络上的东西在哪&#xff1f; 为什么我们写&#xff0c;www.baidu.com就能找到百度了呢&#xff1f; 我一拼ping www.baidu.com 就拼到了ip地址&#xff1a; [119.75.218.70]…...

unsloth vlm模型Qwen2-VL、Llama 3.2 Vision微调案例

T4卡15G显卡训练 参考: https://github.com/unslothai/unsloth 按自己显卡cuda版本安装 免费colab微调代码: Qwen2-VL: https://colab.research.google.com/drive/1whHb54GNZMrNxIsi2wm2EY_-Pvo2QyKh?usp=sharing from unsloth import FastVisionModel # NEW instead …...

云网络基础- TCP/IP 协议

文章目录 典型服务模式TCP/IP 协议设置和查看IPIP地址的分类:IP地址组成: 网络位主机位组成克隆:产生一台新的虚拟机win2008 典型服务模式 • C/S,Client/Server架构 – 由服务器提供资源或某种功能 – 客户机使用资源或功能 TCP/IP 协议 • TCP/IP是最广泛支持的通信协议集合…...

【数据分享】2001-2023年我国30米分辨率冬小麦种植分布栅格数据(免费获取)

小麦、玉米、水稻等各类农作物的种植分布数据在农业、环境、国土等很多专业都经常用到&#xff01; 本次给大家分享的是我国2001-2023年逐年的30米分辨率冬小麦种植分布栅格数据&#xff01;数据格式为TIFF格式&#xff0c;数据坐标为GCS_WGS_1984。该数据包括我国11个省份的冬…...

前端预览pdf文件流

需求 后端接口返回pdf文件流&#xff0c;实现新窗口预览pdf。 解决方案 把后端返回的pdf文件流转为blob路径&#xff0c;利用浏览器直接预览。 具体实现步骤 1、引入axios import axios from axios;2、创建预览方法&#xff08;具体使用时将axios的请求路径替换为你的后端…...

【Leetcode 每日一题】146. LRU 缓存(c++)

146. LRU 缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中&#xff0c;则返回关键字的值&#x…...

Neural Magic 发布 LLM Compressor:提升大模型推理效率的新工具

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

QT简易项目 数据库可视化界面 数据库编程SQLITE QT5.12.3环境 C++实现

案例需求&#xff1a; 完成数据库插入&#xff0c;删除&#xff0c;修改&#xff0c;查看操作。 分为 插入&#xff0c;删除&#xff0c;修改&#xff0c;查看&#xff0c;查询 几个模块。 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget…...

为什么DDoS防御很贵?

分布式拒绝服务攻击&#xff08;DDoS攻击&#xff09;是一种常见的网络安全威胁&#xff0c;通过大量恶意流量使目标服务器无法提供正常服务。DDoS防御是一项复杂且昂贵的服务&#xff0c;本文将详细探讨为什么DDoS防御如此昂贵&#xff0c;并提供一些实用的代码示例和解决方案…...

Spring Boot3远程调用工具RestClient

Spring Boot3.2之后web模块提供了一个新的远程调用工具RestClient&#xff0c;它的使用比RestTemplate方便&#xff0c;开箱即用&#xff0c;不需要单独注入到容器之中&#xff0c;友好的rest风格调用。下面简单的介绍一下该工具的使用。 一、写几个rest风格测试接口 RestCont…...

C51相关实验

C51相关实验 LED //功能&#xff1a;1.让开发板的LED全亮&#xff0c;2,点亮某一个LED,3.让LED3以5Hz的频率闪动#include "reg52.h"#define LED P2 sbit led1 LED^1;void main(void) {LED 0xff;//LED全灭led1 0;while(1)//保持应用程序不退出{} }LED 输出端是高…...

云服务器部署springboot项目、云服务器配置JDK、Tomcat

目录 环境准备&#xff1a;JDK、Tomcat 将两个文件上传刀usr/java目录下并解压&#xff1a; 改java相关文件里的参数 执行以下命令&#xff0c;打开 profile 文件 执行以下命令&#xff0c;读取环境变量&#xff1a; 查看JDK是否安装成功&#xff1a; 改Tomcat参数 项目…...

STM32 USART串口发送

单片机学习&#xff01; 目录 前言 一、串口发送配置步骤 二、详细步骤 2.1 RCC开启USART和GPIO时钟 2.2 GPIO初始化 2.3 配置USART 2.4 开启USART 2.5 初始化总代码 三、发送数据函数设计 3.1 发送一个字节数据函数 3.2 发送一个数组函数 3.3 发送字符串函数 3.4…...

二叉树的深度搜索专题一>计算布尔二叉树的值

题目&#xff1a; 题目解析&#xff1a; 算法解析&#xff1a; 代码&#xff1a; public boolean evaluateTree(TreeNode root) {if(root.left null && root.right null) return root.val 1 ? true : false;boolean leftTree evaluateTree(root.left);boolean…...

Web day01 html css

目录 1.html: 常用标签&#xff1a; 1.video img p br b u i s &#xff1a; 2.布局标签&#xff1a;div span 3.表单标签&#xff1a; 4.表单标签项&#xff1a; 5.表格标签: 2.css: 1.使用样式: 2.选择器&#xff1a; 3.样式&#xff1a; 1.color&#xff1a; 2. …...

PHP 超级全局变量

超级全局变量是指在php任意脚本下都可以使用 PHP 超级全局变量列表: $GLOBALS&#xff1a;是PHP的一个超级全局变量组&#xff0c;在一个PHP脚本的全部作用域中都可以访问。 $_SERVER&#xff1a;$_SERVER 是一个PHP内置的超级全局变量,它是一个包含了诸如头信息(header)、路…...

题目:素数列

思路&#xff1a; 注意审题&#xff0c;题目中的等差素数列指公差相同且每一个元素都是素数的数列&#xff0c;并不是说是所有素数中一段连续且插值相同的数列&#xff0c;它可以是离散的。 因此&#xff0c;只需要暴力的遍历每一个素数&#xff0c;并找以其开头的所有可能等差…...