深入解析MySQL中的事务(下)

MySQL事务管理

    • 3. 隔离性(Isolation)
      • 查看和设置隔离级别
        • 隔离级别作用域区别与解析
      • 四种隔离级别解析
      • 小结
    • 4. 一致性(Consistency)
      • 如何保持一致性
    • 5.“保持原子性、隔离性、持久性就能保证一致性”的理解:
  • 四、如何理解隔离性
    • 1.数据库并发的场景有三种:
      • 读-写
    • MVCC(多版本并发控制)
      • 理解undo log
      • 模拟MVCC
        • 快照
        • 通过快照理解回滚(Rollback)

3. 隔离性(Isolation)

隔离性指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的隔离空间,一个事务的内部操作对其他事务都是不可见的。这样,事务之间就不可能产生干扰。MySQL中的事务隔离级别决定了事务之间的可见性和并发性能。

示例:考虑两个并发的转账事务,一个是账户A转账给账户B,另一个是账户C转账给账户D。由于事务的隔离性,这两个事务不会互相干扰。即使它们同时发生,一个事务也不会看到另一个事务的中间状态。例如,在账户A转账给账户B的过程中,即使账户B的余额已经增加(但事务尚未提交),账户C的事务也看不到这个更改。这样可以确保每个事务都在一个独立的环境中执行,从而避免了并发操作可能引起的数据不一致问题。

MySQL支持四种事务隔离级别:
READ UNCOMMITTED(读取未提交)
READ COMMITTED(读取已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(可串行化)

查看和设置隔离级别

在MySQL中,@@transaction_isolation@@session.transaction_isolation@@global.transaction_isolation(有时也被写作@@tx_isolation@@session.tx_isolation@@global.tx_isolation)是用于查看和设置事务隔离级别的系统变量。这些变量在MySQL中用于控制事务如何与其他事务进行隔离。
在这里插入图片描述

隔离级别作用域区别与解析
  1. @@transaction_isolation@@tx_isolation

这个变量通常是@@session.transaction_isolation的别名。当你不指定sessionglobal时,它通常指的是当前会话(session)的事务隔离级别。也就是说,它会返回你当前会话的事务隔离级别设置。

例如,如果你在一个会话中执行SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;,然后执行SELECT @@transaction_isolation;,你会得到与REPEATABLE READ隔离级别相对应的值。
在这里插入图片描述

  1. @@session.transaction_isolation@@session.tx_isolation

这个变量用于查看和设置当前会话的事务隔离级别。它只影响当前会话中的事务。如果你在一个会话中更改了这个值,它不会影响其他已经存在的会话或新创建的会话。
在这里插入图片描述

  1. @@global.transaction_isolation@@global.tx_isolation

这个变量用于查看和设置全局(即服务器级别)的事务隔离级别。当你更改这个值时,它会影响所有新创建的会话。但是,已经存在的会话的事务隔离级别不会改变,除非它们明确地被设置为与全局设置不同。
在这里插入图片描述
但是设置了全局并未影响会话隔离级别
在这里插入图片描述
真的是这样吗?(原来是要重新启动服务后下一次生效)
在这里插入图片描述
这样就合理多了!

tips:理解全局隔离级别和会话隔离级别将其当成全局变量和局部变量一样理解会好记很多!

四种隔离级别解析

  1. READ UNCOMMITTED(读未提交)
    • 定义:允许读取并发事务尚未提交的数据。
    • 数据一致性:最低。由于可以读取到其他事务未提交的数据,所以可能会出现脏读(Dirty Read)、不可重复读(Non-repeatable Read)和幻读(Phantom Read)的问题。
    • 并发性:最高。因为不需要对数据行进行加锁等待,所以可以提高并发性能。
    • 应用场景:很少使用,因为它提供的数据一致性太低。

创建两个会话,设置其隔离级别为读未提交——如下图
在这里插入图片描述
在两个终端各自启动一个事务,左终端中的事务所作的修改在没有提交之前,右终端中的事务就已经能够看到了。如下:
在这里插入图片描述

什么是脏读?怎么解决?

脏读(Dirty Read)

定义:一个事务读取了另一个尚未提交的事务的数据。如果另一个事务发生错误并执行了回滚操作,那么第一个事务读取到的数据就是脏数据。

示例

  1. 事务A修改了一行数据。

  2. 事务B读取了事务A修改后的数据。

  3. 事务A由于某种原因发生错误并执行了回滚操作,撤销了之前的修改。

  4. 此时事务B读取到的数据就是脏数据,因为它读取的是从未真正提交过的数据。
    在这里插入图片描述

  5. READ COMMITTED(读已提交)

    • 定义:对同一字段的多次读取结果都是一致的。但是,不同的事务之间可以读取到对方已经提交的数据。
    • 数据一致性:中等。解决了脏读的问题,但可能会出现不可重复读和幻读。
    • 并发性:较高。因为只需要等待其他事务提交,而不需要等待其完成。
    • 应用场景:这是大多数数据库系统的默认隔离级别(但不是MySQL的默认级别)。它提供了较好的数据一致性和并发性之间的平衡。

创建两个会话,设置其隔离级别为读提交——如下图
在这里插入图片描述
两个终端各自启动一个事务,左终端中的事务所作的修改在没有提交之前,右终端中的事务无法看到。如下在这里插入图片描述
与上述读未提交相比明显可以看出,其他会话并不能查看到修改(提交后才可以)在这里插入图片描述

一个事务在执行过程中,两个相同的select查询得到了不同的数据,这种现象叫做不可重复读。

  1. REPEATABLE READ(可重复读)
    • 定义:对同一字段的多次读取结果都是一致的。在一个事务中,对同一字段的多次读取结果都是相同的。
    • 数据一致性:较高。解决了脏读和不可重复读的问题,但可能会出现幻读(在InnoDB存储引擎中,通过多版本并发控制(MVCC)和Next-Key Locking策略,幻读也被解决了)。
    • 并发性:中等。因为需要对数据行进行加锁等待,所以并发性能会有所降低。
    • 应用场景:MySQL的InnoDB存储引擎的默认隔离级别。它提供了较高的数据一致性和相对较好的并发性能。

创建两个会话,设置其隔离级别为可重复读——如下图
在这里插入图片描述
同时启动事务后,左边终端进行数据更新,右端终端并不能查看到左端终端的修改(合理,这和读已提交一样)
在这里插入图片描述
左端终端结束事务,右端终端事务仍在继续,可以看到左端终端的提交的事务并不会让右端终端发生幻读(一个事务在执行过程中,相同的select查询得到了新的数据,如同出现了幻觉,这种现象叫做幻读。)现象
在这里插入图片描述
只有当右端事务完成事务,才会更新修改数据在这里插入图片描述
那两个终端同时启动事务,并对一条数据进行修改呢,因为是左端先执行,所以成功,而左端并没有结束提交事务,所以在右端同时对其进行修改的时候,并不能直接修改,而是被卡在修改数据这条指令上
在这里插入图片描述
长期的卡住会导致锁超时在这里插入图片描述
我们提交后则可以修改
在这里插入图片描述

  1. SERIALIZABLE(可串行化)
    • 定义:最高的隔离级别,也是完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就不可能产生干扰。
    • 数据一致性:最高。解决了脏读、不可重复读和幻读的问题。
    • 并发性:最低。因为事务需要排队执行,所以并发性能最差。
    • 应用场景:当对数据一致性要求非常高,且可以接受较低并发性能的场景下使用。

创建两个会话,设置其隔离级别为可串行化——如下图
在这里插入图片描述
在两个终端各自启动一个事务,如果这两个事务都对表进行的是读操作,那么这两个事务可以并发执行,不会被阻塞。如下:
在这里插入图片描述
但如果这两个事务中有一个事务要对表进行写操作,那么这个事务就会立即被阻塞(这里就与可重复读有区别)。如下:
在这里插入图片描述
超时会被这条操作会被杀掉
在这里插入图片描述
两个事务同时修改,左边先一点,右边后一点,则会执行时间靠前的,时间靠后的error在这里插入图片描述
事务提交后数据变得一致
在这里插入图片描述

tips:这里的锁有点类似于悲观锁,但是又有不同——
SERIALIZABLE(可串行化)中的锁和悲观锁在概念和应用上是有区别的

SERIALIZABLE是数据库事务的一个隔离级别,用于解决并发问题。当事务设置为SERIALIZABLE隔离级别时,所有的事务依次逐个执行,这样事务之间就不可能产生干扰。在这种隔离级别下,事务会对它所使用的资源(如行或表)进行加锁,以防止其他事务并发访问这些资源。但是,SERIALIZABLE隔离级别并不一定等同于悲观锁,因为具体的加锁策略可能因数据库管理系统的不同而有所差异。

悲观锁则是一种对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度的并发控制方式。它假设最坏的情况,即数据被并发修改的概率比较大,因此,在修改数据之前先加锁,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制,如行锁、表锁等。

总结来说,SERIALIZABLE隔离级别和悲观锁都是为了解决并发问题而采用的策略,但它们在实现方式、应用场景和效果上有所不同。SERIALIZABLE隔离级别是一种全局性的策略,通过串行化事务的执行来避免并发问题;而悲观锁则是一种具体的加锁策略,它假设数据被并发修改的概率较大,因此在修改数据之前先加锁。

  1. 默认的隔离级别

在mysql中,InnoDB的默认隔离级别可以重启mysql服务查看——为可重复读

sudo systemctl restart mysqld

在这里插入图片描述

小结

在这里插入图片描述

tips:

  • 隔离级别越严格,安全性越高,但数据库的并发性能也就越低,在选择隔离级别时往往需要在两者之间找一个平衡点。
  • 表中只写出了各种隔离级别下进行读操作时是否需要加锁,因为无论哪种隔离级别,只要需要进行写操作就一定需要加锁。

4. 一致性(Consistency)

事务(Transaction)是一个逻辑上独立的工作单位,它确保数据从一个一致性的状态转变到另一个一致性的状态。事务的一致性(Consistency)是事务ACID属性(Atomicity, Consistency, Isolation, Durability)中的一个关键部分。

一致性确保了数据库从一个一致性状态转变为另一个一致性状态。具体地说,它意味着:

  1. 数据的完整性:事务必须确保数据库中的数据和业务规则保持一致。例如,如果有一个规则规定一个账户的余额不能为负,那么任何导致余额为负的事务都必须被回滚(Rollback),以保持数据的一致性。
  2. 数据的完整性约束:数据库中的完整性约束(如主键约束、外键约束、唯一性约束等)必须在事务执行前后都得到满足。
  3. 数据的初始状态:如果事务由于某种原因(如系统崩溃)未能完成,那么数据库必须恢复到事务开始之前的状态,这确保了数据库的一致性。

如何保持一致性

  1. 预定义的业务规则:数据库和应用程序必须遵循预定义的业务规则来确保数据的一致性。这些规则可以是简单的(如确保余额不为负)或复杂的(如确保在多个表之间的数据关系保持一致)。
  2. 完整性约束:使用数据库的完整性约束(如主键、外键、唯一性约束等)可以帮助自动维护数据的一致性。
  3. 事务管理:DBMS使用事务管理来确保数据的一致性。如果事务中的某个操作失败,那么整个事务都会被回滚,数据库将恢复到事务开始之前的状态。
  4. 并发控制:并发事务可能导致数据不一致。DBMS使用各种并发控制机制(如锁、时间戳等)来防止这种情况的发生。
  5. 数据备份和恢复:定期备份数据库并在需要时恢复数据是确保数据一致性的重要手段。如果数据库因某种原因变得不一致,可以使用备份来恢复到一致的状态。

一致性指的是事务必须使数据库从一个一致性状态变换到另一个一致性状态。也就是说,一个事务执行之前和执行之后都必须处于一致性状态。这种一致性状态是指数据库的完整性约束没有被破坏,数据的语义没有改变。

示例:考虑一个在线购物系统,用户在购买商品时需要扣除库存并更新用户的订单状态。这个操作涉及两个表:一个是商品库存表(products),另一个是用户订单表(orders)。在事务开始之前,商品库存表中的库存数量与用户订单表中的订单状态都是一致的。在事务执行过程中,我们需要先减少库存表中的库存数量,然后更新用户订单表中的订单状态为已购买。如果这两个操作都成功执行,那么事务结束后数据库的状态仍然是一致的。但是,如果其中任何一个操作失败(例如,由于网络问题或系统错误),那么我们需要回滚事务,以保持数据库的一致性。

5.“保持原子性、隔离性、持久性就能保证一致性”的理解:

  • 这四个属性是事务的基本特性,它们共同确保了数据库系统的可靠性和稳定性。
  • 原子性确保了事务要么全部完成,要么全部不完成,这为实现一致性提供了基础。
  • 隔离性保证了事务之间不会互相干扰,从而确保了在并发环境下的一致性。
  • 持久性确保了事务的结果在提交后是永久性的,这也有助于维护数据的一致性。
  • 然而,仅仅保证原子性、隔离性和持久性并不足以完全确保一致性。还需要在数据库设计时定义正确的数据完整性约束和业务规则,并在事务中遵守这些规则和约束,以确保数据的一致性。

四、如何理解隔离性

经过上述实验,发现隔离性好像简而言之就是并发环境中,多个事务之间应该相互独立,一个事务的执行不应该影响其他事务。换句话说,当多个事务并发执行时,每个事务都应该感觉自己是在单独执行,不受其他事务的干扰。但是数据库底层又是如何保证的呢?

1.数据库并发的场景有三种:

  • 读-读 :不存在任何问题,也不需要并发控
  • 读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
  • 写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

读-写

多版本并发控制( MVCC )是一种用来解决 读-写冲突 的无锁并发控制为事务分配单向增长的事务ID,为每个修改保存一个版本,版本与事务ID关联,读操作只读该事务开始前的数据库的快照。 所以 MVCC 可以为数据库解决以下问题在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题
理解 MVCC 需要知道三个前提知识:

  • 3个记录隐藏字段
  • undo 日志
  • Read View
    3个记录隐藏列字段
  • DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录创建这条记录/最后一次修改该记录的事务ID
  • DB_ROLL_PTR : 7 byte,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一般在 undo log 中)
  • DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB 会自动以 DB_ROW_ID 产生一个聚簇索引
  • 补充:实际还有一个删除flag隐藏字段, 既记录被更新或删除并不代表真的删除,而是删除flag变了

示例

在这里插入图片描述
比如我们存在上述表,则上述表表达的意思为
在这里插入图片描述
我们目前并不知道创建该记录的事务ID,隐式主键,我们就默认设置成null,1。第一条记录也没有其他版本,我们设置回滚指针为null。

MVCC(多版本并发控制)

MVCC(Multi-Version Concurrency Control),即多版本并发控制,是一种并发控制的方法,主要用于数据库管理系统中实现对数据库的并发访问。

  1. 核心思想:MVCC允许在数据库系统中存在数据的多个版本,从而允许多个用户或事务同时访问数据库而不会产生冲突。通过为每个事务提供一个数据快照,每个事务都可以看到数据的一个一致性的视图,而不管其他事务正在进行的修改。
  2. 工作原理
    • 当一个事务启动时,系统会为其分配一个唯一的事务ID。
    • 当事务要访问数据库中的某个数据时,系统会检查该数据的版本号和事务的启动时间。如果该数据的版本号早于该事务的启动时间,则该事务可以访问该数据;否则,该事务需要等待其他事务完成对该数据的访问。
    • 当事务修改数据时,系统会为该数据创建一个新版本,并将修改后的数据存储在新的位置。同时,旧版本的数据仍然可用供其他事务访问。
    • 当事务提交时,系统会将其所做的所有修改操作合并到数据库中,并删除旧版本的数据(或标记为可删除)。
  3. 优点
    • 提高并发访问数据库的效率:由于每个事务都访问数据的独立版本,因此多个事务可以并发执行而不会相互阻塞。
    • 减少数据冲突和不一致性的发生:由于每个事务都看到数据的一个一致性的快照,因此不会出现脏读、不可重复读或幻读等问题。
  4. 实现方式:不同的数据库系统可能采用不同的方式来实现MVCC。例如,在MySQL的InnoDB存储引擎中,MVCC是通过为每个数据行添加额外的隐藏字段(如创建时间和删除时间戳)来实现的。这些字段用于跟踪行的版本和状态。

总的来说,MVCC是一种用于提高数据库并发性能和减少数据冲突的技术。它允许在并发环境中存在数据的多个版本,并通过为每个事务提供数据快照来确保事务之间的一致性和隔离性。

理解undo log

Undo log(撤销日志)是数据库管理系统中的一种重要机制,特别是在MySQL等关系型数据库中。以下是关于Undo log的详细解释:

  1. 定义与作用
  • Undo log,顾名思义,是一种用于撤销或回退的日志。其主要作用是记录事务回滚前的数据状态,以便在需要时能够进行数据恢复,保证数据的一致性和完整性。当事务进行修改操作时(如插入、更新或删除),数据库系统会先将修改前的数据状态记录到Undo log中。如果事务需要回滚或者系统发生故障需要恢复数据,就可以利用Undo log中的信息来撤销之前的操作或恢复到某个一致的状态。
  1. 组成部分
  • Undo log通常包含以下几个关键部分:事务ID(用于标识进行修改的事务)、操作类型(如插入、更新、删除等)、被修改的数据内容以及操作发生的时间戳。
  1. 存储位置
  • Undo log存在于一个特殊的段中,这个段被称为Undo log segment(撤销日志段),它通常位于数据库系统的表空间中。具体来说,在MySQL中,Undo log默认存放在共享表空间中,但也可以通过配置来指定其存放位置。每行数据通常都会有一个指向其对应Undo log的指针,以便在需要时能够快速定位并恢复数据。

总的来说,Undo log是数据库管理系统中确保数据一致性和完整性的重要机制之一。它通过记录事务修改前的数据状态,为数据恢复和事务回滚提供了可能。

简而言之:undo log -> 回滚日志,用于对已经执行的操作进行回滚,保证事务的原子性。

模拟MVCC

现在有一个事务10(仅仅为了好区分),对student表中记录进行修改(update):将name(张三)改成name(李四)。

  • 事务10,因为要修改,所以要先给该记录加行锁。
  • 修改前,现将改行记录拷贝到undo log中,所以,undo log中就有了一行副本数据。(原理就是写时拷贝)
  • 所以现在 MySQL 中有两行同样的记录。现在修改原始记录中的name,改成 ‘李四’。并且修改原始记录的隐藏字段 DB_TRX_ID 为当前 事务10 的ID, 我们默认从 10 开始,之后递增。而原始记录的回滚指针 DB_ROLL_PTR 列,里面写入undo log中副本数据的地址,从而指向副本记录,既表示我的上一个版本就是它。
  • 事务10提交,释放锁。
    在这里插入图片描述
    tips: 此时,最新的记录是’李四‘那条记录。

现在又有一个事务11,对student表中记录进行修改(update):将age(28)改成age(38)。

  • 事务11,因为也要修改,所以要先给该记录加行锁。(该记录是那条?)
  • 修改前,现将改行记录拷贝到undo log中,所以,undo log中就又有了一行副本数据。此时,新的副本,我们
    采用头插方式,插入undo log。
  • 现在修改原始记录中的age,改成 38。并且修改原始记录的隐藏字段 DB_TRX_ID 为当前 事务11 的ID。而原始记录的回滚指针 DB_ROLL_PTR 列,里面写入undo log中副本数据的地址,从而指向副本记录,既表示我的上一个版本就是它。
  • 事务11提交,释放锁。
    在这里插入图片描述

这样,我们就有了一个基于链表记录的历史版本链。所谓的回滚,无非就是用历史数据,覆盖当前数据。
上面的一个一个版本,我们可以称之为一个一个的快照。

快照

在MVCC(Multi-Version Concurrency Control,多版本并发控制)中,快照是指数据库中数据的一个特定时间点的视图。这个快照版本是在事务开始时创建的,用于为事务提供所需的一致性视图。

具体来说,当一个事务开始时,数据库系统会根据该事务开始的时间点为该事务创建一个快照版本。通过使用这个快照版本,MVCC提供了每个事务的一致性视图,使得事务能够在并发执行时保持隔离性,避免了读取脏数据或互相覆盖的问题。每个事务都能够看到在其开始之前已经提交的数据版本,从而保证了数据的一致性和事务的隔离性。

在MVCC中,数据的多版本是通过隐藏列或元数据来跟踪的。这些隐藏列或元数据包含了数据的版本信息,例如创建时间戳、删除时间戳等。通过这些信息,数据库系统可以确定哪些数据版本对于当前事务是可见的。

需要注意的是,不同数据库系统的MVCC实现可能会有所不同,但其核心原理和目标都是类似的。通过创建快照版本和基于快照版本的并发控制,MVCC提供了一种高效且并发安全的方法来处理数据库事务的并发访问。

通过快照理解回滚(Rollback)
  1. 快照的定义:快照是关于指定数据集合的一个完全可用拷贝,这个拷贝包含了数据在某个时间点(拷贝开始的时间点)的映像。它可以是数据的副本或复制品。
  2. 快照的作用:快照的主要作用之一是进行在线数据备份与恢复。当存储设备发生应用故障或者文件损坏时,可以使用快照来进行快速的数据恢复,将数据恢复到快照创建时的状态。
  3. 回滚的定义:回滚是指程序或数据处理错误时,将程序或数据恢复到上一次正确状态的行为。在数据库系统中,回滚通常用于撤销事务中的更改,将数据库恢复到事务开始之前的状态。
  4. 快照与回滚的关系:通过快照,我们可以保存数据库在某个时间点的状态。如果后续发现数据出现了错误或者需要进行回滚操作,我们可以选择将数据库回滚到之前某个快照的状态,从而撤销在快照之后所做的更改。

具体来说,假设我们有一个数据库系统,并且定期为该数据库创建快照。在某个时间点,我们执行了一个事务,但由于某种原因,该事务导致了数据错误。此时,我们可以选择将数据库回滚到该事务执行之前的某个快照的状态,从而撤销该事务所做的更改,恢复数据的正确性。

因此,通过快照,我们可以为数据库提供多个时间点的备份状态。当需要进行回滚操作时,我们可以选择将数据库回滚到这些备份状态之一,从而恢复数据的正确性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图论专题训练

leecode 547 并查集 class Solution { public:int findCircleNum(vector<vector<int>>& isConnected) {ini();int len isConnected.size();for(int i0;i<len;i){for(int j0;j<len;j)if(isConnected[i][j]){unio(i,j);}}int ans 0;for(int i0;i<len;…

自动驾驶技术与传感器数据处理

目录 自动驾驶总体架构 感知系统 决策系统 定位系统 ​计算平台​ 仿真平台​ 自动驾驶公开数据集 激光点云 点云表征方式 1) 原始点云 2) 三维点云体素化 3)深度图 4)鸟瞰图 点云检测障碍物的步骤 PCL点云库 车载毫米波雷达 车载相机 设备标定 自动驾驶…

python选修课期末考试复习

目录 记住输出小数的格式文件条件判断随想循环小星星计算金额猜数字折纸 函数找最大值 基础知识总结 记住输出小数的格式 输出a&#xff0c;保留两位小数 %.2f%a打开文件有点儿难&#xff0c;多记几遍格式吧 文件的格式后面有冒号&#xff0c;谨慎一点&#xff0c;都用双引号…

花了24小时做的采购、库存、进销存excel模板,真心好用,免费分享

花了24小时做的采购、库存、进销存excel模板&#xff0c;真心好用 在企业的日常运营中&#xff0c;进销存管理是一项至关重要的任务。它不仅涉及到商品的采购、销售和库存管理&#xff0c;还直接影响到企业的财务状况和市场竞争力。为了提高管理效率&#xff0c;许多企业选择使…

字典是如何实现的?Rehash 了解吗?

字典是 Redis 服务器中出现最为频繁的复合型数据结构。除了 hash 结构的数据会用到字典外&#xff0c;整个 Redis 数据库的所有 key 和 value 也组成了一个 全局字典&#xff0c;还有带过期时间的 key 也是一个字典。(存储在 RedisDb 数据结构中) 字典结构是什么样的呢&#xf…

loongarch64 electron打包deb改成符合统信测试通过的deb

需要做软件适配统信系统的自主认证。 我之前是在 麒麟 龙芯 loongarch64 电脑上使用 electron 打包的 deb包&#xff1a;麒麟龙芯loongarch64 electron 打包deb包_electron麒麟系统打包的-CSDN博客 安装在统信电脑 处理器&#xff1a;Loongson-3A60000-HV 2.5GHz 可以使用&…

陪玩系统APP小程序H5音视频社交系统陪玩系统源码,陪玩app源码,陪玩源码搭建陪玩社交系统开发(现成,可定制)线下陪玩系统项目开发搭建

线下陪玩系统项目的设计 在需求分析完成后&#xff0c;接下来进行系统设计。系统设计主要包括以下几个部分&#xff1a; 1. 数据库设计&#xff1a;根据需求分析的结果&#xff0c;设计数据库结构&#xff0c;包括用户信息表、服务信息表、订单信息表等。 2. 界面设计&#…

Git在windows和Linux安装并自动更新代码超详细讲解

一、Git官网安装 1、官网安装地址&#xff1a; Git - Downloading Packagehttps://git-scm.com/download/win 官网下载比较慢建议使用下面链接 2、国内镜像下载地址&#xff1a; CNPM Binaries Mirrorhttps://registry.npmmirror.com/binary.html?pathgit-for-windows/ 3、…

【mysql篇】执行delete删除大量数据后,磁盘未清空,为什么?

目录 迁移脚本删除数据以及备份数据 解决方法OPTIMIZE TABLE二进制日志按月生成数据 最近某个项目虽说用户量不大&#xff0c;但是&#xff0c;单表的数据量越来越大&#xff0c;mysql一般单表超过千万级别后&#xff0c;性能直线下降&#xff0c;所以利用shardingphere按月做了…

c语言柔性数组

柔性数组 在c99中&#xff0c;结构体的最后一个元素允许是未知大小的数组&#xff0c;这个就是柔性数组 柔性数组的特点 1.结构体中的柔性数组成员前面必须至少有一个其他成员 2.sizeof返回的这种结构大小不包括柔性数组的内存 3.包含柔性数组成员的结构用malloc()函数进行内存…

C++11:常用语法汇总

目录 &#x1f341;统一的列表初始化 { }initializer_list &#x1f341;decltype 推导表达式类型&#x1f341;可变参数模板解析可变参数包方法一方法二 &#x1f341;lambda 表达式捕捉列表的使用运用场景举例lambda表达式 与 函数对象 &#x1f341;统一的列表初始化 { } 在…

8个免费无版权视频素材网站,高清无水印视频任性下载

在数字化时代&#xff0c;优质的视频素材成为各种项目不可缺少的元素&#xff0c;从短片制作到商业广告&#xff0c;高品质的视频能显著提高作品的吸引力和传播效果。然而&#xff0c;寻找既免费又无版权问题的高清视频素材并非易事。以下介绍几个优秀的免费视频素材网站&#…

基于YOLOV8复杂场景下船舶目标检测系统

1. 背景 海洋作为地球上70%的表面积&#xff0c;承载着人类生活、经济发展和生态系统的重要功能。船舶作为海洋活动的主要载体之一&#xff0c;在海上运输、资源开发、环境监测等方面发挥着重要作用。复杂海洋环境下的船舶目标检测成为了海事管理、海洋资源开发和环境保护等领…

嵌入式全栈开发学习笔记---C语言笔试复习大全17

目录 指针和字符串 用数组和指针定义字符串 两种定义方法有什么区别&#xff1f; 第一个区别&#xff1a; 第二个区别&#xff1a; 第三个区别&#xff1a; 指针数组 上一篇复习了指针和数组,这一篇我们来复习指针和字符串。 说明&#xff1a;我们学过单片机的一般都是有…

(Java)心得:LeetCode——18.四数之和

一、原题 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a; …

【智能算法应用】基于果蝇算法-BP回归预测(FOA-BP)

目录 1.算法原理2.数学模型3.结果展示4.代码获取 1.算法原理 【智能算法应用】智能算法优化BP神经网络思路【智能算法】果蝇算法&#xff08;FOA&#xff09;原理及实现 2.数学模型 数据集样本特征数为13&#xff0c;适应度函数设计为&#xff1a; f i t n e s s e r r o…

推荐我常用的爬虫工具,三种爬虫方式,搞定反爬和动态页面

我和很多学python的同学聊过&#xff0c;至少有30%以上的人学Python是为了网络爬虫&#xff0c;也就是采集网站的数据&#xff0c;不得不说这确实是一个刚性需求。 但一个残酷的事实是&#xff0c;即使一部分人学了Python&#xff0c;掌握了requests、urllib、bs4等爬虫技术&a…

JUC下的Java java.util.concurrent.Locks详解

java.util.concurrent.locks 包介绍 java.util.concurrent.locks 包是Java并发编程中非常重要的一个部分&#xff0c;它提供了比内置synchronized关键字更为灵活的锁机制&#xff0c;用于多线程环境下的同步控制。这个包中最核心的是Lock接口&#xff0c;以及一系列实现类&…

整理好的中债国债3年期到期收益率数据集(2002-2023年)

01、数据简介 国债&#xff0c;又称国家公债&#xff0c;是由国家发行的债券&#xff0c;是中央ZF为筹集CZ资金而发行的一种ZF债券&#xff0c;是中央ZF向投资者出具的、承诺在一定时期支付利息和到期偿还本金的债权债务凭证。 中债&#xff0c;是指由中国中债登记结算有限责…

【ROS2】功能包

文章目录 ROS2 功能包创建功能包编译功能包设置环境变量功能包的结构C 功能包结构Python 功能包结构 参考链接 ROS2 功能包 在 ROS2 工作空间的 src 目录下进行编写的文件并不是普通的文件&#xff0c;而是被称作功能包。 创建功能包 Usage: ros2 pkg create --build-type …