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

MySQL索引和事务

一.索引

1.作用

索引可以理解为数据库表中数据的目录,就像书籍的目录能让你快速找到想要的内容一样,数据库索引能帮助数据库系统快速定位到表中符合查询条件的数据行,从而显著减少数据库的查询时间,提高查询性能。

CREATE INDEX idx_name ON table_name (column_name);
DROP INDEX idx_name ON table_name;

2.案例 

案例一:普通索引提高查询效率

场景描述:

假设有一个电商系统的订单表 orders,该表存储了大量的订单信息,其中包含 order_date 列,业务中经常需要根据订单日期进行查询。

- 创建订单表
CREATE TABLE orders (order_id INT PRIMARY KEY AUTO_INCREMENT,customer_id INT,order_date DATE,total_amount DECIMAL(10, 2)
);- 插入一些示例数据
INSERT INTO orders (customer_id, order_date, total_amount)
VALUES 
(1, '2024-01-01', 100.00),
(2, '2024-01-02', 200.00),
(3, '2024-01-03', 300.00);- 未创建索引时执行查询,使用 EXPLAIN 分析查询执行计划
EXPLAIN SELECT * FROM orders WHERE order_date = '2024-01-02';- 创建普通索引
CREATE INDEX idx_order_date ON orders (order_date);- 创建索引后再次执行查询并分析
EXPLAIN SELECT * FROM orders WHERE order_date = '2024-01-02';

分析 :

  • 未创建索引时,数据库可能需要进行全表扫描来查找符合条件的记录,效率较低。
  • 创建索引后,数据库可以利用索引快速定位到 order_date 为 2024-01-02 的记录,减少了查询时间。

二.事务 

在 MySQL 里,事务是一组不可分割的数据库操作序列,这些操作要么全部成功执行,要么全部不执行,以此保证数据的一致性和完整性。 

1.事务的控制语句

  • start transaction:用于显式地开始一个事务。
  • commit:提交事务,将事务中所有的操作结果永久保存到数据库中。
  • roll back:回滚事务,撤销事务中所有未提交的操作,使数据库恢复到事务开始前的状态。
  • save point:在事务中设置一个保存点,允许部分回滚事务。
  • rollback to savepoint:将事务回滚到指定的保存点

2.案例 

2.1 案例一:银行转账

场景描述:

在银行系统中,转账操作涉及从一个账户扣款并向另一个账户存款,这两个操作必须作为一个整体执行,要么都成功,要么都失败,以保证账户余额的一致性。

-- 创建账户表
CREATE TABLE accounts (account_id VARCHAR(10) PRIMARY KEY,balance DECIMAL(10, 2)
);-- 插入示例数据
INSERT INTO accounts (account_id, balance)
VALUES ('A', 1000.00), ('B', 2000.00);-- 开启事务
START TRANSACTION;-- 从账户 A 扣除 100 元
UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A';-- 模拟可能出现的错误,例如网络中断等
-- 可以在这里添加条件判断,如果出现错误则回滚事务-- 向账户 B 存入 100 元
UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B';-- 提交事务
COMMIT;-- 如果出现错误,使用 ROLLBACK 回滚事务
-- ROLLBACK;-- 查看转账后的账户余额
SELECT * FROM accounts;

分析: 

此事务将两个更新操作封装在一起,确保在转账过程中,若任何一个操作失败(如数据库故障、网络问题),整个事务会回滚,保证账户 A 和账户 B 的总金额不变

2.2 案例二:库存管理

场景描述:

在电商系统中,当用户下单购买商品时,需要同时减少商品库存和增加订单记录。这两个操作必须同时成功,否则会出现数据不一致的情况。

-- 创建商品表
CREATE TABLE products (product_id INT PRIMARY KEY,product_name VARCHAR(100),stock INT
);-- 创建订单表
CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMARY KEY,product_id INT,quantity INT
);-- 插入示例数据
INSERT INTO products (product_id, product_name, stock)
VALUES (1, 'Product A', 10);-- 开启事务
START TRANSACTION;-- 减少商品库存
UPDATE products SET stock = stock - 2 WHERE product_id = 1;-- 模拟可能出现的错误
-- 例如,库存不足的情况可以在这里进行判断,如果库存不足则回滚事务-- 增加订单记录
INSERT INTO orders (product_id, quantity) VALUES (1, 2);-- 提交事务
COMMIT;-- 如果出现错误,使用 ROLLBACK 回滚事务
-- ROLLBACK;-- 查看更新后的商品库存和订单记录
SELECT * FROM products;
SELECT * FROM orders;

分析: 

  • 该事务保证了商品库存的减少和订单记录的增加是一个原子操作。若在减少库存后,插入订单记录时出现错误,事务会回滚,库存数量会恢复到原来的值。

2.3 案例三:使用保存点进行部分回滚

场景描述:

在一个复杂的业务操作中,可能需要对多个表进行更新,当其中某个操作出现问题时,希望能部分回滚到之前的某个状态,而不是整个事务都回滚

-- 创建表
CREATE TABLE table1 (id INT PRIMARY KEY,value VARCHAR(50)
);CREATE TABLE table2 (id INT PRIMARY KEY,value VARCHAR(50)
);CREATE TABLE table3 (id INT PRIMARY KEY,value VARCHAR(50)
);-- 插入示例数据
INSERT INTO table1 (id, value) VALUES (1, 'value1');
INSERT INTO table2 (id, value) VALUES (1, 'value2');
INSERT INTO table3 (id, value) VALUES (1, 'value3');-- 开启事务
START TRANSACTION;-- 更新 table1
UPDATE table1 SET value = 'new_value1' WHERE id = 1;-- 设置保存点
SAVEPOINT my_savepoint;-- 更新 table2
UPDATE table2 SET value = 'new_value2' WHERE id = 1;-- 模拟 table2 更新后出现错误
-- 假设出现错误,需要回滚到保存点
ROLLBACK TO my_savepoint;-- 继续更新 table3
UPDATE table3 SET value = 'new_value3' WHERE id = 1;-- 提交事务
COMMIT;-- 查看更新后的表数据
SELECT * FROM table1;
SELECT * FROM table2;
SELECT * FROM table3;

分析: 

 通过设置保存点 my_savepoint,当 table2 更新出现问题时,可以回滚到保存点,table1 的更新操作仍然保留,然后继续执行 table3 的更新操作,最后提交事务,实现了部分回滚的功能

http://www.xdnf.cn/news/3683.html

相关文章:

  • 接口测试的核心思维(基础篇)
  • Java 中如何实现自定义类加载器,应用场景是什么?
  • 如何快速有效学习数字社会学AI社会学,抓住网络社会学知识图谱,数字社会学50个核心概念
  • Hal库下备份寄存器
  • 字母异位词分组(中等)
  • 继承【Java版】详细讲解
  • 虚幻引擎入门笔记
  • 山东大学计算机组成与设计第七章习题解析
  • Nginx — 防盗链配置
  • 深度学习核心架构:探明四种基础神经网络
  • 从基础到实践(三十六):RTC时钟芯片的应用
  • 多线程系列三:这就是线程的状态?
  • 什么是生成式 AI (GenAI)?
  • 强化学习--2.数学
  • 摩尔缠论课程合集完整版核心课程前置课程圈子问答星球圈子摩尔缠论三个阶段
  • redis延时队列详细介绍
  • Dart和Go语言特征对比
  • 接上篇,解决FramePack启动报错:“httpx.ReadError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。“的问题
  • 关于项目中优化使用ConcurrentHashMap来存储锁对象
  • 【C语言练习】019. 使用结构体数组存储复杂数据
  • 【unity游戏开发入门到精通——UGUI】整体控制一个UGUI面板的淡入淡出——CanvasGroup画布组组件的使用
  • 基于D-Mixer与TransXNet的YOLOv8改进—融合全局-局部特征与空间降维注意力机制的CNN-ViT混合架构
  • 三、shell脚本--运算符与表达式:让脚本学会“思考”
  • 高中数学联赛模拟试题精选学数学系列第4套几何题
  • 数据的存储
  • Python表达式全解析:从基础到高级
  • 开源项目实战学习之YOLO11:ultralytics-cfg-models-nas(十)
  • C++的内存
  • 深入探索 AAC 编码原理与 ADTS 格式:音频世界的智慧结晶
  • PCIe | TLP 报头 / 包格式 / 地址转换 / 配置空间 / 寄存器 / 配置类型