Mysql如何完成数据的增删改查(详解从0到1)

前言: 

      Mysql可能是每个程序员的必修课,可以说是使用起来是没有什么问题的,但是作为一名合格的程序猿,深入学习Mysql的内部工作原理是非常有必要的,主要是理解和学习Mysql的底层思想,希望在日后如遇到一些"搜索"操作,能够举一反三!!

        接下来可能会先去探索整个数据库的工作流程,后续会再说明其中的一些细节,例如INNODB、MYISUM等搜索引擎~

Mysql的存储数据:

创建数据库:

        当我们使用create创建一个数据库,此时对应的在磁盘上会生成一个以该数据库命名的文件夹,如下:

        

每创建一个数据库,此处的文件就多一个。当然该数据库的相关配置信息也会被记录在一个例如后缀为.ibd的文件中

        我们默认上述创建的数据库选用的是INNODB引擎,并配用UTF-8mb4的字符集。

  • 元数据存储
  • 系统表更新:MySQL 会在系统数据库(主要是 mysql 数据库和 information_schema 数据库)的相关表中记录新数据库的元数据。
    • 在 information_schema.SCHEMATA 表中,会新增一条记录,包含数据库的名称、默认字符集、默认排序规则等信息。例如,使用 CREATE DATABASE test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 创建数据库时,这些字符集和排序规则信息会被准确记录。
    • mysql.db 表也会更新,存储与该数据库相关的权限信息,确保后续可以对数据库的访问权限进行管理。

  • 数据字典更新:数据字典是 MySQL 存储数据库元数据的重要组成部分,它会同步更新新数据库的元数据信息,为后续数据库对象的管理和操作提供基础。

上图展示的是用户特殊的数据库权限(数据库级别),下图是可以登录mysql的所有用户,与用户相关权限(全局级别):

  • 文件系统操作:MySQL 会在文件系统中创建一个与数据库同名的目录,用于存储该数据库下的所有对象,如表、索引等。例如,创建名为test_db的数据库,在文件系统的数据库存储目录下会生成一个test_db目录。不同存储引擎可能还会在该目录下创建一些特定的文件用于存储数据和索引等。如 InnoDB 存储引擎的独立表空间模式下,每个表会有一个.ibd文件存储在该数据库目录下。

(一般是每个表都有自己的.idb的文件,前提是使用INNODB搜索引擎)

查找数据库:

         当我们数据库创建结束后,当我们想使用数据库时一般是需要查看当前有哪些数据库,一般使用show databases语句。

        此是mysql书如何完成扫描所有数据库的呢?

        分为以下五步:

  • 查询解析:MySQL 服务器接收到SHOW DATABASES语句后,首先对其进行词法分析和语法分析。词法分析将语句分解为一个个的单词,如SHOWDATABASES等,语法分析则检查语句是否符合 MySQL 的语法规则。如果语句语法有误,服务器会返回错误信息。
  • 权限检查:在执行查询之前,MySQL 会检查当前用户是否具有查看数据库列表的权限。只有具有相应权限的用户才能执行SHOW DATABASES操作。如果用户没有足够的权限,服务器将拒绝执行该查询,并返回权限不足的错误信息。
  • 元数据获取:MySQL 会从系统表中获取数据库的元数据信息。这些元数据存储在系统数据库(通常是mysql数据库)的相关表中,例如mysql.db表或information_schema.SCHEMATA表。mysql.db表存储了数据库的授权信息等,information_schema.SCHEMATA表提供了关于数据库的各种元数据,包括数据库名称、创建时间、字符集等。MySQL 通过查询这些系统表来获取所有数据库的相关信息。
  • 结果集生成:根据从系统表中获取的元数据信息,MySQL 生成包含所有数据库名称的结果集。结果集中的每一行对应一个数据库,通常只包含数据库名称这一列信息。
  • 结果返回:将生成的结果集返回给客户端。如果是在命令行中执行SHOW DATABASES,结果会以表格的形式显示在终端上;如果是通过编程语言中的 MySQL 客户端库执行该语句,结果会以相应编程语言的数据结构形式返回,供程序进一步处理。

以上的操作都是围绕着mysql.idb相关文件中的内容进行查找的,至于是不是以遍历的方式进行查找的,这是不一定的,一般是根据索引的方式查找~~ (与存储时选定的搜索引擎有关)

创建数据表

        当我们创建完数据库之后,就可以开始创建该库中的相关表了,一般创建表会使用如下的sql语句:

        use 数据库;

        create table 表名 (字段名 字段类型(int bigint char varchar ...) 指定是否可以为空 指定是否自增 指定注解......)

 当我们创建完数据库,mysql会分以下三步进行:

  • 元数据记录
    • MySQL 会在系统表中记录新表的元数据信息。对于 InnoDB 存储引擎,会在 mysql.innodb_table_stats 和 information_schema.TABLES 等表中记录表的基本信息,如名称、创建时间、存储引擎、表空间等。
    • 同时,会在 information_schema.COLUMNS 表中记录表的列信息,包括列名、数据类型、约束条件等。
information_schema.TABLES
mysql.innodb_table_stats 
  • 存储引擎交互
    • 不同的存储引擎在创建表时的操作有所不同。以 InnoDB 为例,会为新表分配一个独立的表空间(如果开启了独立表空间模式),并创建对应的 .ibd 文件来存储表的数据和索引
    • 存储引擎会初始化数据结构,如创建 B+ 树索引结构(如果有索引定义),为后续的数据插入和查询操作做好准备。
  • 文件系统操作
    • MySQL 会在文件系统中执行相应的操作。对于 InnoDB 存储引擎,会在数据库目录下创建与表对应的 .ibd 文件。对于 MyISAM 存储引擎,会创建三个文件:.frm 文件存储表的定义,.MYD 文件存储表的数据,.MYI 文件存储表的索引。

查询数据表

        当输入:

SELECT * FROM users WHERE age > 18;

之后会发生什么?

1.检查缓存:

        首先Mysql也是向缓存中检查之前有没有同样的sql语句,如果有直接返回之前的结果,就不再进行下一步操作了。

 2.解析查询语句:

        检查下查询语句的语法是否有误,如果没与错误,会将关键字、查询条件解析出来发送给mysql服务器。

3.生成查询计划:

        服务器收到了客户端发来的解析过后的语法,MySQL 的查询优化器会根据表的索引情况、统计信息等,生成多个可能的查询执行计划,并评估每个计划的成本(如磁盘 I/O 次数、CPU 开销等),选择成本最低的执行计划。例如,如果 users 表的 age 列上有索引,优化器可能会选择使用该索引来加快查询速度。

4.执行查询计划:

  • 访问存储引擎:根据生成的查询执行计划,服务器调用相应的存储引擎(如 InnoDB、MyISAM 等)来执行具体的查询操作。存储引擎负责从磁盘或内存中读取数据,并根据查询条件进行过滤和排序。
  • 数据读取与过滤:存储引擎根据执行计划读取满足条件的数据行。例如,对于上述查询,存储引擎会扫描 users 表,找出 age 大于 18 的记录。如果使用了索引,存储引擎会利用索引快速定位到符合条件的记录,减少不必要的磁盘 I/O 操作。

5.返回结果:

  • 结果集处理:存储引擎将满足查询条件的数据行返回给服务器,服务器对这些数据进行进一步处理,如排序、分组、聚合等(如果查询语句中有相应的操作)。
  • 结果返回客户端:最后,服务器将处理好的结果集返回给客户端。客户端接收到结果后,会以合适的方式显示给用户。

查询计划的补充:

        查询计划是根据自身写的sql语句中的条件生成,如果查询计划中有引入索引列(前提是索引列生效),会生成较为快的查询方式,如果查询条件中没有引入索引列,则会根据默认的索引生成查询计划。

        此时涉及到索引,那么此处需要展开对索引的一些了解:

        索引的分类如下:

普通索引:

        作为普通索引的数据列,对该列中的数据没有其他要求,可以为空,也可以是重复的数据。

        SQL语句如下:

create table test_db (id int comment'主键id',
user_name varchar(20) comment'用户名称'
,age int comment'用户年龄', 
INDEX idx_name (user_name));

        此时如果在查询时存在索引作为查询条件,会生成较快的查询策略!!

唯一索引:

        作为唯一索引的数据列,该列中的数据不能有重复,但是数据可以为NULL。

        SQL语句如下:

create table product (id int COMMENT'主键id',
product_code varchar(20) COMMENT'产品id',
name varchar(20) COMMENT'产品名', 
UNIQUE INDEX product_id (product_code));

 主键索引:

        作为主键索引的数据列,该列必须为设置为主键,该列中的数据不能重复,不能为NULL。

        SQL语句如下:

CREATE TABLE orders (order_id INT PRIMARY KEY,customer_id INT,order_date DATE
);

全文索引:

        一般是将数据类型为test文本类型的数据列设置为全文索引,全文索引可以对大文本字段(如文章内容、评论等)进行分词处理,并建立索引,以支持高效的全文搜索。

        SQL语句如下:

CREATE TABLE articles (id INT,title VARCHAR(200),content TEXT,FULLTEXT INDEX idx_content (content)
);

联合索引:

        可以同时将多个列设置为索引,但是查询时,查询条件必须遵守最左前缀原则:

        SQL语句如下:

CREATE TABLE employees (id INT,first_name VARCHAR(50),last_name VARCHAR(50),INDEX idx_name (first_name, last_name)
);

    最左前缀原则:

     查询时,查询条件从左至右依次符合匹配作为索引列的索引顺序,否则索引失效:

当查询条件经常同时涉及多个列时,使用复合索引可以提高查询效率。例如 SELECT * FROM employees WHERE first_name = 'John' AND last_name = 'Doe';,如果 first_name 和 last_name 上有复合索引,查询会更快。    

执行查询计划补充:

        当筛选出最佳查询计划之后,这时候就需要将查询计划告诉搜索引擎,然后执行查询计划。 

此处涉及到相关的搜索引擎的概念,我们需要简单了解一下:

InnoDB:

        InnoDB是现在Mysql中默认的搜索引擎。特点如下:

        1.支持事务:确保了ACID(原子性、一致性、隔离性、持久性),保证了数据的完整性。

        2.支持行级锁:采用行级锁,在高并发的场景下,可以精细的对数据进行控制,减少了所冲突的概率。

        3.支持外键约束:可以通过外键建立表与表之间的关联关系,保证数据的参照完整性。

        4.聚簇索引:数据和索引存储在一起,以主键为索引结构,能快速查询主键相关的数据。(此处的聚簇索引中的索引必须是主键索引)

        此时肯定是有一些疑问的,普遍疑问如下:

InnoDB是如何支持事务的?

1.原子性:

        原子性指事务中的所有操作要么全部成功,要么全部失败回滚。InnoDB 主要利用 回滚日志(Undo Log) 来实现原子性

  • 记录操作:在执行事务中的每一个修改操作(如插入、更新、删除)之前,InnoDB 会将操作的逆操作记录到回滚日志中。例如,当执行一个删除操作时,回滚日志会记录被删除记录的原始数据;当执行一个更新操作时,回滚日志会记录更新前的数据值。
  • 回滚机制:如果事务在执行过程中出现错误或者用户手动发起回滚操作,InnoDB 会根据回滚日志中的信息,将数据恢复到事务开始之前的状态,保证事务中的所有操作都没有对数据库产生影响。

2.一致性;

        要求事务将数据库从一个一致状态转换到另一个一致状态。InnoDB 通过以下几种方式来协助实现一致性:

  • 事务隔离级别:不同的隔离级别可以防止不同类型的并发问题(如脏读、不可重复读、幻读),从而保证数据在事务执行前后的一致性。例如,可串行化隔离级别可以确保事务串行执行,避免并发问题。
  • 约束检查:在事务执行过程中,InnoDB 会检查数据是否满足数据库的约束条件,如主键约束、唯一约束、外键约束等。如果违反了这些约束,事务会被回滚,以保证数据的一致性。
  • 回滚和提交:通过回滚日志和提交机制,确保事务要么全部完成,要么全部撤销,从而维护数据库的一致性。

3.隔离性;

        隔离性保证多个事务并发执行时,彼此之间互不干扰。InnoDB 提供了四种事务隔离级别,通过 锁机制 和 多版本并发控制(MVCC) 来实现隔离性:

  • 锁机制
    • 共享锁(S 锁):多个事务可以同时对同一资源加共享锁,用于读操作,相互之间不冲突。例如,多个事务可以同时对一条记录加共享锁进行读取。(加了共享锁的资源,就不能再加排他锁(写锁)了!
    • 排他锁(X 锁):一个事务对资源加排他锁后,其他事务不能再对该资源加任何类型的锁,用于写操作。例如,一个事务对一条记录加排他锁后,其他事务不能对该记录进行读取或修改。
    • 意向锁:用于表示事务对某个资源(如表或行)有更高层次的锁需求,提高锁的管理效率。
  • 多版本并发控制(MVCC):MVCC 是 InnoDB 实现高并发的关键技术之一。它通过为每个数据行维护多个版本,使得读操作可以在不获取锁的情况下进行,从而避免了读写冲突。在 MVCC 中,读操作读取的是数据的快照版本,而写操作会创建新的数据版本。不同的隔离级别对 MVCC 的使用方式有所不同,例如,在可重复读隔离级别下,一个事务在执行期间看到的数据版本是一致的。 (后续有介绍)

隔离级别:

  • 读未提交(Read Uncommitted)
    • 描述:在该隔离级别下,事务可以读取到其他事务尚未提交的数据,这可能导致脏读。
    • 示例:事务 A 修改了一条记录但未提交,此时事务 B 可以读取到事务 A 修改后的值。如果事务 A 回滚,那么事务 B 读取到的数据就是无效的,即脏数据。
    • 特点:隔离级别最低,并发性能最高,但可能出现脏读、不可重复读和幻读等问题。
  • 读已提交(Read Committed)
    • 描述:事务只能读取到其他事务已经提交的数据,避免了脏读,但可能会出现不可重复读的情况。
    • 示例:事务 A 在两次读取同一数据之间,事务 B 修改并提交了该数据,那么事务 A 两次读取到的值可能不同。
    • 特点:可以避免脏读,但是在同一事务中多次读取相同数据时,可能会因为其他事务的提交而得到不同的结果,无法保证可重复读。
  • 可重复读(Repeatable Read)
    • 描述:在同一个事务中,多次读取同一数据时,得到的结果是一致的,它解决了脏读和不可重复读的问题,但可能会出现幻读。
    • 示例:事务 A 在读取某些数据后,事务 B 插入了一条符合事务 A 查询条件的新记录并提交,当事务 A 再次以相同条件查询时,会发现多了一条记录,就好像产生了幻觉一样。
    • 特点:默认的隔离级别,保证了事务在多次读取相同数据时的一致性,但对于新增数据的并发操作可能存在幻读问题。
  • 串行化(Serializable)
    • 描述:这是最高的隔离级别,它强制事务串行执行,即每个事务都必须等待前一个事务完成后才能执行,从而避免了所有的并发问题,包括脏读、不可重复读和幻读。
    • 示例:如果有多个事务同时对同一数据进行操作,在串行化隔离级别下,这些事务会按照顺序依次执行,就像在单线程环境中一样。
    • 特点:隔离级别最高,能确保数据的一致性,但并发性能最低,因为所有事务都只能串行执行,在高并发场景下可能会导致性能瓶颈。

多版本并发控制:

基本原理

  • MVCC 在每行数据后面添加了两个隐藏的列,分别是创建版本号删除版本号
  • 当一个事务插入一行数据时,会将当前系统的版本号(通常是一个递增的数字)写入创建版本号列。
  • 当事务更新或删除一行数据时,实际上并不是真正删除或立即更新数据,而是将当前系统版本号写入删除版本号列,并在当前行的位置插入一条新的数据记录(对于更新操作),新记录的创建版本号为当前系统版本号。

工作机制

  • 读操作:当一个事务进行读操作时,它只会读取创建版本号小于或等于当前事务版本号,且删除版本号大于当前事务版本号(或为空)的数据行。这样可以确保读取到的数据是在当前事务开始之前已经提交的数据,避免了读取到未提交的脏数据。
  • 写操作:写操作(插入、更新、删除)会创建新的版本记录,并更新相应的版本号。在更新或删除操作时,MVCC 会先检查要操作的数据行的当前版本号与事务的版本号是否一致,如果不一致,说明数据在其他事务中已经被修改,可能会导致冲突,这时就需要根据一定的策略来处理冲突,如回滚事务或进行重试等。

优点

  • 提高并发性能:读操作和写操作可以并发执行,不会因为读操作而阻塞写操作,也不会因为写操作而阻塞读操作,大大提高了数据库的并发处理能力。
  • 减少锁竞争:相比于基于锁的并发控制机制,MVCC 减少了锁的使用,从而降低了锁竞争带来的性能开销和死锁风险。

4.持久性:    

        持久性确保一旦事务提交,其对数据库的修改就会永久保存,即使在系统崩溃或故障的情况下也不会丢失。InnoDB 主要通过 重做日志(Redo Log) 来实现持久性:

  • 记录修改:在事务执行过程中,InnoDB 会将对数据页的修改操作记录到重做日志中。重做日志采用顺序写入的方式,性能较高。
  • 崩溃恢复:当系统崩溃后重启时,InnoDB 会根据重做日志中的记录,将未完成的事务对数据库的修改重新应用到数据页上,从而保证数据的持久性。

        综上所述,InnoDB 通过回滚日志、锁机制、多版本并发控制和重做日志等技术,实现了事务的 ACID 特性,为数据库的可靠性和一致性提供了有力保障。

InnoDB通过聚簇索引为什么能够加快查询速度?工作原理?      

        原理:

        1.在聚簇索引中,数据页和索引页是紧密关联的。叶子节点包含了完整的数据行,而不仅仅是索引键和指针。这意味着当通过聚簇索引查找数据时,在找到索引节点的同时也就找到了对应的数据,无需再进行额外的磁盘 I/O 操作来获取数据,构建了一棵B+树

        2.并且叶子节点与相邻的叶子节点通过指针构成双向链表,再遍历也在子节点时也比较方便。

        示例:

        假设要查询一个具有聚簇索引的表中某一特定主键值的记录。数据库引擎会从聚簇索引的根节点开始搜索,通过比较索引值逐步向下导航到叶子节点,而叶子节点直接存储了对应的数据行,这样可以快速获取到所需的数据。

        

insert相关插入:

        通过sql语句,其中的insert语句是插入语句,如果一张表存在,我们可以通过insert语句插入数据到mysql或类似的sql型数据库中。

        那么从用户输入sql到数据存储到数据库整个流程是怎样的呢?

1.语法检查:mysql首先是会检查语法是否有误。

2.权限检查:当语法检查的过关以后,就会进入权限的检查

3.解析并优化:将sql语句解析为内部的数据结构,并且根据条件进行语句的优化。(Insert优化较少)

4.存储引擎处理:根据最开始选择的存储引擎执行解析后的语句,若当前语句是放在事务中执行的,遵循ACID特性。进行锁机制、多版本并发控制的处理

5.索引更新:若数据表中存在索引,则将索引结构进行更新。

6.写入日志:为了方便后期进行事务的回滚(UNDO LOG)或者系统崩溃后恢复(REDO LOG)。

7.提交或回滚:

  • 事务提交:若当前会话处于事务中,并且执行了 COMMIT 语句,那么插入操作会被永久保存到数据库中。
  • 事务回滚:若执行了 ROLLBACK 语句,插入操作会被撤销,数据库会恢复到插入操作之前的状态。

delete删除操作:

        delete删除操作与insert操作是类似的,这里不做重复的解释了!!

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

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

相关文章

单片机嵌入式按键库

kw_btn库说明 本库主要满足嵌入式按键需求,集成了常用的按键响应事件:高电平、低电平、上升沿、下降沿、单击、双击、长按键事件。可以裸机运行,也可以配合实时操作系统运行。 本库开源连接地址:连接 实现思路 本库采用C语言进行…

Qt—鼠标移动事件的趣味小程序:会移动的按钮

1.项目目标 本次根据Qt的鼠标移动事件实现一个趣味小程序:当鼠标移动到按钮时,按钮就会随机出现在置,以至于根本点击不到按钮。​​​​​ 2.项目步骤 首先现在ui界面设计控件(也可以用代码的方式创建,就不多说了) 第一个按钮不需…

MySQL的information_schema在SQL注入中的关键作用与防御策略

目录 一、information_schema的核心价值 二、攻击利用场景与示例 1. 联合查询注入(Union-Based) 2. 报错注入(Error-Based) 3. 布尔盲注(Boolean Blind) 4. 时间盲注(Time-Based&#xff0…

c语言 关键字--目录

下面是详细介绍的链接 1.c语言 关键字 2.typedef 关键字 3.volatile 关键字 4.register 关键字 5.const关键字用法 6.extern关键字 7.sizeof关键字

python爬虫爬取网站图片出现403解决方法【仅供学习使用】

基于CSDN第一篇文章,Python爬虫之入门保姆级教程,学不会我去你家刷厕所。 这篇文章是2021年作者发表的,由于此教程,网站添加了反爬机制,有作者通过添加cookie信息来达到原来的效果,Python爬虫添加Cookies以…

docker创建一个centOS容器安装软件(以宝塔为例)的详细步骤

备忘:后续偶尔忘记了docker虚拟机与宿主机的端口映射关系,来这里查看即可: docker run -d \ --name baota \ --privilegedtrue \ -p 8888:8888 \ -p 8880:80 \ -p 8443:443 \ -p 8820:20 \ -p 8821:21 \ -v /home/www:/www/wwwroot \ centos…

linux 使用nginx部署ssl证书,将http升级为https

前言 本文基于:操作系统 CentOS Stream 8 使用工具:Xshell 8、Xftp 8 服务器基础环境: nginx - 请查看 linux 使用nginx部署vue、react项目 所需服务器基础环境,请根据提示进行下载、安装。 1.下载证书 以腾讯云为例&#x…

日常开发中,iOS 性能调优我们怎么做?

日常开发中,iOS 性能调优我们怎么做?聊聊我用过的几款工具 最近在给一个 iOS 视频类 App 做性能优化,过程中踩了不少坑,也用了一些不错的工具,今天就以一个开发者视角随便聊聊我在调试过程中的一些经验。 一、性能问…

Redis ⑨-Jedis | Spring Redis

Jedis 通过 Jedis 可以连接 Redis 服务器。 通过 Maven 引入 Jedis 依赖。 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><versi…

【人工智能】解锁AI潜能:LM Studio多模型并行运行DeepSeek与开源大模型的实践指南

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着大语言模型(LLM)的快速发展,LM Studio作为一款本地化部署工具,以其简单易用的图形化界面和强大的模型管理能力受到广泛关注。本文深…

Node.js面试题

一、什么是Node.js&#xff1f; Node.js 是一个开源的跨平台 JavaScript 运行时环境&#xff0c;允许开发者在服务器端运行 JavaScript 代码。它基于 Chrome 的 V8 JavaScript 引擎构建&#xff0c;能够高效地处理 I/O 操作&#xff0c;适合构建高性能的网络应用。 异步非阻塞&…

Playwright MCP 入门实战:自动化测试与 Copilot 集成指南

什么是 MCP&#xff1f; MCP&#xff08;Model Context Protocol&#xff09; 是一种为大语言模型&#xff08;LLM&#xff09;设计的协议&#xff0c;MCP充当 LLM 与实际应用之间的桥梁或“翻译器”&#xff0c;将自然语言转化为结构化指令&#xff0c;使得模型可以更精确、高…

达梦DM数据库安装步骤

文章目录 1、下载并解压缩2、安装DM数据库2.1 运行安装程序2.2 选择语言与时区2.3 安装向导2.4 许可证协议2.5 Key文件2.6 选择组件2.7 安装位置2.8 安装前小结2.9 安装过程2.10 已完成2.11 初始化 3、配置实例3.1选择操作方式3.2创建数据库模版3.3指定数据库目录3.4数据库标识…

电商双11美妆数据分析(2)

接下来用seaborn包给出每个店铺各个大类以及各个小类的销量销售额 关于性别 接下来考虑性别因素&#xff0c;了解各类产品在男性消费者中的销量占比 男士的销量基本来自于清洁类&#xff0c;其次是补水类。而这两类正是总销量中占比最高的两类。 非男士专用中&#xff0c;补水…

54.实现Trie(前缀树)

Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构&#xff0c;用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景&#xff0c;例如自动补全和拼写检查。 请你实现 Trie 类&#xff1a; Trie() 初始化前缀树对象。void insert(String wo…

Excel文件批量处理指南 | 用VBA一键操作文件夹所有工作簿

系列文章 Excel跨文件夹批处理黑科技 | 用VBA递归遍历所有子目录 目录 系列文章&#x1f4c1; Excel文件批量处理指南 | 用VBA一键操作文件夹所有工作簿一、场景痛点与解决方案二、核心代码架构解析1. 文件遍历引擎2. 安全打开机制3. 错误处理框架 三、7大实战应用场景场景1&a…

南京大学OpenHarmony技术俱乐部正式揭牌 仓颉编程语言引领生态创新

2025年4月24日&#xff0c;由OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;项目群技术指导委员会与南京大学软件学院共同举办的“南京大学OpenHarmony技术俱乐部成立大会暨基础软件与生态应用论坛”在南京大学仙林校区召开。 大会聚焦国产自主编程语言…

C++回调函数学习

C回调函数学习 遇到问题&#xff0c;要学习C回调函数 遇到问题&#xff0c;要学习C回调函数 来吧&#xff0c;直接看代码吧 共有4种方法&#xff0c;每种方法都有标识&#xff0c;对用的屏蔽和打开就可以使用 原文在这里&#xff1a; #include<iostream> #include<f…

PDF解析新范式:Free2AI工具实测

在数字化浪潮中,PDF文件已成为企业、政府及个人存储与传递信息的核心载体。然而,PDF内容的提取与处理始终是行业痛点——无论是合同解析、研究报告整理,还是大规模知识库构建,传统方法常面临效率低、成本高、准确率不足等问题。Free2AI基于智能体技术与大模型算力,为PDF内…

【JS逆向基础】WEB自动化

前言&#xff1a;随着互联网的发展&#xff0c;前端技术也在不断变化&#xff0c;数据的加载方式也不再是单纯的服务端渲染了。现在你可以看到很多网站的数据可能都是通过接口的形式传输的&#xff0c;或者即使不是接口那也是一些 JSON 的数据&#xff0c;然后经过 JavaScript …