MySQL技术内幕InnoDB存储引擎 学习笔记 第六章 锁

2023-10-26

锁是数据库系统区别于文件系统的一个关键特性,锁机制用于管理对共享资源的并发访问。

InnoDB引擎会对表数据上锁以提供数据的完整性和一致性,除此之外,还会对数据库内部其他多个地方使用锁,从而保证对多种不同资源提供并发访问,如增删改LRU列表中的元素。

不同数据库和引擎使用的锁机制的实现可能完全不同。对MyISAM来说,其锁是表锁,并发读没有问题,但并发插入性能较差,如果插入是在底部的情况,MyISAM还是可以有一定并发操作。对于SQL server,在2005版之前都是页锁,相对于MyISAM的表锁性能有所提高,到2005版本开始支持乐观并发和悲观并发,在乐观并发下开始支持行级锁,但其实现方式与MySQL完全不同。

InnoDB引擎锁的实现与Oracle非常类似,提供一致性读、行级锁支持,行级锁没有相关的开销,可同时得到并发性和一致性。

InnoDB中实现了两种行级锁:
1.共享锁(S Lock):允许事务读一行数据。
2.排他锁(X Lock):允许事务删除或更新一行数据。

锁兼容:一个事务已经获取了行r的共享锁,另外的事务可以立即获得行r的共享锁,因为读取没有改变行r的数据。此时如果有事务想获得行r的排他锁,则必须等待事务释放行r上的共享锁,此种情况称为锁不兼容。

InnoDB引擎支持多粒度锁定,允许行级锁和表级锁同时存在。InnoDB支持一种额外的锁方式,称为意向锁,意向锁是表级别的锁,设计目的是表明某个事务正在某一行上持有锁,或者准备去持有锁,有两种意向锁:
1.意向共享锁(IS Lock):事务想要获取一个表中某几行的共享锁。
2.意向排他锁(IX Lock):事务想要获取一个表中某几行的排他锁。

事务在请求S锁和X锁前,需要先获得对应的意向锁。

查看当前请求锁的信息:
在这里插入图片描述
在这里插入图片描述
在InnoDB Plugin之前,只能通过SHOW FULL PROCESSLISTSHOW ENGINE INNODB STATUS等命令查看当前数据库请求,再判断当前事务中锁的情况。在新版本中,information_schema架构下添加了innodb_trx、innodb_locks、innodb_lock_waits三张表,可更简单地监控当前事务并分析可能存在的锁问题。首先看innodb_trx表中的字段:
1.trx_id:InnoDB引擎内部唯一的事务ID。
2.trx_state:当前事务状态。
3.trx_started:事务的开始时间。
4.trx_requested_lock_id:等待事务的锁ID,如果trx_state状态为LOCK WAIT,则该值代表当前事务等待的锁资源ID,该锁资源正在被其他事务占用。如trx_state不是LOCK WAIT,则该值为NULL。
5.trx_wait_started:事务等待开始的时间。
6.trx_weight:事务的权重,反映了一个事务修改和锁住的行数。发生死锁需要回滚时,InnoDB引擎会选择该值最小的事务进行回滚。
7.trx_mysql_thread_id:MySQL中线程id。
8.trx_query:事务运行的SQL语句,该值实际使用时有时会显示为NULL。

innodb_trx表只能显示当前运行的事务,不能判断锁的情况,使用innodb_locks表查看锁,该表中字段如下:
1.lock_id:锁ID。
2.lock_trx_id:事务ID。
3.lock_mode:锁的模式。
4.lock_type:锁的类型,表锁还是行锁。
5.lock_table:加锁的表。
6.lock_index:锁的索引。
7.lock_space:表空间ID。
8.lock_page:被锁住的页的数量,表锁时此值为NULL。
9.lock_rec:被锁住的行的数量,表锁时此值为NULL。
10.lock_data:被锁住的行的主键值,表锁时此值为NULL。此值不是可靠的值,当进行范围查找时,lock_data可能只是第一行的主键值。如果当前资源被锁住,且缓冲池中该被锁住资源所在的页被替换出内存,此时再查看innodb_locks表,该值会显示为NULL。

查出了每张表上的锁情况,就能判断锁的等待情况了,如果事务量太大,还是不容易判断,此时可通过innodb_lock_waits表查看等待情况,该表由以下字段组成:
1.requesting_trx_id:申请锁资源的事务ID。
2.requesting_lock_id:申请的锁的ID。
3.blockint_trx_id:当前占用此锁的事务ID。
4.blocking_lock_id:当前被占用的锁的ID。

可执行以下联合查询直观地看详细信息:

SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query
FROM information_schema.innodb_lock_waits w 
INNER JOIN information_schema.innodb_trx b 
ON b.trx_id = w.blocking_trx_id 
INNER JOIN information_schema.innodb_trx r 
ON r.trx_id = w.requesting_trx_id;

INNER JOIN等于JOIN,含义为选取两表的共有部分。运行结果如下:
在这里插入图片描述
在这里插入图片描述
一致性的非锁定行读指InnoDB通过行多版本控制的方式读取请求时间点时的数据库中行的数据。如果读取的行正执行DELETE、UPDATE操作,此时读操作不会等待行上锁的释放,而是会去读取行的一个快照数据:
在这里插入图片描述
之所以称其为非锁定读,是因为不需要等待要访问的行上的X锁的释放。快照数据是该行之前版本的数据,这是通过Undo段实现的,而Undo段原本用来在事务中回滚数据,因此快照数据本身没有开销。读快照数据不需要上锁,因为没有必要对历史的数据进行修改。

非锁定性读提高了数据读取的并发性,在InnoDB引擎的默认设置下,这是默认的读取方式,但在不同事务隔离级别下,读取的方式不同,并不是每个事务隔离级别下读取都是一致性读,即使都是使用一致性读,对于快照数据的定义也不同。

快照数据就是当前行数据之前的历史版本,可能有多个历史版本,一个行可能有不止一个快照数据,称其为行多版本技术,由此带来的并发控制称之为多版本并发控制(Multi Version Concurrency Control,MVCC)。

在Read Committed和Repeatable Read(InnoDB引擎默认事务隔离级别)下,InnoDB使用非锁定的一致性读,但它们对于快照的定义不同,Read Committed事务隔离级别下,非一致性读总是读取被锁定行的最新一份快照数据,在Repeatable Read事务隔离级别下,非一致性读总是读取事务开始时的行数据版本。

假如有两个事务,A事务如下:
在这里插入图片描述
此时事务A已开始,并读取了id为1的行数据,但事务并没有结束,此时在事务B中做以下修改:
在这里插入图片描述
同样事务B也未提交,此时id为1的行上加了一个X锁,如果此时再在事务A中读取id为1的行,如果InnoDB引擎的事务隔离级别现在是Read Committed或Repeatable Read,会使用非锁定的一致性读读取快照内容,结果如下(假设这段时间只有这两个事务,此时会只有一个版本的快照数据):
在这里插入图片描述
如果此时事务B提交了事务:
在这里插入图片描述
如果此时事务A再读取id为1的数据,不同事务隔离级别下结果就不同了:
1.如果是Read Committed事务隔离级别:
在这里插入图片描述
它总是会读取行的最新版本,如果行被锁定了,则读取最新的快照,因此会读不到id为1的行数据:
在这里插入图片描述
2.如果是Repeatable Read事务隔离级别:
在这里插入图片描述
它总是会读取事务开始时的行数据,因此此时A应该还能读取到id为1的行:
在这里插入图片描述
从时间角度展现上述示例:
在这里插入图片描述
对于Read Committed事务隔离级别,它违反了ACID中的隔离性。

默认,InnoDB引擎的SELECT操作使用一致性非锁定读,但某些情况下需要对读取操作进行加锁:
1.SELECT … FOR UPDATE:对读取的行记录加一个X锁,其他事务想在这些行上加任何锁都会被阻塞。
2.SELECT … LOCK IN SHARE MODE:对读取的行记录加一个S锁,其他事务可以向被锁定的记录加S锁,但会阻塞加X锁的事务。

以上两条语句在事务中使用时,事务提交了,锁也就释放了。

对于一致性非锁定读,即使读取的行已经被使用SELECT … FOR UPDATE语句加锁了,也是可以进行读取的。

InnoDB引擎对于每个含有自增长值的表都有一个自增长计数器,得到计数器的值:

SELECT MAX(auto_inc_col)
FROM tableName
FOR UPDATE;

插入操作会将这个计数器值加1赋予自增长列,实现方式为AUTO-INC Locking,这种实现方式采用一种特殊的表锁机制,为提高插入性能,锁不是在一个事务结束后才释放,而是完成对自增长值插入的SQL后立即释放。这种方式对于有自增长的列的并发插入性能较差,需要等待前一个插入的完成,对于INSERT … SELECT这种大数据量的插入,会令其他插入操作被阻塞。

从MySQL 5.1.22开始,InnoDB引擎提供了一种轻量级互斥量的自增长实现机制,大大提高了自增长值插入的性能,此版本开始,InnoDB引擎提供了参数innodb_autoinc_lock_mode,默认值为1,以下是自增长列的几种插入情况:
1.INSERT-like指所有的插入语句,如INSERT、REPLACE、INSERT … SELECT、REPLACE … SELECT、LOAD DATA等。
2.Simple inserts指能在插入前确认插入行数的语句,如INSERT、REPLACE等,但不包括INSERT … ON DUPLICATE KEY UPDATE(MySQL特有语句,当insert的记录的主键在表中冲突时,执行Update)这类SQL语句。
3.Bulk inserts指在插入前不能确定插入行数的语句,如INSERT … SELECT、REPLACE … SELECT、LOAD DATA语句。
4.Mixed-mode inserts指插入中有一部分值是自增长的,如INSERT语句同时插入多行数据时,有一部分自增列值给出、一部分为NULL值或INSERT … ON DUPLICATE KEY UPDATE时。

参数innodb_auoinc_lock_mode的可选值:
1.0是5.1.22版本之前自增长的实现方式,即通过表锁的AUTO-INC Locking方式。
2.1是参数默认值,对于Simple inserts,该值使用互斥量对内存中的计数器进行累加操作,对于Bulk inserts,还是使用传统的AUTO-INC Locking方式。此时,不考虑回滚操作,自增值的增长还是连续的。这种情况下,如果先使用了AUTO-INC Locking方式产生自增长的值,在该INSERT语句还未结束时,Simple inserts的操作还是会等待AUTO-INC Locking的释放。
3.2是令所有INSERT-like的自增长值的产生都是通过互斥量,这是性能最高的方式,但会带来一些问题,由于并发插入的存在,每次插入时,自增长的值可能不是连续的,如果主从复制时,使用的是Statement-Base Replication(主从库使用相同的SQL语句),可能会由于并发使得主从库的自增列值不同,此时应使用Row-Base Replication(主从库会做相同更改,binlog中记录的是行的改变而非SQL语句)。

MyISAM使用的是表锁,自增长不用考虑并发插入问题。

InnoDB引擎中,自增长的列必须是索引列,如果是联合索引,则必须是联合索引的第一个列,如果是第二个列则会报错,MyISAM没有这个问题:

CREATE TABLE tab (
    a    INT   auto_increment,
    b    INT,
    KEY(b, a)
) ENGINE = InnoDB;

运行它:
在这里插入图片描述
对于外键列,如果没有显式对这个列加索引,InnoDB引擎会自动对其添加一个索引,这样可以避免表锁。

对外键列的插入或更新,需要先查询父表中的记录,即SELECT父表,对于父表的SELECT,不使用一致性非锁定读,这样会发生数据不一致的问题,它会使用SELECT … LOCK IN SHARE MODE,对父表加一个S锁,如果此时父表上已经加X锁了,子表上的操作会被阻塞:
在这里插入图片描述
上图情况下,两个事务都没有COMMIT或ROLLBACK,此时事务B会被阻塞,因为事务A在父表的id=3的行上加了一个X锁,而事务B需要在父表上id=3的行加一个S锁,事务B会被阻塞。如果事务B访问父表时使用的是一致性非锁定读,在InnoDB的默认事务隔离级别Repeatable Read情况下,会读到父表中有id为3的行,可以进行插入操作,而事务A提交后,父表中就没有了id为3的记录,会出现父子表不一致的情况。如果此时查询innodb_locks表:
在这里插入图片描述
在这里插入图片描述
InnoDB引擎有三种行锁算法设计:
1.Record Lock:单个行记录上的锁。
2.Gap Lock:间隙锁,锁定一个范围,不包含记录本身。
3.Next-Key Lock:相当于1与2一起使用,可锁定一个范围,且锁定记录本身。是结合了Gap Lock和Record Lock的一种锁定算法,对于不同SQL查询语句,可能设置共享的Next-Key Lock和排他的Next-Key Lock。

Record Lock总是会锁定索引记录,如果InnoDB引擎表建立时没有设置索引,会使用InnoDB引擎隐式主键进行锁定。

演示Next-Key Lock,先创建表:

CREATE TABLE nkl (
    a    INT,
    PRIMARY KEY(a)
) ENGINE = InnoDB;

向表中插入以下数据:

BEGIN;

INSERT INTO nkl 
SELECT 1;

INSERT INTO nkl 
SELECT 2;

INSERT INTO nkl 
SELECT 3;

INSERT INTO nkl 
SELECT 4;

INSERT INTO nkl 
SELECT 7;

INSERT INTO nkl 
SELECT 8;

COMMIT;

接着执行以下两个事务:
在这里插入图片描述
在以上情况下,事务B无论插入的是5还是6都会被锁定,因为在Next-Key Lock算法下,Gap Lock锁定的是(-∞, 6)区间内所有数值,Record Lock锁定6,此时插入9是可以的。而对于单个值的索引查询,不需要用到Gap Lock,此时Next-Key Lock优化为Record Lock:
在这里插入图片描述
上例演示过程是在InnoDB默认事务隔离级别下进行的,即在Repeatable Read模式下Next-Key Lock算法是默认的行记录锁定算法。

锁可能带来以下三种问题:
1.丢失更新:多用户同时修改一条记录时,可能会丢失更新,即用户的更新操作被另一个用户的更新操作覆盖了,比如以下情况:
(1)事务1查询一行数据,放入本地内存,显示给用户1。
(2)事务2查询同一行数据,放入本地内存,显示给用户2。
(3)用户1修改这行记录,更新数据库并提交。
(4)用户2修改这行记录,更新数据库并提交。此时用户1的修改被丢失了。

要避免丢失更新,需要让事务变成串行操作,可在第(1)步给记录加一个排他锁(下图的for update子句),此时事务2需要等待(1)(3)步完成才能进行第(2)步查询数据:
在这里插入图片描述
2.脏读:脏数据和脏页不同,脏页指在缓冲池中已被修改,但还没被刷新到磁盘的页,即内存中的页和磁盘中的页中数据不一致(当然在数据刷到磁盘前,重做日志已被写入),而脏数据指在缓冲池中被修改但还没被事务提交的数据。

读脏页不会影响数据一致性,因为有效数据在脏页中,这样异步同步数据还能带来性能的提高。而读脏数据意味着一个事务读到了另一个事务中未提交的数据,违反了数据库的隔离性。

事务隔离级别Read Uncommitted才会发生脏读。

3.不可重复读:指在同一个事务内多次读同一数据时,在两次读的数据的间隔,由于另一个事务的修改,导致两次读到的数据不同。

事务隔离级别Read Committed会导致不可重复读。一般不可重复读的问题是可接受的,SQL server和Oracle数据库的默认隔离级别都是Read Committed。

InnoDB引擎通过使用Next-Key Lock算法避免不可重复读的问题,MySQL官方文档将不可重复读定义为Phantom Problem(幻读),在此算法下,对于索引的扫描锁住的不仅是扫描到的索引,还锁住这些索引覆盖的范围,因此对于这个范围内的插入都是不允许的,这就避免了另外的事务在这个范围内插入数据导致的不可重复读问题,InnoDB默认事务隔离级别下采用Next-Key Lock算法,避免了不可重复读问题。

由于不同锁之间的兼容性关系,有些时候一个事务中的锁需要等待另一个事务中的锁释放它所占用的资源,这就是阻塞。

InnoDB引擎中,参数innodb_lock_wait_timeout用来控制阻塞等待的最大时间(默认50秒,动态参数,可运行时调整),参数innodb_rollback_on_timeout用来设定等待阻塞超时后对进行中的事务是否进行回滚(默认OFF,不回滚,静态参数)。

默认,InnoDB不对阻塞超时的事务进行回滚,而是提交,可能会产生错误,以下是一个例子:
在这里插入图片描述
在事务A中对上表加一个Next-Key Lock,锁住a小于4的所有记录,4也被锁住:
在这里插入图片描述
在这里插入图片描述
在事务B中,进行插入操作:
在这里插入图片描述
可见事务B并没有执行完,但已经执行的部分被提交。

经典死锁情况:
**在这里插入图片描述**
如上图,InnoDB检测到了死锁,大多数的死锁都可以被检测到,不需要人为干预。上例中事务B发生死锁后进行了回滚,释放了锁,事务A才得到了资源。InnoDB引擎不会回滚大部分的错误异常,但死锁除外,因此出现死锁异常时,不需要对事务再次回滚。

Oracle数据库产生死锁的常见原因是没有对外键添加索引,而InnoDB引擎会自动对表中外键列添加索引,删除此索引时会抛出异常。

锁升级指将锁的范围扩大,如将行锁升级为页锁,将页锁升级为表锁。有些数据库设计认为锁是一个稀缺资源,想避免维护锁的开销,可将锁升级,SQL server就是这样做的,它会在合适的时候自动将行、键或分页级锁升级为更粗粒度的锁,保护了系统资源,防止系统使用太多内存维护锁,一定程度上提高了效率,但会带来并发性能的降低。

在SQL server 2005之后,新支持了行锁,但其设计与InnoDB引擎完全不同,以下情况仍可能发生锁升级:
1.一句单独的SQL语句在一个对象上持有的锁数量超过阈值(默认5000),如果是不同对象,则不会发生锁升级。
2.锁资源占用的内存超过了激活内存的40%时。

InnoDB引擎没有锁升级,对它来说1个锁和1000000个锁是一样的,都没有开销,这点与Oracle数据库类似。InnoDB记录锁是以位图表示的,0表示未加锁,1表示加锁,基本没有开销。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL技术内幕InnoDB存储引擎 学习笔记 第六章 锁 的相关文章

  • 使用MySqlCommand参数时如何查看命令字符串?

    代码如下 MySqlCommand cmd new MySqlCommand SELECT FROM DB name here WHERE some field some value cmd Parameters AddWithValue
  • 更改 django 应用程序名称时迁移历史记录不一致

    我正在尝试重命名 django 网站中的应用程序之一 还有另一个应用程序依赖于它及其 mysql 表 我检查了两个应用程序中的所有文件 并将旧名称的实例更改为新名称 但是 现在我在尝试执行迁移时遇到此错误消息 File Users Limo
  • 在mysql中将纪元数转换为人类可读的日期

    我有一个纪元号 例如 1389422614485 存储该值的值的数据类型是varchar 我想将其值转换为人类可读的时间 我们怎样才能做到呢 这种转换有什么例子吗 你的时代价值1389422614485似乎具有毫秒精度 所以你需要使用一些m
  • 将所有 mysql 选定的行放入数组中

    我想知道 php 中是否有一个函数可以允许我将所有选定的数据放入一个数组中 目前我正在使用 mysql fetch array 正如我在手册中读到的那样 该函数不会获取表中的每条记录 result mysql query SELECT FR
  • 更改表以给出外键约束

    我有一个表 其中有 2 列 是从两个不同的表复制的 我现在要做的是对列名 email 和 id 给出外键约束 如下所示 ALTER TABLE users role map ADD CONSTRAINT FK users role map
  • 如何向多个涉及外键依赖的表插入数据(MySQL)

    我正在寻找将数据插入多个 MySQL 表的最佳实践方法 其中某些列是外键依赖项 这是一个例子 Table contacts contact id first name last name prof id zip code 联系人 表有主键
  • mysql CLI 工具是否提供了一种以控制台友好的方式显示二进制数据的方法?

    我有一个 MySQL 数据库 其中包含一个带有二进制类型列的表 我希望能够投影该列而不必运行它 例如 HEX 是否mysqlCLI 工具有一个配置选项或其他方式来显示二进制数据的表示形式 而不会输出任意字节供我的控制台以搞笑 烦人的方式解释
  • 在 Kubernetes 中向 MySQL 添加另一个用户

    这是我的MySQL apiVersion apps v1beta1 kind Deployment metadata name abc def my mysql namespace abc sk test labels project ab
  • 为什么这个简单的 MySQL 查询不返回该行?

    我在表中有一行users与用户名test 但由于某种原因 此查询返回空结果集 SELECT id FROM users WHERE username test AND id null 但是 如果我删除 id null段 查询返回结果id 1
  • DataImportHandler 未在 solr admin 中索引 mysql 表

    我正在尝试使用 DataImportHandler 在 solr 中索引 mysql 表 但它似乎没有索引 数据配置 xml
  • php 中的 PDOException“找不到驱动程序”

    我已经在 Linux 系统上安装了 Lampp 并且正在学习 symfony2 同时尝试使用 symfony2 命令创建架构 php app console doctrine schema create 我收到以下错误消息 PDOExcep
  • Mysqldb 属性错误:游标

    我开始在 python 中使用 mysqldb 模块 并且我似乎对调用查询的 标准 方式有一些问题 我知道标准方法是创建游标 然后用它来执行查询 然而 当我尝试实例化一个时 它给了我以下错误 属性错误 光标 我的数据库类如下所示 class
  • 如何抑制输出并检查命令是否成功?

    我正在尝试编写一个 powershell 脚本来测试 MySQL 登录是否成功 检查是否发生错误 我还想抑制命令的所有输出 成功或不成功 这些是我尝试过的事情 mysql u root password mypass e show data
  • Android-数据在微调器中分配,但选择时不显示微调器中的值

    Problem我正在使用 Retrofit 从 mysql 获取一些产品类别 数据即将到来并在微调器中分配 但是当我选择一个项目时 它不会显示 在下拉菜单中 项目已分配 并且 setOnItemSelected 侦听器也正在工作 但所选项目
  • MySqlBulkLoader 说明

    你能告诉我什么吗MySqlBulkLoader的用途 在哪里以及如何使用它 一些例子也将不胜感激 请 MySQLBulkLoader是MySQL Connector Net类中的一个类 包装了MySQL语句LOAD DATA INFILE
  • 删除ID最小的记录

    当我在 MySQL 中输入此查询时 DELETE FROM myTable WHERE ID SELECT Min ID FROM myTable 我收到以下错误消息 1093 You can t specify target table
  • MySQL 5.0 索引 - 唯一索引与非唯一索引

    MySQL 唯一索引和非唯一索引在性能方面有什么区别 假设我想在 2 列的组合上创建索引 并且该组合是唯一的 但我创建了一个非唯一索引 这会对 MySQL 使用的性能或内存产生重大影响吗 同样的问题 有区别吗primary钥匙和unique
  • PDO 和 IS NOT NULL 函数

    我是 PDO 新手 我想知道是否有相当于 mysql 语句的语句来检查参数是否不为空 例如 SELECT FROM table WHERE param IS NOT NULL 我试过这个 pdo gt prepare SELECT FROM
  • 如何使用 Laravel 查询生成器在 WHERE 条件周围添加括号

    我使用 Laravel 查询构建器根据用户的过滤器选择动态过滤数据 query DB table readings foreach selections as selection query gt orWhere id selection
  • MongoDB 聚合查询与 MySQL SELECT field1 FROM 表

    我对 MongoDB 完全陌生 想要比较 NoSQL 数据模型相对于关系数据库对应部分的查询性能 我将其写入 MongoDB shell Make 10 businesses Each business has 10 locations E

随机推荐

  • Visio 2007/2010 左侧"形状"窗口管理

    Visio 2007 2010 左侧 形状 窗口管理 Visio 打开后 通常窗口左侧会有一个 形状 面板 我们可以方便地从中选择需要的形状 有时为了获得更大的版面空间或者不小心关闭了形状面板 怎么把它重新调出来 我们可以从 视图 中把它找
  • 使用docker快速搭建服务器环境

    思路 将nginx mysql tomcat等环境打包为一个个docker 然后使用docker compose管理 服务器内安装docker相关环境 然后直接运行docker compose配置 即可快速搭建完成服务器环境 之后可以将相关
  • Markdown / KaTex数学公式汇总

    目录 LaTex和KaTex 软件推荐 Mathpix 一 如何插入公式 二 上下标 三 常用运算符 四 高级运算符 五 常用数学符号 六 特殊符号 6 1 箭头 6 2 公式序号 七 括号使用 八 矩阵 九 集合运算 十 希腊字母 十一
  • 使用反射实现动态修改@Excel的注解属性

    业务场景 我们使用poi实现数据导出时 通常是根据 Excel name xxx 来确定列名 通常情况下这个是不会发生变动的 但这里就说少数情况 在我们需要这里根据某些情况来进行改变的时候 我们就需要用到反射 AirQualityRanki
  • Java反射(自己的理解)

    动态语言 运行是代码可以根据某些条件改变自身结构 像js和php python等 但是我们不像c 是一门静态语言 可以准确的说我们是一门准动态语言 因为反射让我们具有动态性 我来直接用我所理解的反射给大家先讲一下大概 这绝对让你的耳目一新
  • 五、单向散列函数

    单向散列函数 获取消息的指纹 当需要比较两条消息是否一致时 我们不必直接对比消息本身的内容 只要对比它们的 指纹 就可以了 单向散列函数 one wayftnction 有一个输人和一个输出 其中输人称为消息 message 输出称为散列值
  • 全国大学生数字建模竞赛、中国研究生数学建模竞赛(数学建模与计算实验)前言

    1 什么是数学建模 2 所需要学的知识 知识算法分类表格汇总 3 所需要的软件工具 4 论文模板 查找文献 查找数据 一 什么是数学建模 全国大学生数字建模竞赛 National College Student Mathematical M
  • HashMap源码初探

    Hash table based implementation of the Map interface This implementation provides all of the optional map operations and
  • Qt动态库加载之 QLibrary

    目录 一 使用Qt编译C动态库 二 使用QLibrary调用共享库 一 使用Qt编译C动态库 使用Qt新建一个C项目 cbb frame 在项目中我们声明和定义两个函数 并导出函数 在cbb mylog中我们使用了函数指针 这里为啥这样干
  • python人脸识别考勤系统 dlib+OpenCV和Pyqt5、数据库sqlite 人脸识别系统 计算机 毕业设计 源码

    一 项目介绍 Python语言 dlib OpenCV Pyqt5界面设计 sqlite3数据库 本系统使用dlib作为人脸识别工具 dlib提供一个方法可将人脸图片数据映射到128维度的空间向量 如果两张图片来源于同一个人 那么两个图片所
  • hrformer

    High Resolution Transformer Copyright c 2021 Microsoft Licensed under The MIT License see LICENSE for details Written by
  • keepalived 实现双机热备

    文章目录 一 说明 二 概念解释 三 环境准备 四 操作过程 五 验证 一 说明 我们经常听说 nginx keepalived 双机热备 其实在这里 双机热备有两种思路 一是只利用 keepalived 实现两个节点的故障切换 当主节点挂
  • 章节二:Vue.js的安装和配置

    2 1 下载和安装Vue js 要下载和安装Vue js 你有几个选项可供选择 通过CDN 在HTML文件中引入Vue js的CDN链接 然后直接使用Vue全局变量 使用包管理器 使用npm或yarn等包管理器 在项目中安装Vue js 下
  • 一文搞懂IP基础以及子网划分!!!!!

    1 什么是IP地址 IP地址 Internet Protocol Address 互联网国际地址 是一种在Internet上的给主机编址的方式 它主要是为互联网上的每一个网络和每一台主机分配一个逻辑地址 以此来屏蔽物理地址的差异 IP地址就
  • Reactjs鼠标滚轮监听

    1 添加相应的react所需的包及插件 npm install react s npm install react dom s 2 鼠标滚轮事件及引用子组件的滚轮处理事件 handleWheel function event 判断鼠标滚轮的
  • JavaBean配置

    在JSP内嵌入大量的Java代码可能会造成维护不方便 为此最好的方就是把JSP代码和Java代码分开 将JSP中的Java代码移植到Java类中 这些可能用到的类就是JavaBean JavaBean实现步骤如下 1 在src中新建一个be
  • 微型计算机上的南桥芯片功能,微型计算机主板上安装的主要部件

    如下 1 芯片组 芯片组是构成主板电路的核心 决定了主板的级别和档次 北桥芯片是主板上最重要的芯片 主要负责与CPU 内存 显卡进行通讯 南桥芯片负责连接硬盘 USB 接口 PCI 接口等其他接口 南桥芯片和北桥芯片之间也有联系 2 存储控
  • 洋桃电子STM32物联网入门30步笔记三、CubeMX图形化编程、设置开发板上的IO口

    此文档作为对杨桃电子视频的整理 B站链接 第四集 一 开启RCC的外部时钟 包括外部高速时钟HSE和外部低速时钟LSE 时钟配置三个选项的含义 选择禁用的话就只能使用内部时钟 旁路时钟源一般是有源晶振 晶体与陶瓷振荡器一般是无源晶振 二 开
  • 利用JS获取IE客户端IP及MAC的实现

    在做B S结构的系统时 我们常常需要获取客户端的一些信息 如IP和MAC 以结合身份验证 在ASP NET中 要获取服务器端的MAC很容易 但是要获取客户端的MAC的地址确要花费一翻心思 通常的做法是调用Win32API或直接调用nbtst
  • MySQL技术内幕InnoDB存储引擎 学习笔记 第六章 锁

    锁是数据库系统区别于文件系统的一个关键特性 锁机制用于管理对共享资源的并发访问 InnoDB引擎会对表数据上锁以提供数据的完整性和一致性 除此之外 还会对数据库内部其他多个地方使用锁 从而保证对多种不同资源提供并发访问 如增删改LRU列表中