You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
7.9 KiB
150 lines
7.9 KiB
1. 核心定义与特点
|
|
MySQL 是Oracle 公司维护的开源关系型数据库管理系统(RDBMS),基于标准 SQL 语言,是 Web 开发、企业级业务最主流的数据库。
|
|
核心优势:开源免费、跨平台、性能优异、支持事务、高可用生态完善、社区活跃。
|
|
主流版本:
|
|
5.7:企业广泛使用的稳定版,长期支持,兼容性好
|
|
8.0:当前最新稳定版,性能大幅提升,新增窗口函数、CTE、原子 DDL、原生 JSON 支持,默认 InnoDB 引擎,默认字符集 utf8mb4,移除查询缓存。
|
|
字段约束
|
|
NOT NULL:非空约束,建议所有字段都设置,避免 NULL 值带来的性能问题
|
|
UNIQUE:唯一约束,字段值唯一,允许 NULL
|
|
PRIMARY KEY:主键约束,非空 + 唯一,一张表仅一个
|
|
DEFAULT:默认值,字段未赋值时的兜底值
|
|
CHECK:检查约束,MySQL 8.0.16 + 正式支持,限制字段取值范围
|
|
二、SQL 核心语法
|
|
SQL 分为五大类:DDL(数据定义)、DML(数据操作)、DQL(数据查询)、DCL(数据控制)、TCL(事务控制)
|
|
1. DDL:操作库、表结构
|
|
-- 创建数据库
|
|
CREATE DATABASE IF NOT EXISTS test_db
|
|
DEFAULT CHARACTER SET utf8mb4
|
|
DEFAULT COLLATE utf8mb4_general_ci;
|
|
-- 删除数据库
|
|
DROP DATABASE IF EXISTS test_db;
|
|
-- 查看数据库创建语句
|
|
SHOW CREATE DATABASE test_db;
|
|
-- 创建表(企业级规范示例)
|
|
CREATE TABLE IF NOT EXISTS `user` (
|
|
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
|
`username` VARCHAR(50) NOT NULL COMMENT '用户名',
|
|
`phone` CHAR(11) NOT NULL COMMENT '手机号',
|
|
`age` TINYINT UNSIGNED DEFAULT 0 COMMENT '年龄',
|
|
`gender` ENUM('男','女','未知') DEFAULT '未知' COMMENT '性别',
|
|
`balance` DECIMAL(10,2) DEFAULT 0.00 COMMENT '账户余额',
|
|
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
|
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
|
PRIMARY KEY (`id`), -- 主键索引
|
|
UNIQUE KEY `uk_phone` (`phone`), -- 唯一索引
|
|
KEY `idx_username` (`username`) -- 普通索引
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
|
|
-- 修改表结构
|
|
ALTER TABLE `user` ADD COLUMN `email` VARCHAR(100) NOT NULL COMMENT '邮箱' AFTER `phone`; -- 新增字段
|
|
ALTER TABLE `user` MODIFY COLUMN `age` TINYINT UNSIGNED DEFAULT 18 COMMENT '年龄'; -- 修改字段属性
|
|
ALTER TABLE `user` DROP COLUMN `email`; -- 删除字段
|
|
ALTER TABLE `user` ADD INDEX `idx_create_time` (`create_time`); -- 新增索引
|
|
ALTER TABLE `user` DROP INDEX `idx_create_time`; -- 删除索引
|
|
-- 删除表
|
|
DROP TABLE IF EXISTS `user`;
|
|
2. DML:增删改表数据
|
|
-- 插入数据(批量插入性能远高于循环单条插入)
|
|
INSERT INTO `user` (username, phone, age, gender, balance)
|
|
VALUES
|
|
('张三', '13800138000', 25, '男', 1000.00),
|
|
('李四', '13800138001', 22, '女', 500.00);
|
|
-- 更新数据(必须加WHERE条件,否则全表更新!!!)
|
|
UPDATE `user`
|
|
SET balance = 1500.00, age = 26
|
|
WHERE id = 1;
|
|
-- 删除数据(必须加WHERE条件,否则全表删除!!!)
|
|
DELETE FROM `user` WHERE id = 1;
|
|
-- 清空全表(比DELETE快,自增主键重置)
|
|
TRUNCATE TABLE `user`;
|
|
3. DQL:数据查询
|
|
-- 语法书写顺序
|
|
SELECT [DISTINCT] 字段列表
|
|
FROM 表名
|
|
[WHERE 条件过滤]
|
|
[GROUP BY 分组字段]
|
|
[HAVING 分组后过滤]
|
|
[ORDER BY 排序字段 ASC/DESC]
|
|
[LIMIT 分页偏移量, 条数];
|
|
-- 实际执行顺序
|
|
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
|
|
SELECT u.id, u.username, o.order_no, o.amount
|
|
FROM `user` u
|
|
INNER JOIN `order` o ON u.id = o.user_id;
|
|
-- 查询所有用户,含无订单的用户
|
|
SELECT u.id, u.username, o.order_no, o.amount
|
|
FROM `user` u
|
|
LEFT JOIN `order` o ON u.id = o.user_id;
|
|
|
|
-- 查询无订单的用户
|
|
SELECT u.id, u.username
|
|
FROM `user` u
|
|
LEFT JOIN `order` o ON u.id = o.user_id
|
|
WHERE o.id IS NULL;
|
|
-- 创建用户(%允许远程登录,localhost仅本地登录)
|
|
CREATE USER 'test_user'@'%' IDENTIFIED BY 'Test@123456';
|
|
|
|
-- 授权(最小权限原则)
|
|
GRANT SELECT, INSERT ON test_db.* TO 'test_user'@'%'; -- 给test库授予查询、插入权限
|
|
GRANT ALL PRIVILEGES ON *.* TO 'admin_user'@'%' WITH GRANT OPTION; -- 管理员全权限
|
|
|
|
-- 刷新权限
|
|
FLUSH PRIVILEGES;
|
|
|
|
-- 查看权限
|
|
SHOW GRANTS FOR 'test_user'@'%';
|
|
|
|
-- 撤销权限
|
|
REVOKE INSERT ON test_db.* FROM 'test_user'@'%';
|
|
-- 删除用户
|
|
DROP USER 'test_user'@'%';
|
|
五、事务与 ACID、MVCC
|
|
1. 事务四大特性(ACID)
|
|
事务是一组原子性的 SQL 操作,要么全成功,要么全失败回滚,仅 InnoDB 支持。
|
|
表格
|
|
特性 定义 实现原理
|
|
原子性(Atomicity) 事务是最小执行单元,不可分割,要么全成要么全败 undo log(回滚日志),存储数据历史版本,回滚时恢复
|
|
一致性(Consistency) 事务执行前后,数据的完整性约束不被破坏 事务的最终目的,由原子性、隔离性、持久性共同保证
|
|
隔离性(Isolation) 并发事务之间相互隔离,互不干扰 锁机制 + MVCC 多版本并发控制
|
|
持久性(Durability) 事务提交后,数据修改永久生效,崩溃也不丢失 redo log(重做日志),WAL 预写日志机制
|
|
2. 事务并发问题与隔离级别
|
|
并发问题
|
|
脏读:一个事务读到了另一个事务未提交的数据
|
|
不可重复读:同一事务内,两次读取同一行数据结果不一致(另一个事务修改并提交)
|
|
幻读:同一事务内,两次范围查询返回的行数不一致(另一个事务插入 / 删除并提交)
|
|
四大隔离级别
|
|
表格
|
|
隔离级别 脏读 不可重复读 幻读 说明
|
|
读未提交(Read Uncommitted) 可能 可能 可能 最低级别,几乎不用
|
|
读已提交(Read Committed) 解决 可能 可能 Oracle、SQL Server 默认
|
|
可重复读(Repeatable Read) 解决 解决 可能(InnoDB 已解决) MySQL 默认级别
|
|
串行化(Serializable) 解决 解决 解决 最高级别,事务串行执行,并发性能极差
|
|
重点:InnoDB 的 RR 级别,通过 ** 临键锁(Next-Key Lock)** 彻底解决了幻读问题。
|
|
3. MVCC 多版本并发控制
|
|
MVCC 是 InnoDB 实现隔离级别的核心,通过数据行的多个版本实现读写不阻塞,大幅提升并发性能。
|
|
核心实现:隐藏字段(DB_TRX_ID、DB_ROLL_PTR)+ undo log + Read View 读视图
|
|
核心逻辑:事务开启时生成 Read View,判断当前事务能看到的数据版本,不同隔离级别 Read View 生成时机不同:
|
|
RC 级别:每次 SELECT 都生成新的 Read View,解决脏读
|
|
RR 级别:第一次 SELECT 生成 Read View,后续复用,解决不可重复读
|
|
六、MySQL 锁机制
|
|
锁是实现事务隔离性的核心,解决并发修改数据的冲突问题。
|
|
1. 锁的分类
|
|
按粒度分类
|
|
全局锁:锁住整个实例,所有读写阻塞,仅用于全库备份
|
|
表级锁:锁住整张表,加锁快、冲突概率高、并发差,MyISAM 默认使用
|
|
行级锁:InnoDB 特有,锁住具体行,锁粒度最小、冲突概率最低、并发性能最高
|
|
注意:InnoDB 行锁是针对索引加的锁,查询没用到索引会升级为表锁!
|
|
按功能分类
|
|
共享锁(S 锁,读锁):多个事务可同时加 S 锁,阻塞写操作,用法SELECT ... LOCK IN SHARE MODE;
|
|
排他锁(X 锁,写锁):一个事务加 X 锁后,其他事务不能加 S/X 锁,读写都阻塞。UPDATE/DELETE/INSERT 会自动加 X 锁,用法SELECT ... FOR UPDATE;
|
|
2. InnoDB 行锁 3 种算法(RR 级别)
|
|
记录锁:锁住具体的索引记录,如WHERE id=1,仅锁住 id=1 的行
|
|
间隙锁:锁住索引之间的间隙,防止插入数据,解决幻读
|
|
临键锁(Next-Key Lock):记录锁 + 间隙锁,左开右闭区间,InnoDB 默认行锁算法,彻底解决幻读
|
|
3. 死锁
|
|
产生条件:互斥、请求与保持、不剥夺、循环等待
|
|
避免方案:
|
|
所有事务按相同顺序访问数据行
|
|
大事务拆分为小事务,减少锁持有时间
|
|
等值查询用唯一索引,避免间隙锁扩大范围
|
|
避免无索引查询导致的表锁
|