MySQL学习记录(9)InnoDB存储引擎

news2024/12/26 17:33:30

文章目录

  • 6、InnoDB存储引擎
    • 6.1、逻辑存储结构
    • 6.2、架构
      • 6.2.1、概述
      • 6.2.2、内存结构
      • 6.2.3、磁盘结构
      • 6.2.4、后台线程
    • 6.3、事务原理
      • 6.3.1、事务基础
      • 6.3.2、redo log日志
      • 6.3.3、undo log日志
    • 6.4、MVCC
      • 6.4.1、基本概念
      • 6.4.2、记录中隐藏字段
      • 6.4.3、undo log日志
      • 6.4.4、readview
      • 6.4.5、MVCC实现原理

6、InnoDB存储引擎

6.1、逻辑存储结构

InnoDB的逻辑存储结构如下图所示:

  1. Tablespace表空间(ibd文件):一个mysql实例可以对应多个表空间,用于存储记录、索引等数据
  2. Segment段:分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段 (Rollback segment),InnoDB是索引组织表,数据段就是B+树的叶子节点, 索引段即为B+树的非叶子节点。段用来管理多个Extent(区)。
  3. Extent区:表空间的单元结构,每个区的大小为1M。 默认情况下, InnoDB存储引擎页大小为16K, 即一 个区中一共有64个连续的页。
  4. Page页:是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。为了保证页的连续性,InnoDB 存储引擎每次从磁盘申请 4-5 个区。
  5. Row行:InnoDB 存储引擎数据是按行进行存放的。在行中,默认有两个隐藏字段:
  • Trx_id:每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。
  • Roll_pointer:每次对某条引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个 隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。

6.2、架构

6.2.1、概述

MySQL5.5 版本开始,默认使用InnoDB存储引擎,它擅长事务处理,具有崩溃恢复特性,在日常开发 中使用非常广泛。下面是InnoDB架构图,左侧为内存结构,右侧为磁盘结构。

6.2.2、内存结构

在左侧的内存结构中,主要分为这么四大块儿: Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer。接下来介绍一下这四个部分。

1). Buffer Pool

InnoDB存储引擎基于磁盘文件存储,访问物理硬盘和在内存中进行访问,速度相差很大,为了尽可能 弥补这两者之间的I/O效率的差值,就需要把经常使用的数据加载到缓冲池中,避免每次访问都进行磁盘I/O。

在InnoDB的缓冲池中不仅缓存了索引页和数据页,还包含了undo页、插入缓存、自适应哈希索引以及 InnoDB的锁信息等等。

缓冲池 Buffer Pool,是主内存中的一个区域,里面可以缓存磁盘上经常操作的真实数据,在执行增 删改查操作时,先操作缓冲池中的数据(若缓冲池没有数据,则从磁盘加载并缓存),然后再以一定频 率刷新到磁盘,从而减少磁盘IO,加快处理速度。

缓冲池以Page页为单位,底层采用链表数据结构管理Page。

根据状态,将Page分为三种类型:

  • free page:空闲page,未被使用。
  • clean page:被使用page,数据没有被修改过。
  • dirty page:脏页,被使用page,数据被修改过,也中数据与磁盘的数据产生了不一致。

2). Change Buffer

Change Buffer,更改缓冲区(针对于非唯一二级索引页),在执行DML语句时,如果这些数据Page没有在Buffer Pool中,不会直接操作磁盘,而会将数据变更存在更改缓冲区Change Buffer 中,在未来数据被读取时,再将数据合并恢复到Buffer Pool中,再将合并后的数据刷新到磁盘中。

与聚集索引不同,二级索引通常是非唯一的,并且以相对随机的顺序插入二级索引。同样,删除和更新可能会影响索引树中不相邻的二级索引页,如果每一次都操作磁盘,会造成大量的磁盘IO。有了 ChangeBuffer之后,我们可以在缓冲池中进行合并处理,减少磁盘IO。

3). Adaptive Hash Index

自适应hash索引,用于优化对Buffer Pool数据的查询。MySQL的innoDB引擎中虽然没有直接支持 hash索引,但是给我们提供了一个功能就是这个自适应hash索引。

因为前面我们讲到过,hash索引在进行等值匹配时,一般性能是要高于B+树的,因为hash索引一般只需要一次IO即可,而B+树,可能需 要几次匹配,所以hash索引的效率要高,但是hash索引又不适合做范围查询、模糊匹配等。

InnoDB存储引擎会监控对表上各索引页的查询,如果观察到在特定的条件下hash索引可以提升速度, 则建立hash索引,称之为自适应hash索引。

自适应哈希索引,无需人工干预,是系统根据情况自动完成。

参数: adaptive_hash_index

4). Log Buffer Log Buffer:

日志缓冲区,用来保存要写入到磁盘中的log日志数据(redo log 、undo log), 默认大小为 16MB,日志缓冲区的日志会定期刷新到磁盘中。

如果需要更新、插入或删除许多行的事 务,增加日志缓冲区的大小可以节省磁盘 I/O。

参数: innodb_log_buffer_size:

缓冲区大小 innodb_flush_log_at_trx_commit:日志刷新到磁盘时机,取值主要包含以下三个:

​ 1: 日志在每次事务提交时写入并刷新到磁盘,默认值。

​ 0: 每秒将日志写入并刷新到磁盘一次。

​ 2: 日志在每次事务提交后写入,并每秒刷新到磁盘一次。

6.2.3、磁盘结构

1). System Tablespace

系统表空间是更改缓冲区的存储区域。如果表是在系统表空间而不是每个表文件或通用表空间中创建 的,它也可能包含表和索引数据。(在MySQL5.x版本中还包含InnoDB数据字典、undolog等)

参数:innodb_data_file_path

系统表空间,默认的文件名叫 ibdata1。

2). File-Per-Table Tablespaces

如果开启了innodb_file_per_table开关 ,则每个表的文件表空间包含单个InnoDB表的数据和索引 ,并存储在文件系统上的单个数据文件中。 开关参数:

innodb_file_per_table ,该参数默认开启。

3). General Tablespaces

通用表空间,需要通过 CREATE TABLESPACE 语法创建通用表空间,在创建表时,可以指定该表空 间。

A. 创建表空间

CREATE TABLESPACE ts_name ADD DATAFILE 'file_name' ENGINE = engine_name;

B. 创建表时指定表空间

CREATE TABLE xxx ... TABLESPACE ts_name;

4). Undo Tablespaces 撤销表空间

MySQL实例在初始化时会自动创建两个默认的undo表空间(初始大小16M),用于存储 undo log日志。

5). Temporary Tablespaces

InnoDB 使用会话临时表空间和全局临时表空间。存储用户创建的临时表等数据。

6). Doublewrite Buffer Files

双写缓冲区,innoDB引擎将数据页从Buffer Pool刷新到磁盘前,先将数据页写入双写缓冲区文件中,便于系统异常时恢复数据。

7). Redo Log

重做日志,是用来实现事务的持久性。

该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者在磁盘中。

当事务提交之后会把所有修改信息都会存到该日志中, 用于在刷新脏页到磁盘时,发生错误时, 进行数据恢复使用。 以循环方式写入重做日志文件,涉及两个文件:

在这里插入图片描述

6.2.4、后台线程

在这里插入图片描述

在InnoDB的后台线程中,分为4类,分别是:Master Thread 、IO Thread、Purge Thread、 Page Cleaner Thread。

1). Master Thread

核心后台线程,负责调度其他线程,还负责将缓冲池中的数据异步刷新到磁盘中, 保持数据的一致性, 还包括脏页的刷新、合并插入缓存、undo页的回收 。

2). IO Thread

在InnoDB存储引擎中大量使用了AIO来处理IO请求, 这样可以极大地提高数据库的性能,而IO Thread主要负责这些IO请求的回调。

线程类型默认个数职责
Read thread4负责读操作
Write thread4负责写操作
Log thread1负责将日志缓冲区刷新到磁盘
Insert buffer thread1负责将写缓冲区内容刷新到磁盘

我们可以通过以下的这条指令,查看到InnoDB的状态信息,其中就包含IO Thread信息。

show engine innodb status;

3). Purge Thread

主要用于回收事务已经提交了的undo log,在事务提交之后,undo log可能不用了,就用它来回收。

4). Page Cleaner Thread

协助 Master Thread 刷新脏页到磁盘的线程,它可以减轻 Master Thread 的工作压力,减少阻塞。

6.3、事务原理

6.3.1、事务基础

1). 事务

事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。

2). 特性

原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。

一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。

隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环 境下运行。

持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

实际上,我们研究事务的原理,就是研究MySQL的InnoDB引擎是如何保证事务的这四大特性的。

而对于这四大特性,实际上分为两个部分。

其中的原子性、一致性、持久化,实际上是由InnoDB中的两份日志来保证的,一份是redo log日志,一份是undo log日志。

而隔离性是通过数据库的锁, 加上MVCC来保证的。

在这里插入图片描述

6.3.2、redo log日志

重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性

该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file) 前者是在内存中,后者在磁盘中,当事务提交之后会把所有修改都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据恢复使用。

我们知道,在InnoDB引擎中的内存结构中,主要的内存区域就是缓冲池,在缓冲池中缓存了很多的数 据页。 当我们在一个事务中,执行多个增删改的操作时,InnoDB引擎会先操作缓冲池中的数据,如果 缓冲区没有对应的数据,会通过后台线程将磁盘中的数据加载出来,存放在缓冲区中,然后将缓冲池中 的数据修改,修改后的数据页我们称为脏页。 而脏页则会在一定的时机,通过后台线程刷新到磁盘 中,从而保证缓冲区与磁盘的数据一致。 而缓冲区的脏页数据并不是实时刷新的,而是一段时间之后 将缓冲区的数据刷新到磁盘中,假如刷新到磁盘的过程出错了,而提示给用户事务提交成功,而数据却 没有持久化下来,这就出现问题了,没有保证事务的持久性。

在这里插入图片描述

有了redo log之后,当对缓冲区的数据进行增删改之后,会首先将操作的数据页的变化,记录在redo log buffer中。在事务提交时,会将redo log buffer中的数据刷新到redo log磁盘文件中。 过一段时间之后,如果刷新缓冲区的脏页到磁盘时,发生错误,此时就可以借助于redo log进行数据 恢复,这样就保证了事务的持久性。 而如果脏页成功刷新到磁盘 或 或者涉及到的数据已经落盘,此时redo log就没有作用了,就可以删除了,所以存在的两个redo log文件是循环写的

在这里插入图片描述

那为什么每一次提交事务,要刷新redo log 到磁盘中呢,而不是直接将buffer pool中的脏页刷新 到磁盘呢 ?

因为在业务操作中,我们操作数据一般都是随机读写磁盘的,而不是顺序读写磁盘。 而redo log在 往磁盘文件中写入数据,由于是日志文件,所以都是顺序写的。顺序写的效率,要远大于随机写。 这 种先写日志的方式,称之为 WAL(Write-Ahead Logging)。

6.3.3、undo log日志

回滚日志,用于记录数据被修改前的信息 , 作用包含两个 : 提供回滚(保证事务的原子性) 和 MVCC(多版本并发控制) 。

undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的 update记录。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

Undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。

Undo log存储:undo log采用段的方式进行管理和记录,存放在前面介绍的 rollback segment 回滚段中,内部包含1024个undo log segment。

6.4、MVCC

6.4.1、基本概念

当前读:读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁

快照读:简单的select(不加锁)就是快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读

MVCC:全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本, 使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需 要依赖于数据库记录中的三个隐式字段、undo log日志、readView。

6.4.2、记录中隐藏字段

InnoDB会自动的给我们添加三个隐藏字段:

隐藏字段含义
DB_TRX_ID最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID。
DB_ROLL_PTR回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版 本。
DB_ROW_ID隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。

6.4.3、undo log日志

(1)介绍

回滚日志,在insert、update、delete的时候产生的便于回滚的日志

当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。

而update、delete的时候,,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除

(2)undo log版本链

不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条 记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

有一张表原始数据为:

在这里插入图片描述

DB_TRX_ID : 代表最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID,是 自增的。

DB_ROLL_PTR : 由于这条数据是才插入的,没有被更新过,所以该字段值为null。

有四个并发事务同时在访问这张表。

在这里插入图片描述

当事务2执行第一条修改语句时,会记录undo log日志,记录数据变更之前的样子; 然后更新记录, 并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。

在这里插入图片描述

当事务3执行第一条修改语句时,也会记录undo log日志,记录数据变更之前的样子; 然后更新记 录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本

当事务4执行第一条修改语句时,也会记录undo log日志,记录数据变更之前的样子; 然后更新记 录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本。

在这里插入图片描述

6.4.4、readview

ReadView(读视图)是快照读SQL执行时MVCC提取数据的依赖,记录并维护系统当前活跃的事务(未提交的)id。

ReadView中包含了四个核心字段:

字段含义
m_ids当前活跃的事务ID集合
min_trx_id最小活跃事务ID
max_trx_id预分配事务id,当前最大事务ID+1(因为事务的自增的)
creator_trx_idReadView创建者的事务ID

而在readview中就规定了版本链数据的访问规则:

trx_id 代表当前undolog版本链对应事务ID。

条件是否可以访问说明
trx_id == creator_trx_id可以访问该版本成立,说明数据是当前这个事务更改的。
trx_id < min_trx_id可以访问该版本成立,说明数据已经提交了。
trx_id > max_trx_id不可以访问该版本成立,说明该事务是在 ReadView生成后才开启。
min_trx_id <= trx_id <= max_trx_id如果trx_id不在m_ids中, 是可以访问该版本的成立,说明数据已经提交。

不同的隔离级别,生成ReadView的时机不同:

READ COMMITTED :在事务中每一次执行快照读时生成ReadView。

REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

6.4.5、MVCC实现原理

(1)RC隔离级别下,在事务中国每一次执行快照读时生成ReadView

我们就来分析事务5中,两次快照读读取数据,是如何获取数据的? 在事务5中,查询了两次id为30的记录,由于隔离级别为Read Committed,所以每一次进行快照读 都会生成一个ReadView,那么两次生成的ReadView如下。

那么这两次快照读在获取数据时,就需要根据所生成的ReadView以及ReadView的版本链访问规则, 到undolog版本链中匹配数据,最终决定此次快照读返回的数据。

第一次快照读:

在这里插入图片描述

在进行匹配时,会从undo log的版本链,从上到下进行挨个匹配

先匹配 trx_id为4的这条数据,也就是将4带入右侧的匹配规则中。 ①不满足 ②不满足 ③不满足 ④也不满足 , 都不满足,则继续匹配undo log版本链的下一条。

再匹配第二条 ,这条记录对应的trx_id为3,也就是将3带入右侧的匹配规则中。①不满足 ②不满足 ③不满足 ④也不满足 ,都不满足,则继续匹配undo log版本链的下一条

再匹配第三条 ,这条记 录对应的trx_id为2,也就是将2带入右侧的匹配规则中。①不满足 ②满足 终止匹配,此次快照 读,返回的数据就是版本链中记录的这条数据。

第二次快照读:

在这里插入图片描述

在进行匹配时,会从undo log的版本链,从上到下进行挨个匹配:

先匹配 trx_id为4的数据,也就是将4带入右侧的匹配规则中。 ①不满足 ②不满足 ③不满足 ④也不满足 , 都不满足,则继续匹配undo log版本链的下一条。

再匹配第二条 ,这条记录对应的trx_id为3,也就是将3带入右侧的匹配规则中。①不满足 ②满足 。终止匹配,此次 快照读,返回的数据就是版本链中记录的这条数据。

(2)在RR隔离级别下,仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

而RR 是可 重复读,在一个事务中,执行两次相同的select语句,查询到的结果是一样的。

在这里插入图片描述

我们看到,在RR隔离级别下,只是在事务中第一次快照读时生成ReadView,后续都是复用该 ReadView,那么既然ReadView都一样, ReadView的版本链匹配规则也一样, 那么最终快照读返 回的结果也是一样的。

所以呢,MVCC的实现原理就是通过 InnoDB表的隐藏字段、UndoLog 版本链、ReadView来实现的。 而MVCC + 锁,则实现了事务的隔离性。 而一致性则是由redolog 与 undolog保证。

在这里插入图片描述

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

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

相关文章

【Pytorch项目实战】之图像分类与识别:手写数字识别(MNIST)、普适物体识别(CIFAR-10)

文章目录图像分类与识别&#xff08;一&#xff09;实战&#xff1a;基于CNN的手写数字识别&#xff08;数据集&#xff1a;MNIST&#xff09;&#xff08;二&#xff09;实战&#xff1a;基于CNN的图像分类&#xff08;数据集&#xff1a;CIFAR-10&#xff09;图像分类与识别 …

Lua 函数 - 可变参数

Lua 函数 - 可变参数 参考至菜鸟教程。 Lua函数可以接收可变数目的参数&#xff0c;和C语言类似&#xff0c;在函数参数列表中使用三点...表示函数有可变的参数。 function add(...) local s 0 for i, v in ipairs{...} do --> {...} 表示一个由所有变长参数构成的数…

模拟实现C库函数(2)

"烦恼无影踪,丢宇宙~"上一篇的模拟实现了好几个库函数,strlen\strcpy\memcpy\memmove,那么这一篇又会增加几个常用C库函数的模拟实现 memset\itoa\atoi。一、memsetmemset - fill memory with a constant byte#include <string.h>void *memset(void *s, int c,…

机器自动翻译古文拼音 - 十大宋词 - 江城子·乙卯正月二十日夜记梦 苏轼

江城子乙卯正月二十日夜记梦 宋苏轼 十年生死两茫茫&#xff0c;不思量&#xff0c;自难忘。 千里孤坟&#xff0c;无处话凄凉。 纵使相逢应不识&#xff0c;尘满面&#xff0c;鬓如霜。 夜来幽梦忽还乡&#xff0c;小轩窗&#xff0c;正梳妆。 相顾无言&#xff0c;惟有泪千…

uniapp使用及踩坑项目记录

环境准备 下载 HBuilderX 使用命令行创建项目&#xff1a; 一些常识准备 响应式单位rpx 当设计稿宽度为750px的时&#xff0c;1rpx1px。 uniapp中vue文件style不用添加scoped 打包成h5端的时候自动添加上去&#xff0c;打包成 微信小程序端 不需要添加 scoped。 图片的…

SpringDataJpa set()方法自动保存失效

问题描述&#xff1a;springdatajpa支持直接操作对象设置属性进行更新数据库记录的方式&#xff0c;正常情况下&#xff0c;get()得到的对象直接进行set后&#xff0c;即使不进行save操作&#xff0c;也将自动更新数据记录&#xff0c;将改动持久化到数据库中&#xff0c;但这里…

20230126使AIO-3568J开发板在原厂Android11下跑起来

20230126使AIO-3568J开发板在原厂Android11下跑起来 2023/1/26 18:22 1、前提 2、修改dts设备树 3、适配板子的dts 4、&#xff08;修改uboot&#xff09;编译系统烧入固件验证 前提 因源码是直接使用原厂的SDK&#xff0c;没有使用firefly配套的SDK源码&#xff0c;所以手上这…

Linux安装mongodb企业版集群(分片集群)

目录 一、mongodb分片集群三种角色 二、安装 1、准备工作 2、安装 configsvr配置 router配置 shard配置 三、测试 四、整合Springboot 一、mongodb分片集群三种角色 router角色&#xff1a; mongodb的路由&#xff0c;提供入口&#xff0c;使得分片集群对外透明&…

【目标检测论文解读复现NO.27】基于改进YOLOv5的螺纹钢表面缺陷检测

前言此前出了目标改进算法专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读最新目标检测算法论文&#xff0c;…

【工程化之路】Node require 正解

require 实现原理 流程概述 步骤1&#xff1a;尝试执行代码require("./1"). 开始调用方法require.步骤2&#xff1a;此时会得到filename&#xff0c;根据filename 会判断缓存中是否已经加载模块&#xff0c;如果加载完毕直接返回&#xff0c;反之继续执行步骤3&…

python图像处理(laplacian算子)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 和之前的prewitt算子、sobel算子不同,laplacian算子更适合检测一些孤立点、短线段的边缘。因此,它对噪声比较敏感,输入的图像一定要做好噪声的处理工作。同时,laplacian算子设计…

Leetcode 03. 无重复字符的最长子串 [C语言]

目录题目思路1代码1结果1思路2代码2结果2该文章只是用于记录考研复试刷题题目 Leetcode 03: 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所…

尚医通-OAuth2-微信登录接口开发(三十一)

目录&#xff1a; &#xff08;1&#xff09;微信登录-OAuth2介绍 &#xff08;2&#xff09;前台用户系统-微信登录-准备工作 &#xff08;3&#xff09;微信登录-生成微信二维码-接口开发 &#xff08;4&#xff09;微信登录-生成验证码-前端整合 &#xff08;5&#xf…

Telerik DevCraft Ultimate R1 2023

Telerik DevCraft Ultimate R1 2023 Kendo UI R1 2023-添加新的Chip和ChipList组件。 KendoReact R1 2023&#xff08;v5.11.0&#xff09;-新的PDFViewer组件允许用户直接在应用程序中查看PDF文档。 Telerik JustLock R1 2023-Visual Studio快速操作菜单现在可以在创建通用…

蓝桥杯重点(C/C++)(随时更新,更新时间:2023.1.29)

点关注不迷路&#xff0c;欢迎推荐给更多人 目录 1 技巧 1.1 取消同步&#xff08;节约时间&#xff0c;甚至能多骗点分&#xff0c;最好每个程序都写上&#xff09; 1.2 万能库&#xff08;可能会耽误编译时间&#xff0c;但是省脑子&#xff09; 1.3 蓝桥杯return 0…

【数据库-通用知识系列-01】数据库规范化设计之范式,让数据库表看起来更专业

我们在设计数据库时考虑的因素包括读取性能&#xff0c;数据一致性&#xff0c;数据冗余度&#xff0c;可扩展性等&#xff0c;好好学习数据库规范化的知识&#xff0c;设计的数据库表看起来才专业。 范式一览 “键”理解&#xff1a; 超键&#xff1a;在关系中能唯一标识元组…

送什么礼物给小学生比较有纪念意义?适合送小学生的小礼物

送给小学生的礼物哪种比较有意义呢&#xff1f;送给学生的礼物&#xff0c;基本上是对学习有所帮助的&#xff0c;但是像送钢笔、练习册这些&#xff0c;有一部分学生是抗拒的&#xff0c;作为大人就是希望对视力、对成长有用的东西&#xff0c;我认为保护视力是现在许多家庭的…

isNotEmpty() 和 isNotBlank() 的区别,字符串判空, StringUtils工具包 StringUtil工具类,isEmpty() 和 isBlank() 的区别

目录1.StringUtils 和 StringUtilStringUtils 的依赖&#xff1a;StringUtils 的用法&#xff1a;StringUtil 工具类2. isNotEmpty() 和 isNotBlank()1.StringUtils 和 StringUtil 注&#xff1a;StringUtils 和 StringUtil 的区别&#xff08;StringUtil为自定义工具类&#…

以表达式作为template参数

目录 一.template参数的分类&#xff1a; 二.非类型参数与默认参数值一起使用 三.应用 一.template参数的分类&#xff1a; ①.某种类型&#xff1a; template<typename T>; ②.表达式(非类型)&#xff1a; template<int length,int position>; 其中length…

Liunx中shell命令行和权限的理解

文章目录前言1.shell外壳的理解2.关于权限理解1.Linux下的用户2.角色划分3.文件和目录的权限3.粘滞位3.总结前言 Linux中的操作都是通过在命令行上敲指令来实现的&#xff0c;本文将简单的介绍Linux中的外壳程序shell以及浅谈一下对Linux中的权限理解。 1.shell外壳的理解 Lin…