MySQL杂项
MySQL杂项
前言
我觉得MySQL还有一些杂项 我觉得我要单独拿出一篇文章去说明一下 会很笼统
MySQL事务:
MySQL 事务(Transaction)是一组不可分割的数据库操作序列,这些操作要么全部成功执行,要么全部失败回滚,确保数据的一致性和完整性。
事务的四大特性(ACID)
- 原子性(Atomicity) :事务中的所有操作要么全部完成,要么全部不完成,不会停留在中间状态。
- 一致性(Consistency) :事务执行前后,数据库从一个一致状态转变为另一个一致状态(数据规则不被破坏)。
- 隔离性(Isolation) :多个事务并发执行时,彼此之间不会相互干扰,每个事务都感觉不到其他事务的存在。
- 持久性(Durability) :事务一旦提交,其修改会永久保存到数据库中,即使系统崩溃也不会丢失。
事务控制语句
-
开启事务
sqlSTART TRANSACTION; -- 或 BEGIN;
-
提交事务(所有操作生效)
sqlCOMMIT;
-
回滚事务(取消所有操作,回到事务开始前的状态)
sqlROLLBACK;
-
设置保存点(在事务中创建一个标记,可回滚到该点而不影响之前的操作)
sqlSAVEPOINT savepoint_name; -- 创建保存点 ROLLBACK TO savepoint_name; -- 回滚到指定保存点
PS:ka'qi
示例:转账操作
sql
-- 开启事务
START TRANSACTION;-- 步骤1:A账户减少100元
UPDATE account SET balance = balance - 100 WHERE id = 1;-- 步骤2:B账户增加100元
UPDATE account SET balance = balance + 100 WHERE id = 2;-- 检查操作是否正确,正确则提交
COMMIT;-- 如果出错,回滚所有操作
-- ROLLBACK;
事务隔离级别
MySQL 提供了 4 种隔离级别(默认是 REPEATABLE READ):
- READ UNCOMMITTED(读未提交):最低级别,可能读取到未提交的数据(脏读)。
- READ COMMITTED(读已提交):只能读取到已提交的数据,避免脏读,但可能出现不可重复读。
- REPEATABLE READ(可重复读):保证同一事务中多次读取的数据一致,避免不可重复读,但可能出现幻读(MySQL 中通过 MVCC 机制解决了幻读)。
- SERIALIZABLE(串行化):最高级别,完全隔离事务,避免所有并发问题,但性能最差。
设置隔离级别:
sql
-- 全局生效(需重启会话)
SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别名称;-- 当前会话生效
SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别名称;
注意事项
- 只有使用 InnoDB 存储引擎的表才支持事务,MyISAM 不支持。
- 事务默认是自动提交的(
AUTOCOMMIT=1
),开启事务后会临时关闭自动提交。 - 长时间未提交的事务可能导致锁等待,影响数据库性能。
MySQL视图
MySQL 视图(View)是一种虚拟表,它基于 SQL 查询结果构建,本身不存储实际数据,只保存查询定义。视图可以简化复杂查询、隐藏数据细节、提供数据安全性。
视图的特点
- 视图是虚拟表,不存储实际数据,数据来源于基础表
- 对视图的操作(增删改)会影响基础表(有一定限制)
- 视图可以简化复杂查询,将常用查询逻辑封装
视图的创建与修改
- 创建视图
sql
CREATE [OR REPLACE] VIEW 视图名 AS
SELECT 列1, 列2, ...
FROM 表名
[WHERE 条件]
[GROUP BY 分组]
[HAVING 条件];
- 示例
sql
-- 创建员工部门视图
CREATE OR REPLACE VIEW employee_dept AS
SELECT e.id, e.name AS employee_name, d.name AS dept_name,e.salary
FROM employees e
JOIN departments d ON e.dept_id = d.id
WHERE e.status = 1;
- 修改视图定义
sql
ALTER VIEW 视图名 AS
新的SELECT查询;
视图的使用
使用视图与使用普通表类似:
sql
-- 查询视图
SELECT * FROM employee_dept WHERE dept_name = '技术部';-- 过滤和排序
SELECT employee_name, salary
FROM employee_dept
WHERE salary > 5000
ORDER BY salary DESC;
视图的删除
sql
DROP VIEW [IF EXISTS] 视图名;
视图的限制
-
并非所有视图都可更新,以下情况无法更新:
- 包含
DISTINCT
、GROUP BY
、HAVING
子句 - 包含聚合函数(
SUM
、COUNT
等) - 包含
UNION
、UNION ALL
等集合操作 - 由多个表连接生成的视图
- 包含
-
视图依赖基础表结构,若基础表结构变更,可能导致视图失效
MySQL 存储引擎
MySQL 存储引擎是数据库底层用于管理数据存储、索引、事务等操作的核心组件,不同的存储引擎具有不同的特性,适用于不同的业务场景。以下是 MySQL 中常见的存储引擎及其特点:
一、常用存储引擎
1. InnoDB(MySQL 5.5+ 默认存储引擎)
-
核心特性:
- 支持 事务(ACID 特性),通过
COMMIT
、ROLLBACK
控制事务。 - 支持 行级锁 和 表级锁,并发性能优异(适合高并发写入场景)。
- 支持 外键约束,保证数据的参照完整性。
- 采用 聚簇索引 存储数据,索引和数据紧密关联,查询效率高。
- 支持 崩溃恢复(通过 redo log 和 undo log 实现)。
- 支持 事务(ACID 特性),通过
-
适用场景:
- 需要事务支持的业务(如电商订单、金融交易)。
- 高并发读写场景(如用户数据、商品信息)。
- 需要外键约束保证数据一致性的场景。
2. MyISAM
-
核心特性:
- 不支持事务 和 外键,设计简单。
- 只支持 表级锁,写入时会锁定整个表(并发写入性能差)。
- 支持 全文索引(MySQL 5.6 前仅 MyISAM 支持)。
- 存储文件包括
.frm
(表结构)、.MYD
(数据)、.MYI
(索引),可直接复制文件备份。 - 占用资源较少,读取性能较好。
-
适用场景:
- 只读或读写极少的场景(如日志表、静态数据)。
- 不需要事务的场景(如数据仓库报表)。
3. Memory(Heap)
-
核心特性:
- 数据存储在 内存 中,读写速度极快(适合临时数据)。
- 不支持事务和外键,重启 MySQL 后数据丢失。
- 支持 哈希索引(查询速度快,但不支持范围查询)和 B 树索引。
- 表大小受内存限制,且默认使用表级锁。
-
适用场景:
- 临时数据缓存(如会话数据、临时计算结果)。
- 对速度要求极高、数据可丢失的场景。
4. Archive
-
核心特性:
- 专门用于 归档数据,压缩比高(节省存储空间)。
- 只支持 INSERT 和 SELECT 操作,不支持 UPDATE、DELETE 和索引(除自增主键)。
- 适合存储大量历史数据(如日志、归档记录)。
-
适用场景:
- 日志存储、历史数据归档(如用户操作日志、系统运行日志)。
二、其他存储引擎(较少用)
- CSV:数据以 CSV 格式存储,适合导入导出数据,不支持索引。
- Blackhole:写入的数据会被丢弃,类似 “黑洞”,可用于复制数据到其他服务器。
- Federated:允许访问远程 MySQL 服务器的表(类似视图,但可直接操作远程表)。
三、存储引擎相关操作
-
查看支持的存储引擎:
sqlSHOW ENGINES;
-
创建表时指定存储引擎:
sqlCREATE TABLE 表名 (列定义... ) ENGINE = InnoDB; -- 例如指定为InnoDB
-
修改表的存储引擎:
sqlALTER TABLE 表名 ENGINE = MyISAM;
MySQL 锁
MySQL 锁是数据库用于控制并发访问、保证数据一致性的重要机制。根据锁定范围和粒度,主要分为以下几类:
一、按锁定粒度划分
1. 表级锁(Table-level Locks)
-
特点:锁定整个表,开销小、加锁快,但并发度低。
-
类型:
-
读锁(共享锁,READ LOCK) :多个事务可同时读取,但不能修改。
sqlLOCK TABLES table_name READ; -- 加读锁
-
写锁(排他锁,WRITE LOCK) :只有持有锁的事务可读写,其他事务阻塞。
sqlLOCK TABLES table_name WRITE; -- 加写锁
-
-
释放锁:
sqlUNLOCK TABLES; -- 释放所有表锁
-
适用引擎:MyISAM、MEMORY 等(InnoDB 也支持,但一般用行级锁)。
2. 行级锁(Row-level Locks)
-
特点:仅锁定被操作的行,并发度高,但开销大、加锁慢。
-
类型(InnoDB 支持):
-
排他锁(X 锁) :事务修改数据时自动加锁,禁止其他事务读取或修改。
sql-- 显式加排他锁(通常在事务中使用) SELECT * FROM table_name WHERE id=1 FOR UPDATE;
-
共享锁(S 锁) :事务读取数据时可加,允许其他事务读,但禁止修改。
sqlSELECT * FROM table_name WHERE id=1 LOCK IN SHARE MODE;
-
-
释放锁:事务提交(COMMIT)或回滚(ROLLBACK)时自动释放。
-
注意:InnoDB 的行锁基于索引,若查询未使用索引,会升级为表锁。
3. 页级锁(Page-level Locks)
- 特点:锁定相邻的一组记录(一页),粒度介于表锁和行锁之间。
- 适用引擎:BDB 存储引擎(较少使用)。
二、按锁的模式划分
-
乐观锁:
假设并发冲突少,不加锁直接操作,提交时检查版本号或时间戳是否变化,若变化则回滚。
示例(通过版本号实现):
sql-- 更新时检查版本号,一致才更新 UPDATE table_name SET value = new_value, version = version + 1 WHERE id = 1 AND version = old_version;
-
悲观锁:
假设并发冲突多,操作前先加锁(如行级锁、表级锁),阻塞其他事务直到释放。
示例(行级排他锁):
sqlSTART TRANSACTION; SELECT * FROM table_name WHERE id=1 FOR UPDATE; -- 加锁 UPDATE table_name SET value = new_value WHERE id=1; COMMIT; -- 释放锁
三、特殊锁机制(InnoDB)
- 意向锁(Intention Locks) :
表级锁,用于标识事务即将对表中的行加锁(意向共享锁 IS、意向排他锁 IX),减少锁冲突检查开销。 - 间隙锁(Gap Locks) :
锁定索引范围之间的 “间隙”,防止其他事务插入数据,解决幻读问题(REPEATABLE READ 隔离级别下生效)。 - 临键锁(Next-Key Locks) :
行锁 + 间隙锁的组合,锁定记录及前面的间隙,是 InnoDB 默认的行锁算法。
四、锁相关操作
-
查看锁状态:
sql-- 查看表锁 SHOW OPEN TABLES WHERE In_use > 0;-- 查看行锁(需要开启 information_schema) SELECT * FROM information_schema.innodb_locks; SELECT * FROM information_schema.innodb_lock_waits;
-
避免死锁:
- 统一事务内操作表的顺序。
- 避免长时间持有锁(及时提交 / 回滚事务)。
- 降低隔离级别(如 READ COMMITTED 可减少间隙锁)。
日志
PS:
--前面说过的 有兴趣可以查看前面的关于MySQL日志的那一章
总结
以上就是这篇的内容 有点潦草 因为70%是AI的 但我觉得AI生成的还蛮易懂的 本来还有MySQL优化的 但关于优化的方法很多 比如索引 比如我很早前说的范式等等 其实都可以做到优化MySQL的结果 这里我就不特地说了
好了 我觉得我的更新频率好像慢了很多了 因为博主也在学新的东西以及发呆 然后就没有时间去更新文档
我很喜欢一句话 有时候发呆的时候发呆 大脑放空不去思考 是对自己的负责 大家天天开心~~