|
|
|
@ -0,0 +1,150 @@ |
|
|
|
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. 死锁 |
|
|
|
产生条件:互斥、请求与保持、不剥夺、循环等待 |
|
|
|
避免方案: |
|
|
|
所有事务按相同顺序访问数据行 |
|
|
|
大事务拆分为小事务,减少锁持有时间 |
|
|
|
等值查询用唯一索引,避免间隙锁扩大范围 |
|
|
|
避免无索引查询导致的表锁 |