一、MySQL 概述 MySQL 是全球最流行的开源关系型数据库管理系统,由 Oracle 公司维护。它以高性能、高可靠性、易用性 著称,是 Web 应用的首选数据库。
存储引擎对比
特性
InnoDB
MyISAM
事务支持
支持
不支持
行级锁
支持
仅表锁
外键
支持
不支持
崩溃恢复
支持
不支持
全文索引
支持(5.6+)
支持
适用场景
OLTP(推荐)
读密集、无事务
日常开发统一使用 InnoDB。
二、表设计规范 命名规范 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE TABLE user_orders ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键' , user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID' , order_no VARCHAR (32 ) NOT NULL COMMENT '订单号' , amount DECIMAL (10 ,2 ) NOT NULL COMMENT '金额' , status TINYINT NOT NULL DEFAULT 0 COMMENT '状态: 0待支付 1已支付 2已取消' , created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' , updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' , PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no), KEY idx_user_id (user_id), KEY idx_status_created (status, created_at) ) ENGINE= InnoDB DEFAULT CHARSET= utf8mb4 COMMENT= '订单表' ;
字段设计原则
规则
说明
主键用 BIGINT
自增或雪花算法,不用 UUID
金额用 DECIMAL
不用 FLOAT/DOUBLE,避免精度丢失
时间用 DATETIME
不用 TIMESTAMP(2038 年问题)
字符串用 VARCHAR
长度按需分配,不滥用 TEXT
状态用 TINYINT
配合注释说明含义
必须有注释
字段和表都要有 COMMENT
必须有主键
每张表都要有自增主键
NOT NULL
尽量避免 NULL,设默认值
三大范式
第一范式(1NF) :字段不可再分(原子性)
第二范式(2NF) :非主键字段完全依赖主键
第三范式(3NF) :非主键字段不传递依赖
实际开发中允许适当反范式化(冗余字段)以提升查询性能。
三、SQL 编写技巧 查询优化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 SELECT id, username, email FROM users WHERE status = 1 ;SELECT * FROM orders WHERE id > 100000 ORDER BY id LIMIT 10 ;INSERT INTO users (name, email) VALUES ('Alice' , 'alice@example.com' ), ('Bob' , 'bob@example.com' ), ('Charlie' , 'charlie@example.com' ); SELECT * FROM users uWHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);SELECT user_id, amount, ROW_NUMBER () OVER (PARTITION BY user_id ORDER BY amount DESC ) AS rn FROM orders;
聚合与分组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 SELECT COUNT (* ) AS total, SUM (amount) AS sum_amount, AVG (amount) AS avg_amount, MAX (amount) AS max_amount, MIN (amount) AS min_amount FROM ordersWHERE status = 1 ;SELECT user_id, SUM (amount) AS totalFROM ordersGROUP BY user_idHAVING total > 1000 ;SELECT user_id, GROUP_CONCAT(order_no SEPARATOR ', ' ) AS order_nosFROM ordersGROUP BY user_id;
JOIN 操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SELECT u.name, o.order_noFROM users uINNER JOIN orders o ON u.id = o.user_id;SELECT u.name, COUNT (o.id) AS order_countFROM users uLEFT JOIN orders o ON u.id = o.user_idGROUP BY u.id;SELECT e.name AS employee, m.name AS managerFROM employees eLEFT JOIN employees m ON e.manager_id = m.id;
四、索引深入 索引类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 PRIMARY KEY (id)UNIQUE KEY uk_email (email)KEY idx_name (name) KEY idx_status_time (status, created_at) FULLTEXT INDEX ft_content (content)
最左前缀原则 1 2 3 4 5 6 7 8 9 10 11 WHERE a = 1 WHERE a = 1 AND b = 2 WHERE a = 1 AND b = 2 AND c = 3 WHERE a = 1 AND c = 3 WHERE a = 1 ORDER BY b WHERE b = 2 WHERE b = 2 AND c = 3
索引失效场景 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 WHERE YEAR (created_at) = 2026 WHERE created_at >= '2026-01-01' WHERE phone = 13800138000 WHERE phone = '13800138000' WHERE name LIKE '%张' WHERE name LIKE '张%' WHERE indexed_col = 1 OR non_indexed_col = 2 WHERE status != 1
EXPLAIN 分析 1 EXPLAIN SELECT * FROM orders WHERE user_id = 100 ;
字段
说明
type
访问类型:ALL < index < range < ref < eq_ref < const
key
实际使用的索引
rows
预估扫描行数
Extra
Using index(覆盖索引)、Using filesort(需优化)
五、事务与锁 事务 ACID
A(原子性) :要么全做,要么全不做
C(一致性) :事务前后数据一致
I(隔离性) :事务间互不干扰
D(持久性) :提交后永久生效
隔离级别 1 2 3 4 5 SELECT @@transaction _isolation;SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
隔离级别
脏读
不可重复读
幻读
READ UNCOMMITTED
有
有
有
READ COMMITTED
无
有
有
REPEATABLE READ(默认)
无
无
有*
SERIALIZABLE
无
无
无
*InnoDB 在 RR 级别通过 MVCC + Gap Lock 解决了大部分幻读问题。
锁机制 1 2 3 4 5 6 7 8 9 SELECT * FROM orders WHERE id = 1 FOR UPDATE ; SELECT * FROM orders WHERE id = 1 LOCK IN SHARE MODE; SHOW ENGINE INNODB STATUS;
六、慢查询优化 开启慢查询日志 1 2 3 4 5 6 SHOW VARIABLES LIKE 'slow_query%' ;SET GLOBAL slow_query_log = ON ;SET GLOBAL long_query_time = 1 ;
优化步骤 1 2 3 4 5 1. 开启慢查询日志,找出慢 SQL 2. EXPLAIN 分析执行计划 3. 检查是否命中索引 4. 优化 SQL 或添加合适索引 5. 必要时拆分大查询
常见优化手段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SELECT user_id, status FROM orders WHERE user_id = 100 ;CREATE TEMPORARY TABLE tmp_user_ids (user_id BIGINT );INSERT INTO tmp_user_ids VALUES (1 ), (2 ), (3 );SELECT * FROM orders WHERE user_id IN (SELECT user_id FROM tmp_user_ids);DELETE FROM logs WHERE created_at < '2025-01-01' LIMIT 1000 ;
七、数据安全 备份与恢复 1 2 3 4 5 6 7 8 9 10 11 mysqldump -u root -p --all-databases > backup.sql mysqldump -u root -p mydb > mydb.sql mysql -u root -p mydb < mydb.sql mysqlbinlog binlog.000001 | mysql -u root -p
SQL 注入防护 1 2 3 4 5 6 7 8 String sql = "SELECT * FROM users WHERE name = '" + name + "'" ;String sql = "SELECT * FROM users WHERE name = ?" ;PreparedStatement ps = conn.prepareStatement(sql);ps.setString(1 , name);
八、分库分表 何时需要
单表数据超过 1000 万行
单库写入 QPS 超过 5000
磁盘容量不足
分表策略
策略
说明
适用场景
范围分表
按 ID 或时间范围
数据增长均匀
Hash 分表
按 ID 取模
数据分布均匀
日期分表
按月/年分表
日志、流水类数据
常用中间件
ShardingSphere :Apache 开源,支持分库分表、读写分离
MyCat :数据库中间件
Vitess :YouTube 开源,适合大规模场景
总结 MySQL 是后端开发的必备技能。表设计要规范,索引要合理,SQL 要优化。通过 EXPLAIN 分析执行计划,通过慢查询日志发现问题,通过分库分表应对大数据量。掌握这些核心知识,能应对绝大多数业务场景。