MySQL 是一个开源的关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现在属于Oracle公司。
主要特点:
常见存储引擎:
存储引擎对比:
特性 | InnoDB | MyISAM | MEMORY |
---|---|---|---|
事务支持 | ✔️ | ✖️ | ✖️ |
锁机制 | 行级锁 | 表级锁 | 表级锁 |
外键支持 | ✔️ | ✖️ | ✖️ |
崩溃恢复 | ✔️ | ✖️ | ✖️ |
全文索引 | ✔️(5.6+) | ✔️ | ✖️ |
存储限制 | 64TB | 256TB | RAM大小 |
核心区别:
事务支持:
锁级别:
外键约束:
崩溃恢复:
性能特点:
存储结构:
事务定义:
事务是一组原子性的SQL查询,要么全部执行成功,要么全部失败回滚。
MySQL事务支持:
START TRANSACTION;
-- SQL语句
COMMIT; -- 提交事务
-- 或
ROLLBACK; -- 回滚事务
事务特性
MySQL事务的实现方式:
SET autocommit=0
关闭自动提交ACID原则是事务的四个基本特性:
事务是不可分割的工作单位
事务中的操作要么全部完成,要么全部不完成
失败时会自动回滚所有操作
事务执行前后,数据库从一个一致状态变到另一个一致状态
不会破坏数据库的完整性约束
例如:转账前后总金额保持不变
多个事务并发执行时互不干扰
通过隔离级别控制:
事务提交后,修改将永久保存
即使系统崩溃,数据也不会丢失
通过事务日志和恢复机制保证
定义:
特点:
定义:
特点:
定义:
类型:
定义:
主要范式:
范式 | 要求 | 示例问题解决 |
---|---|---|
1NF | 属性原子性,无重复组 | 消除重复列 |
2NF | 满足1NF,且非主属性完全依赖主键 | 消除部分依赖 |
3NF | 满足2NF,且消除传递依赖 | 消除非主属性间的依赖 |
BCNF | 更强的3NF | 消除主属性对候选键的部分依赖 |
设计建议:
结构优化:
选择合适的数据类型
规范化设计
命名规范
索引优化:
其他优化:
定义:
使用场景:
读密集场景
性能关键路径
特定技术需求
实现方式:
⚠️ 注意事项:
SELECT DISTINCT column1, COUNT(*)
FROM table1
JOIN table2 ON table1.id = table2.id
WHERE condition = 'value'
GROUP BY column1
HAVING COUNT(*) > 1
ORDER BY column1
LIMIT 10;
JOIN类型 | 语法 | 描述 | 结果 |
---|---|---|---|
INNER JOIN | A INNER JOIN B ON A.id=B.id |
只返回两表中匹配的行 | 两表的交集 |
LEFT JOIN | A LEFT JOIN B ON A.id=B.id |
返回左表所有行+匹配的右表行 | 左表全集+匹配部分 |
RIGHT JOIN | A RIGHT JOIN B ON A.id=B.id |
返回右表所有行+匹配的左表行 | 右表全集+匹配部分 |
FULL JOIN | A FULL JOIN B ON A.id=B.id |
返回两表所有行(MySQL用UNION实现) | 两表的并集 |
CROSS JOIN | A CROSS JOIN B |
返回两表的笛卡尔积 | 所有可能的组合 |
嵌套在另一个查询中的SELECT语句
SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products)
SELECT * FROM
(SELECT user_id, COUNT(*) as order_count FROM orders GROUP BY user_id) as user_orders
WHERE order_count > 5
SELECT product_name,
(SELECT COUNT(*) FROM orders WHERE product_id = p.id) as order_count
FROM products p
SELECT * FROM customers c
WHERE EXISTS (SELECT 1 FROM orders WHERE customer_id = c.id)
SELECT * FROM employees
WHERE department_id IN (SELECT id FROM departments WHERE location = 'NY')
-- 创建组合索引示例
CREATE INDEX idx_user_status ON users(status, register_date);
-- 索引失效的反例
SELECT * FROM users WHERE DATE(create_time) = '2023-01-01';
-- 优化后的正例
SELECT * FROM users WHERE create_time >= '2023-01-01' AND create_time < '2023-01-02';
-- 全表扫描的反例
SELECT * FROM order_details;
-- 优化后的正例
SELECT order_id, product_id, quantity FROM order_details WHERE order_id = 1001;
-- JOIN优化示例
SELECT * FROM small_table s JOIN large_table l ON s.id = l.id;
-- 低效的分页查询
SELECT * FROM large_table LIMIT 100000, 10;
-- 高效的分页查询(使用覆盖索引)
SELECT * FROM large_table WHERE id > 100000 ORDER BY id LIMIT 10;
-- 基本语法
EXPLAIN SELECT * FROM users WHERE id = 1;
-- 查看详细执行计划(MySQL 8.0+)
EXPLAIN ANALYZE SELECT * FROM orders WHERE amount > 100;
type: 访问类型,从好到差:
key: 实际使用的索引
rows: 预估需要检查的行数
Extra: 额外信息
-- 分析查询执行计划
EXPLAIN SELECT u.name, o.order_no
FROM users u JOIN orders o ON u.id = o.user_id
WHERE u.status = 1 AND o.amount > 1000
ORDER BY o.create_time DESC;
-- 优化后添加索引
ALTER TABLE orders ADD INDEX idx_user_amount (user_id, amount);
ALTER TABLE users ADD INDEX idx_status (status);
主要索引类型:
-- 创建各类索引示例
CREATE INDEX idx_name ON users(name); -- 普通索引
CREATE UNIQUE INDEX idx_email ON users(email); -- 唯一索引
ALTER TABLE users ADD PRIMARY KEY (id); -- 主键索引
CREATE INDEX idx_name_age ON users(name, age); -- 组合索引
聚簇索引(Clustered Index):
非聚簇索引(Non-clustered Index):
高效索引创建原则:
-- 高效组合索引示例
CREATE INDEX idx_status_created ON orders(status, created_at);
-- 低效索引示例(区分度低)
CREATE INDEX idx_gender ON users(gender);
索引失效常见场景:
-- 索引失效示例
SELECT * FROM users WHERE YEAR(create_time) = 2023; -- 使用函数
SELECT * FROM products WHERE name LIKE '%apple%'; -- 前导通配符
SELECT * FROM orders WHERE amount+100 > 500; -- 对列运算
覆盖索引(Covering Index):
-- 覆盖索引示例
CREATE INDEX idx_user_order ON orders(user_id, order_date, amount);
-- 使用覆盖索引的查询
SELECT user_id, order_date FROM orders
WHERE user_id = 1001 AND order_date > '2023-01-01';
判断方法:
-- 检查索引使用情况
EXPLAIN SELECT * FROM users WHERE id = 1001;
-- 强制使用/忽略索引
SELECT * FROM users USE INDEX(idx_name) WHERE name = 'John';
SELECT * FROM users IGNORE INDEX(idx_name) WHERE name = 'John';
数据库性能优化策略:
服务器配置优化:
SQL优化:
架构优化:
-- 查看当前配置
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW STATUS LIKE 'Threads_connected';
慢查询定义:
分析优化步骤:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 设置为2秒
EXPLAIN SELECT * FROM orders WHERE create_time < '2023-01-01';
-- 查看慢查询日志位置
SHOW VARIABLES LIKE 'slow_query_log_file';
分库分表策略:
水平分表:
垂直分表:
分库策略:
-- 水平分表示例
CREATE TABLE orders_2023 (...);
CREATE TABLE orders_2024 (...);
读写分离概念:
实现方式:
-- 主库配置
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
-- 从库配置
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read-only=1
大表查询优化方案:
索引优化:
查询优化:
-- 优化大表分页
-- 传统低效分页
SELECT * FROM large_table LIMIT 1000000, 10;
-- 优化后分页
SELECT * FROM large_table WHERE id > 1000000 ORDER BY id LIMIT 10;
架构优化:
-- 创建分区表示例
CREATE TABLE logs (
id INT,
log_date DATE
) PARTITION BY RANGE (YEAR(log_date)) (
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025)
);
四种事务隔离级别:
READ UNCOMMITTED(读未提交)
READ COMMITTED(读已提交)
REPEATABLE READ(可重复读)
SERIALIZABLE(串行化)
-- 查看和设置隔离级别
SELECT @@transaction_isolation;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
并发问题说明:
问题类型 | 描述 | 示例场景 |
---|---|---|
脏读 | 读取到其他事务未提交的数据 | 事务A读取了事务B修改但未提交的数据,B回滚后A读到的是脏数据 |
不可重复读 | 同一事务内多次读取同一数据结果不同 | 事务A两次读取同一行数据,期间事务B修改了该行并提交 |
幻读 | 同一事务内多次查询返回不同行数 | 事务A查询符合条件的数据行数,期间事务B插入新行并提交 |
InnoDB锁分类:
按粒度分:
按功能分:
意向锁:
-- 手动加锁示例
SELECT * FROM accounts WHERE id = 1 FOR UPDATE; -- X锁
SELECT * FROM accounts WHERE id = 1 LOCK IN SHARE MODE; -- S锁
死锁定义:
两个或多个事务互相持有对方需要的锁,导致所有事务都无法继续执行
避免死锁方法:
解决死锁:
– 设置锁等待超时
SET innodb_lock_wait_timeout = 50;
对比说明:
特性 | 悲观锁 | 乐观锁 |
---|---|---|
实现方式 | 数据库原生锁机制 | 版本号或时间戳 |
并发性能 | 较差 | 较好 |
适用场景 | 写多读少 | 读多写少 |
锁时机 | 操作前先加锁 | 提交时检查冲突 |
示例 | SELECT…FOR UPDATE | UPDATE…WHERE version=old_version |
-- 悲观锁实现
BEGIN;
SELECT * FROM products WHERE id = 1 FOR UPDATE;
UPDATE products SET stock = stock - 1 WHERE id = 1;
COMMIT;
-- 乐观锁实现
UPDATE products
SET stock = stock - 1, version = version + 1
WHERE id = 1 AND version = 5;
**MVCC(Multi-Version Concurrency Control,多版本并发控制)**是InnoDB实现高并发的重要机制,通过保存数据的多个版本实现:
版本链存储:
DB_TRX_ID
:最近修改该行的事务IDDB_ROLL_PTR
:回滚指针,指向undo log记录ReadView机制:
m_ids
:当前活跃事务ID集合min_trx_id
:最小活跃事务IDmax_trx_id
:系统预分配的下个事务IDcreator_trx_id
:创建该ReadView的事务ID可见性判断规则:
DB_TRX_ID
< min_trx_id
:可见(事务已提交)DB_TRX_ID
>= max_trx_id
:不可见(事务后启动)min_trx_id
<= DB_TRX_ID
< max_trx_id
:
m_ids
中则不可见(事务未提交)m_ids
中则可见(事务已提交)隔离级别 | MVCC实现特点 |
---|---|
READ UNCOMMITTED | 不使用MVCC,直接读取最新版本(含未提交数据) |
READ COMMITTED | 每次读取都生成新ReadView,看到其他事务已提交的修改 |
REPEATABLE READ | 第一次读取时生成ReadView,后续读取使用相同ReadView(默认级别) |
SERIALIZABLE | 退化为基于锁的并发控制,不使用MVCC |
-- 事务1(更新数据)
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
-- 事务2(同时查询,使用MVCC)
BEGIN;
SELECT * FROM accounts WHERE id = 1; -- 读取的是更新前的版本
COMMIT;
优点:
缺点:
undo log:
purge机制:
innodb_purge_batch_size
控制-- 查看MVCC相关信息
SHOW ENGINE INNODB STATUS\G
SELECT * FROM information_schema.INNODB_TRX;
主流高可用方案:
主从复制(Master-Slave Replication)
MGR(MySQL Group Replication)
Galera Cluster
中间件方案
云数据库方案
备份方法:
-- 全量备份
mysqldump -uroot -p --all-databases > full_backup.sql
-- 单库备份
mysqldump -uroot -p dbname > db_backup.sql
-- XtraBackup热备份
xtrabackup --backup --target-dir=/backup/
恢复方法:
-- 逻辑备份恢复
mysql -uroot -p < full_backup.sql
-- 物理备份恢复
xtrabackup --copy-back --target-dir=/backup/
主从复制原理:
配置步骤:
[mysqld]
server-id=1
log-bin=mysql-bin
binlog-format=ROW
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
[mysqld]
server-id=2
relay-log=mysql-relay-bin
read-only=1
CHANGE MASTER TO
MASTER_HOST='master_host',
MASTER_USER='repl',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
START SLAVE;
复制延迟解决方案:
优化主库写入
提升从库性能
-- 设置并行复制
SET GLOBAL slave_parallel_workers=4;
架构优化
监控延迟
-- 查看复制状态
SHOW SLAVE STATUS\G
读写分离概念:
实现方式:
中间件方案
应用层实现
-- ProxySQL配置示例
INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES
(10,'master',3306),
(20,'slave1',3306),
(20,'slave2',3306);
-- 读写分离规则
INSERT INTO mysql_query_rules (rule_id,active,match_pattern,destination_hostgroup,apply) VALUES
(1,1,'^SELECT.*FOR UPDATE',10,1),
(2,1,'^SELECT',20,1),
(3,1,'^INSERT',10,1),
(4,1,'^UPDATE',10,1),
(5,1,'^DELETE',10,1);
视图定义:
视图(View)是基于SQL查询结果的虚拟表,不实际存储数据,每次查询时动态生成结果集。
-- 创建视图示例
CREATE VIEW customer_orders AS
SELECT c.customer_name, o.order_id, o.order_date
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id;
视图优点:
视图缺点:
-- 可更新视图示例(简单视图)
CREATE VIEW active_users AS
SELECT * FROM users WHERE status = 'active';
-- 更新视图数据(实际更新基表)
UPDATE active_users SET last_login = NOW() WHERE user_id = 101;
主要区别对比:
特性 | 存储过程(Procedure) | 函数(Function) |
---|---|---|
返回值 | 可通过OUT参数返回多个值 | 必须返回单个值 |
调用方式 | CALL procedure_name() | SELECT function_name() |
SQL中使用 | 不能直接在SELECT中使用 | 可在SELECT中直接调用 |
事务控制 | 可以包含事务语句(COMMIT/ROLLBACK) | 通常不包含事务控制 |
主要用途 | 执行复杂业务逻辑 | 计算并返回特定值 |
存储过程示例:
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE transfer_funds(
IN from_account INT,
IN to_account INT,
IN amount DECIMAL(10,2),
OUT status VARCHAR(50)
BEGIN
START TRANSACTION;
UPDATE accounts SET balance = balance - amount WHERE account_id = from_account;
UPDATE accounts SET balance = balance + amount WHERE account_id = to_account;
SET status = 'Transfer completed';
COMMIT;
END //
DELIMITER ;
-- 调用存储过程
CALL transfer_funds(101, 102, 500.00, @status);
SELECT @status;
函数示例:
-- 创建函数
DELIMITER //
CREATE FUNCTION get_customer_balance(c_id INT)
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
DECLARE balance DECIMAL(10,2);
SELECT account_balance INTO balance FROM customers WHERE customer_id = c_id;
RETURN balance;
END //
DELIMITER ;
-- 调用函数
SELECT customer_name, get_customer_balance(customer_id)
FROM customers
WHERE get_customer_balance(customer_id) > 1000;