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

MySQL知识整理

MySQL知识整理

  • 基础
    • 第一讲:基础架构:一条SQL查询语句是如何执行的?
      • 架构
      • 尽量减少长连接的原因和方案
      • 为什么尽量不要依赖查询缓存
  • 索引
    • 第四讲:深入浅出索引(上)
    • 第五讲:深入浅出索引(下)
      • 对覆盖索引的理解
      • 最左前缀原则
      • 索引下推
    • 第九讲:普通索引和唯一索引,应该怎么选择?
      • changebuffer及其应用场景
      • 普通索引和唯一索引,应该怎么选择?
    • 第十讲:MySQL为什么有时候会选错索引?
      • MySQL优化器选错索引的解决方法
    • 第十一讲:怎么给字符串字段加索引?
      • 字符串应该使用什么类型索引
    • 第十六讲:“orderby”是怎么工作的?
      • 全字段排序 VS rowid排序
    • 第十八讲:为什么这些SQL语句逻辑相同,性能却差异巨大?
  • 事务
    • 第三讲:事务隔离:为什么你改了我还看不见?
      • 事务隔离级别
    • 第八讲:事务到底是隔离的还是不隔离的?
    • 第六讲:全局锁和表锁 :给表加个字段怎么有这么多阻碍?
    • 第七讲:行锁功过:怎么减少行锁对性能的影响?
      • 全局锁:
      • 表级锁:
      • 行锁:
      • 两阶段锁协议:
      • 死锁
    • 第二十讲:幻读是什么,幻读有什么问题?
      • 并发事务中存在的问题
      • 如何解决幻读?
      • 间隙锁
      • 临键锁(Next-Key Lock)
  • 日志与主备
    • 第二讲:日志系统:一条SQL更新语句是如何执行的?
      • redo log 和 binlog 的不同
    • 第十五讲:答疑文章(一):日志和索引相关问题
      • MySQL崩溃恢复时的判断规则
      • 两阶段提交的不同时刻,在MySQL异常重启会出现什么现象
  • 临时表
    • 第十三讲:为什么表数据删掉一半,表文件大小不变?
      • 数据库中收缩表空间的方法
    • 第三十四讲: 到底可不可以使用join?
    • 第三十五讲:join语句怎么优化?
  • 实用性
    • 第十四讲:count(*)这么慢,我该怎么办?
      • count(*)在不同引擎中的实现方法
      • 不同count的性能问题select count(?) from t
    • 第三十二讲:为什么还有kill不掉的语句?

基础

第一讲:基础架构:一条SQL查询语句是如何执行的?

架构

在这里插入图片描述
MySQL分为Server层和存储引擎层两部分。
Server层包括连接器、查询缓存(在MySQL8.0被移除)、分析器、优化器、执行器等,涵盖MySQL的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎。从MySQL5.5.5版本开始InnoDB成为了默认存储引擎。InnoDB提供了事务支持、行级锁定和外键约束等功能,非常适合处理大量数据的应用程序。
可以在创建表的时候选择不同的存储引擎,例如CREATETABLEmy_table(…)ENGINE=InnoDB;

从上图可以看出,不同的存储引擎共用一个Server层,也就是从连接器到执行器的部分。

尽量减少长连接的原因和方案

长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。
短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。
长连接可以减少频繁建立连接的开销,但它可能导致随着时间和数据交换的增加,数据库占用的内存越来越大,因为每个连接都会消耗资源。如果不及时释放资源,确实可能会出现内存溢出的情况,导致操作系统为了保护系统稳定性,而触发OOM(OutOfMemory)机制杀掉占用大量内存的进程,MySQL就可能会因此异常重启。
1.定期断开长连接或者定期重置连接,通过执行mysql_reset_connection()来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
2.设置非交互式连接(编程)在关闭之前等待活动的秒数wait_timeout
3.设置交互式连接(shell)未发出任何请求并处于空闲状态时,超过interactive_timeout设置的时间后,MySQL服务器会自动关闭该连接
4.通过定期执行FLUSHHOSTS来清理错误的连接
5.在编程中,使用连接池的策略。连接池可以提供自动的连接管理功能,包括最大连接数的限制、连接的创建和销毁、连接的获取和释放,并且可以自动处理长时间不活跃连接的断开和重置。

为什么尽量不要依赖查询缓存

查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。MySQL也提供了这种“按需使用”的方式。你可以将参数query_cache_type设置成DEMAND,这样对于默认的SQL语句都不使用查询缓存。而对于你确定要使用查询缓存的语句,用SQL_CACHE显式指定

select SQL_CACHE * from T where ID = 10;

MySQL8.0开始没有查询缓存功能

索引

第四讲:深入浅出索引(上)

主键索引的叶子节点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引。
非主键索引的叶子节点内容是主键的值。在InnoDB里,非主键索引也被称为二级索引。

第五讲:深入浅出索引(下)

回表:非主键索引树回到主键索引树的过程

对覆盖索引的理解

覆盖索引是数据库查询优化中的一个概念,指的是一个索引包含了查询所需要的所有数据,因此查询可以直接通过索引来获取结果,而无需再回表查询实际的数据行。在InnoDB存储引擎中,使用覆盖索引可以大大提高查询效率,由于数据可以直接从索引中获取,数据库不必执行额外的I/O操作去读取数据表中的行。

最左前缀原则

在建立联合索引的时候,如何安排索内的字段顺序
第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
再就是需要考虑索引的空间了,(如果既有联合查询,又有基于a、b各自的查询,将字段小的单独建索引)

索引下推

在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

第九讲:普通索引和唯一索引,应该怎么选择?

changebuffer及其应用场景

Changebuffer是InnoDB存储引擎中的一个特殊数据结构,其主要用途是缓存对二级索引的修改操作(非唯一索引的插入、更新或删除操作,减少磁盘I/O操作并提升性能)。当对二级索引进行修改时,如果对应的索引页不在缓冲池中(比如,在磁盘上),使用changebuffer可以避免立即从磁盘读取索引页,从而提高性能。
在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行changebuffer中与这个页有关的操作。通过这种方式就能保证这个数据逻辑的正确性。
将changebuffer中的操作应用到原数据页,得到最新结果的过程称为merge。除了访问这个数据页会触发merge外,系统有后台线程会定期merge。在数据库正常关闭(shutdown)的过程中,也会执行merge操作。

当表中的非唯一索引用得比较少,或者是I/O系统非常快时,changebuffer带来的性能提升可能就不那么明显。

普通索引和唯一索引,应该怎么选择?

两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响。普通索引和changebuffer的配合使用,对于数据量大的表的更新优化还是很明显的。

第十讲:MySQL为什么有时候会选错索引?

MySQL优化器选错索引的解决方法

1.对于由于索引统计信息不准确导致的问题,你可以用analyzetable来解决。
2.对于其他优化器误判的情况,你可以在应用端用forceindex来强行指定索引,

第十一讲:怎么给字符串字段加索引?

字符串应该使用什么类型索引

1.直接创建完整索引,这样可能比较占用空间;
2.创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引;
3.倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题;例如身份证
4.创建hash字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。

第十六讲:“orderby”是怎么工作的?

MySQL会给每个线程分配一块内存用于排序,称为sort_buffer。sort_buffer_size,就是MySQL为排序开辟的内存(sort_buffer)的大小。如果要排序的数据量小于sort_buffer_size,排序就在内存中完成。但如果排序数据量太大,内存放不下,则不得不利用磁盘临时文件辅助排序

全字段排序 VS rowid排序

1.如果MySQL认为内存足够大,会优先选择全字段排序,把需要的字段都放到sort_buffer中,这样排序后就会直接从内存里面返回查询结果了,不用再回到原表去取数据。
2.如果MySQL实在是担心排序内存太小,会影响排序效率,才会采用rowid排序算法,这样排序过程中一次可以排序更多行,但是需要再回到原表去取数据。

第十八讲:为什么这些SQL语句逻辑相同,性能却差异巨大?

索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。
字符集utf8mb4是utf8的超集,所以当这两个类型的字符串在做比较的时候,MySQL内部的操作是,先把utf8字符串转成utf8mb4字符集,再做比较。

事务

第三讲:事务隔离:为什么你改了我还看不见?

事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在MySQL中,事务支持是在引擎层实现的。

事务隔离级别

1.读未提交(readuncommitted):一个事务还没提交时,它做的变更就能被别的事务看到。最低的隔离级别,可能会导致脏读、幻读或不可重复读;
2.读提交(readcommitted):一个事务提交之后,它做的变更才会被其他事务看到。(Oracle默认隔离级别)
3.可重复读(repeatableread):一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。(InnoDB默认隔离级别)
4.串行化(serializable):对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。

第八讲:事务到底是隔离的还是不隔离的?

begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动。
在可重复读隔离级别下,事务在启动的时候就“拍了个快照”。注意,这个快照是基于整库的。
更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(currentread)。

第六讲:全局锁和表锁 :给表加个字段怎么有这么多阻碍?

第七讲:行锁功过:怎么减少行锁对性能的影响?

全局锁:

对数据库实例加锁。应用于全库逻辑备份。命令是 Flush tables with read lock (FTWRL)。整个库处于只读状态,其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括 建表、修改表结构等)和更新类事务的提交语句。

表级锁:

表锁一般是在数据库引擎不支持行锁的时候才会被用到的。在MySQL中,表级别的锁主要有两种类型:
**表锁可以通过LOCK TABLES … READ/WRITE语法来实现,这个命令可以限制其他线程对特定表的读写操作。**比如,当你在一个线程中使用LOCK TABLES t1 READ, t2 WRITE;时,别的线程对t1的写操作或对t2的读写操作都会被阻塞。同时,持有锁的线程也受到限制,它只能对t1进行读操作,对t2进行读写操作。
元数据锁(Metadata Lock, MDL)是另一种表级锁,它被自动加上,而不需要显式的操作。**MDL的目的是确保在表被访问时,其结构不会发生变化。**例如,在读取或写入表数据时,会加上MDL读锁;而在执行表结构变更操作时,会加上MDL写锁。这样可以确保数据的一致性和安全性。MDL的读锁之间不会相互阻塞,而MDL的读锁和写锁之间、写锁和写锁之间则是互斥的。

行锁:

InnoDB存储引擎的行锁是自动加上的。当你执行一个涉及数据修改的语句,比如UPDATE或DELETE,InnoDB会对所涉及的数据行自动加锁,以防止其他事务并发修改这些同一行的数据。

如果你想显式地设置某些锁的级别,可以在事务中设置隔离级别,例如:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

这样可以控制锁的行为,防止其他的事务干扰当前事务。
还有一些特殊的锁定读操作,比如SELECT … FOR UPDATE和SELECT … LOCK IN SHARE MODE,这些操作会在读取数据的同时加上行锁或共享锁,以防止数据在事务结束前被其他事务修改或获取不一致的数据。
总的来说,InnoDB行锁的使用大部分是自动的,依赖于InnoDB的事务和隔离级别机制,而无需手动控制。

两阶段锁协议:

两阶段锁协议是一种在事务性数据库系统中维持数据一致性和事务隔离的锁定协议。它规定了一个事务在其生命周期内如何对数据加锁和解锁的标准过程,分为两个阶段:

加锁阶段(Growing Phase):在这个阶段中,事务可以获得所需的任何锁,但它不能释放任何锁。
解锁阶段(Shrinking Phase):在这个阶段,事务可以释放所持有的锁,但不可以再获得新的锁。
应用两阶段锁协议的关键要点在于,一旦事务开始释放它所持有的锁,它就不能再获得新的锁。这个协议可以防止多个事务同时更新同一数据而导致的数据不一致问题,并且帮助避免死锁的发生。不过,需要注意的是,即使遵守了两阶段锁协议,死锁的情况也是有可能发生的,这时候就需要额外的死锁检测机制来处理。

在InnoDB事务中,只要修改了数据,就会对相关的行加行锁,而这些锁会一直持有到事务结束(即执行COMMIT或ROLLBACK)才释放。这是遵循两阶段锁协议的一部分,确保在整个事务期间数据的一致性。
因此,在设计事务时,你应该注意锁的顺序。理想情况下,你应该尽量推迟那些最有可能导致锁冲突和影响并发度的锁的获得,这样可以最大限度地减少它们持有锁的时间,从而提高系统的并发性能。
例如,对于需要更新多行的业务逻辑,将对竞争最激烈的行的更新放在事务的最后一部分,可以减少这些行被锁定的时间,从而减少其他事务需要等待的时间,这对于性能是有利的。

死锁

当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。
解决策略:

  1. 设置超时时间(innodb_lock_wait_timeout): 如果出现死锁,系统会在超时后中断其中一个事务,从而使其他事务继续执行。但是,超时时间不能设置得太短,以避免误中断那些只是简单等待锁释放的正常事务。。
  2. 启用死锁检测(innodb_deadlock_detect): 当设置为ON时,会在事务被锁的时候检测是否有死锁发生。如果检测到死锁,数据库会自动回滚死锁链中的某个事务,来解开死锁。

第二十讲:幻读是什么,幻读有什么问题?

并发事务中存在的问题

赃读:一个事务读到另外一个事务还没有提交的数据。
不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
幻读与不可重复读类似:一个事务A查询数据时,另一个事务在插入数据时,事务A后续的查询中,发现了不该存在的记录,就是所谓的幻读

如何解决幻读?

产生幻读的原因是,行锁只能锁住行,但是新插入记录这个动作,要更新的是记 录之间的 “ 间隙 ” 。因此,为了解决幻读问题, InnoDB 只好引入新的锁,也就是 间隙锁(Gap Lock)。
但是间隙锁的引入会影响系统的并发度,也增加了锁分析 的复杂度

间隙锁

间隙锁(Gap Lock)不锁定具体的数据行,而是锁定两个数据行之间的间隙,主要目的是防止幻读。

例如,假设有一个表里的数据行是按照某一列的值顺序排列的,现在有一个事务A想要在值10和20之间插入一条数据。如果同时有另一个事务B正在执行涉及到这个范围的查询操作,并对这个范围加了间隙锁,那么事务A就不能在10和20之间插入行,直到事务B释放间隙锁为止。这就有效防止了在事务B的查询操作中出现由于事务A的插入操作而导致的幻读问题。

在REPEATABLE READ(可重复读)下,InnoDB默认会使用间隙锁。在进行范围查询时,不仅对查询到的数据行加锁,还会对查询范围内的间隙加锁。这种机制可以有效防止幻读,但是也可能会导致资源锁定的范围更大,进而影响到数据库的并发处理能力。
在READ COMMITTED(读已提交)下,InnoDB不使用间隙锁,除非是显式地通过某些SQL语句要求锁定某个范围,例如使用SELECT … FOR UPDATE进行加锁查询。这样做降低了资源的锁定范围,提高了数据库操作的并发性,但是牺牲了一部分事务的隔离性能,允许了幻读的发生。

临键锁(Next-Key Lock)

行锁和间隙锁的结合体
前提:间隙锁只能阻止行的插入,并不能解决所有的幻读问题。比如说,如果只是锁住了两个存在数据行之间的空隙,那么对这些实际存在的行的修改还是可以发生的,导致可能仍然会发生幻读现象。
临键锁锁定的是一个行记录以及前面的间隙(即区间)

特点
REPEATABLE READ下,对于普通的SELECT语句,InnoDB不会使用临键锁。但对于使用了FOR UPDATE或LOCK IN SHARE MODE的查询,InnoDB会对符合条件的索引记录以及在这些记录之间的间隙设置临键锁。
当一个事务通过一个索引来查找并锁定一行时,不仅这一行记录会被锁定(防止其他事务进行修改或删除),它之前的间隙也会被锁定(防止其他事务插入新的行)。
当对表进行范围查询并加锁时,比如使用SELECT ... FOR UPDATE命令跟一个范围条件,InnoDB会为查询范围内的所有存在的行以及所有间隙加上临键锁。

日志与主备

第二讲:日志系统:一条SQL更新语句是如何执行的?

redo log 和 binlog 的不同

  1. redo log 是 InnoDB 引擎特有的; binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  2. redo log 是物理日志,记录的是 “ 在某个数据页上做了什么修改 ” ; binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如 “ 给 ID=2 这一行的 c 字段加 1 ” 。
  3. redo log 是循环写的,空间固定会用完; binlog 是可以追加写入的。 “ 追加写 ” 是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
    当有一条记录需要更新的时候, InnoDB 引擎就会先把记录写到 redo log里面,并更新内存,这个时候更新就算完成了。同时, InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,有了 redo log , InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash - safe

第十五讲:答疑文章(一):日志和索引相关问题

MySQL崩溃恢复时的判断规则

1.如果redolog里面的事务是完整的,也就是已经有了commit标识,则直接提交;
2.如果redolog里面的事务只有完整的prepare,则判断对应的事务binlog是否存在并完整:
a.如果是,则提交事务;
b.否则,回滚事务。

两阶段提交的不同时刻,在MySQL异常重启会出现什么现象

在这里插入图片描述

1.如果在图中时刻A的地方,也就是写入redolog处于prepare阶段之后、写binlog之前,发生了崩溃(crash),由于此时binlog还没写,redolog也还没提交,所以崩溃恢复的时候,这个事务会回滚。这时候,binlog还没写,所以也不会传到备库。

2.在时刻B,binlog写完,redolog还没commit前发生crash,崩溃恢复过程中事务会被提交。

临时表

第十三讲:为什么表数据删掉一半,表文件大小不变?

一个 InnoDB 表包含两部分,即:表结构定义和数据。
因为表结构定义占用的空间很 小,所以我们今天主要讨论的是表数据。

数据库中收缩表空间的方法

如果要收缩一个表,只是 delete 掉表里面不用的数据的话,表文件的大小是不会变的,你还要通过 alter table 命令重建表,才能达到表文件变小的目的。

第三十四讲: 到底可不可以使用join?

  1. 如果可以使用被驱动表的索引, join 语句还是有其优势的;
  2. 不能使用被驱动表的索引,只能使用 Block Nested-Loop Join 算法,这样的语句就尽量不要使用;
  3. 在使用 join 的时候,应该让小表做驱动表。

第三十五讲:join语句怎么优化?

  1. BKA 优化是 MySQL 已经内置支持的,建议你默认使用;
  2. BNL 算法效率低,建议你都尽量转成 BKA 算法。优化的方向就是给被驱动表的关联字段加上索引;
  3. 基于临时表的改进方案,对于能够提前过滤出小数据的 join 语句来说,效果还是很好的;
  4. 如果需要 left join 的语义,就不能把被驱动表的字段放在 where 条件里面做等值判断或不等值判断,必须都写在 on 里面。

实用性

第十四讲:count(*)这么慢,我该怎么办?

count(*)在不同引擎中的实现方法

1.MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count() 的时候会直接返回这个数,效率很高;
2. InnoDB 引擎执行 count(
) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。(因为 InnoDB的事务默认的隔离级别是可重复读,在代码上就是通过多版本并发 控制,也就是 MVCC 来实现的。每一行记录都要判断自己是否对这个会话可见,因此对于 count(*) 请求说, InnoDB 只好把数据一行一行地读出依次判断,可见的行才能够用于计算 “ 基 于这个查询 ” 的表的总行数。 )

不同count的性能问题select count(?) from t

count() 的语义: count() 是一个聚合函数,对于返回的结果集,一行行地 判断,如果 count 函数的参数不是 NULL ,累计值就加 1 ,否则不加。最后返回累计值。
count() 、 count( 主键 id) 和 count(1) 都表示返回满足条件的 结果集的总行数 ;而 count( 字 段),则表示返回满足条件的 数据行里面,参数“字段”不为NULL的总个数 。
按照效率排序的话, count( 字段 )<count( 主键 id)<count(1)≈count(
) ,所以我建议
你,尽量使用 count(*) 。

第三十二讲:为什么还有kill不掉的语句?

在 MySQL 中有两个 kill 命令:
kill query+线程id ,表示终止这个线程中正在执行的语句;
kill connection +线程id ,这里 connection 可缺省,表示断开这个线程的连接,当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的。

参考
MySQL实战45讲总结(https://blog.csdn.net/liyifan687/article/details/114224787)
极客时间MySQL实战45讲学习笔记(https://blog.csdn.net/weixin_47887421/article/details/124065427)
MySQL 实战 45 讲(https://time.geekbang.org/column/intro/139)

相关文章:

MySQL知识整理

MySQL知识整理 基础第一讲&#xff1a;基础架构&#xff1a;一条SQL查询语句是如何执行的&#xff1f;架构尽量减少长连接的原因和方案为什么尽量不要依赖查询缓存 索引第四讲&#xff1a;深入浅出索引&#xff08;上&#xff09;第五讲&#xff1a;深入浅出索引&#xff08;下…...

代码随想录算法训练营第36天| 435. 无重叠区间、 763.划分字母区间*、56. 合并区间

435. 无重叠区间 力扣题目链接 代码 示例代码 class Solution { public:// 按照区间右边界排序static bool cmp (const vector<int>& a, const vector<int>& b) {return a[1] < b[1];}int eraseOverlapIntervals(vector<vector<int>>&a…...

SpringBoot整合Nacos

文章目录 nacosnacos下载nacos启动nacos相关配置demo-dev.yamldemo-test.yamluser.yaml 代码pom.xmlUserConfigBeanAutoRefreshConfigExampleValueAnnotationExampleDemoApplicationbootstrap.yml测试结果补充.刷新静态配置 nacos nacos下载 下载地址 一键傻瓜试安装即可,官…...

vue3 浅学

一、toRefs 问题: reactive 对象取出的所有属性值都是⾮响应式的 解决: 利⽤ toRefs 可以将⼀个响应式 reactive 对象的所有原始属性转换为 响应式的 ref 属性 二、hook函数 将可复⽤的功能代码进⾏封装&#xff0c;类似与vue2混⼊。 三、ref&#xff1a;获取元素或者组件 let …...

三小时使用鸿蒙OS模仿羊了个羊,附源码

学习鸿蒙arkTS语言&#xff0c;决定直接通过实践的方式上手&#xff0c;而不是一点点进行观看视频再来实现。 结合羊了个羊的开发思路&#xff0c;准备好相应的卡片素材后进行开发。遇到了需要arkTS进行解决的问题&#xff0c;再去查看相应的文档。 首先需要准备卡片对应的图片…...

如何使用 ArcGIS Pro 制作热力图

热力图是一种用颜色表示数据密度的地图&#xff0c;通常用来显示空间分布数据的热度或密度&#xff0c;我们可以通过 ArcGIS Pro 来制作热力图&#xff0c;这里为大家介绍一下制作的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数…...

SpringBoot之集成Redis

SpringBoot之集成Redis 一、Redis集成简介二、集成步骤2.1 添加依赖2.2 添加配置2.3 项目中使用 三、工具类封装四、序列化 &#xff08;正常都需要自定义序列化&#xff09;五、分布式锁&#xff08;一&#xff09;RedisTemplate 去实现场景一&#xff1a;单体应用场景二&…...

mybatis-plus与mybatis同时使用别名问题

在整合mybatis和mybatis-plus的时候发现一个小坑&#xff0c;单独使用mybatis&#xff0c;配置别名如下&#xff1a; #配置映射文件中指定的实体类的别名 mybatis.type-aliases-packagecom.jk.entity XML映射文件如下&#xff1a; <update id"update" paramete…...

MySQL基础知识——MySQL日志

一条查询语句的执行过程一般是经过连接器、 分析器、 优化器、 执行器等功能模块&#xff0c; 最后到达存储引擎。 那么&#xff0c; 一条更新语句的执行流程又是怎样的呢&#xff1f; 下面我们从一个表的一条更新语句进行具体介绍&#xff1a; 假设这个表有一个主键ID和一个…...

uniapp 地图分幅网格生成 小程序基于map组件

// 获取小数部分 const fractional function(x) {x Math.abs(x);return x - Math.floor(x); } const formatInt function(x, len) {let result x;len len - result.length;while (len > 0) {result 0 result;len--;}return result; }/*** 创建标准分幅网格* param …...

python项目练习——22、人脸识别软件

功能分析: 人脸检测: 识别图像或视频中的人脸,并标记出人脸的位置和边界框。 人脸识别: 识别人脸的身份或特征,通常使用已知的人脸数据库进行训练,然后在新的图像或视频中识别出人脸并匹配到相应的身份。 表情识别: 识别人脸的表情,如高兴、悲伤、愤怒等,并给出相应…...

Linux中账号登陆报错access denied

“Access denied” 是一个权限拒绝的错误提示&#xff0c;意味着用户无法获得所请求资源的访问权限。出现 “Access denied” 错误的原因可以有多种可能性&#xff0c;包括以下几种常见原因&#xff1a; 错误的用户名或密码&#xff1a;输入的用户名或密码不正确&#xff0c;导…...

python语言之round(num, n)小数四舍五入

文章目录 python round(num, n)小数四舍五入python round(num, n)基础银行家舍入&#xff08;Bankers Rounding&#xff09;利息被银行四舍五入后&#xff0c;你到底是赚了还是亏了&#xff1f; python小数位的使用decimal模块四舍五入(解决round 遇5不进) python round(num, n…...

安全风险攻击面管理如何提升企业网络弹性?

从研究人员近些年的调查结果来看&#xff0c;威胁攻击者目前非常善于识别和利用最具有成本效益的网络入侵方法&#xff0c;这就凸显出了企业实施资产识别并了解其资产与整个资产相关的安全态势的迫切需要。 目前来看&#xff0c;为了在如此复杂的网络环境中受到最小程度上的网络…...

常用的几款性能测试软件

Apache JMeter是一款免费、开源的性能测试工具&#xff0c;广泛应用于Web应用程序和服务的性能测试。它支持模拟多种不同类型的负载&#xff0c;可以测试应用程序在不同压力下的性能表现&#xff0c;并提供丰富的图表和报告来分析测试结果。 优点&#xff1a; 免费且开源&…...

谷歌google浏览器无法更新Chrome至最新版本怎么办?浏览器Chrome无法更新至最新版本

打开谷歌google浏览器提示&#xff1a;无法更新Chrome&#xff0c;Chrome无法更新至最新版本&#xff0c;因此您未能获得最新的功能和安全修复程序。点击「重新安装Chrome」后无法访问此网站&#xff0c;造成谷歌浏览器每天提示却无法更新Chrome至最新版本。 谷歌google浏览器无…...

认识异常(1)

❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&a…...

C++矩阵

C矩阵【基本】&#xff08;will循环&#xff09; #include<iostream> #include<string.h> using namespace std; int main() {int a[100][100]{0};int k 1;int i 0;int j 0;while(k<100){if(j>10){j0;i;}a[i][j]k;j;k;}i 0;j 0;while(true){if(i 9&am…...

解锁智能未来:用Ollama开启你的本地AI之旅

Ollama是一个用于在本地运行大型语言模型&#xff08;LLM&#xff09;的开源框架。它旨在简化在Docker容器中部署LLM的过程&#xff0c;使得管理和运行这些模型变得更加容易。Ollama提供了类似OpenAI的API接口和聊天界面&#xff0c;可以非常方便地部署最新版本的GPT模型并通过…...

CSS实现卡片在鼠标悬停时突出效果

在CSS中&#xff0c;实现卡片在鼠标悬停时突出&#xff0c;通常使用:hover伪类选择器。 :hover伪类选择器用于指定当鼠标指针悬停在某个元素上时&#xff0c;该元素的状态变化。通过:hover选择器&#xff0c;你可以定义鼠标悬停在元素上时元素的样式&#xff0c;比如改变颜色、…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

AI语音助手的Python实现

引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...