1. MySQL 数据库操作基础
MySQL作为最流行的开源关系型数据库之一,掌握其核心SQL语句是每位开发者的必备技能。我在实际项目中使用MySQL已有8年时间,从简单的增删改查到复杂的分析查询,积累了不少实战经验。本文将系统梳理MySQL中最常用、最实用的SQL语句,包含基础操作、高级查询、性能优化等多个维度。
对于刚接触MySQL的新手,建议先掌握基础CRUD操作,再逐步学习索引优化、事务控制等进阶内容。而对于有经验的开发者,本文中的一些优化技巧和特殊语法或许能带来新的启发。无论你是准备面试还是解决实际问题,这份SQL语句大全都能作为快速参考手册。
2. 数据库与表操作
2.1 数据库管理
创建数据库是最基础的操作,但有几个关键参数需要注意:
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;这里我推荐使用utf8mb4字符集而非老旧的utf8,因为前者支持完整的Unicode字符(包括emoji)。COLLATE指定了排序规则,utf8mb4_unicode_ci表示不区分大小写的Unicode排序。
查看所有数据库:
SHOW DATABASES;删除数据库(慎用):
DROP DATABASE mydb;切换当前数据库:
USE mydb;2.2 表结构操作
创建表时需要仔细设计字段类型和约束:
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL, age TINYINT UNSIGNED, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX idx_email (email) ) ENGINE=InnoDB;几个关键点:
- 主键使用自增INT是常见做法,但大数据量时考虑BIGINT
- VARCHAR长度根据实际需要设置,过大会浪费内存
- 时间戳字段默认值设为当前时间很实用
- 为常用查询字段(email)添加索引提升性能
修改表结构:
ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;查看表结构:
DESCRIBE users;3. 数据增删改查(CRUD)
3.1 插入数据
基础插入语法:
INSERT INTO users (username, email, age) VALUES ('john_doe', 'john@example.com', 30);批量插入能显著提高性能:
INSERT INTO users (username, email, age) VALUES ('user1', 'user1@example.com', 25), ('user2', 'user2@example.com', 28), ('user3', 'user3@example.com', 32);从其他表导入数据:
INSERT INTO user_backup SELECT * FROM users WHERE created_at > '2023-01-01';3.2 查询数据
基础查询:
SELECT id, username, email FROM users WHERE age > 25;分页查询(注意性能):
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 20; -- 获取第3页,每页10条模糊查询:
SELECT * FROM users WHERE username LIKE 'j%' AND email LIKE '%@example.com';3.3 更新数据
单表更新:
UPDATE users SET age = 31, email = 'new_email@example.com' WHERE id = 1;多表关联更新:
UPDATE orders o JOIN users u ON o.user_id = u.id SET o.status = 'completed' WHERE u.username = 'john_doe';3.4 删除数据
条件删除:
DELETE FROM users WHERE id = 1;清空表(不可回滚):
TRUNCATE TABLE logs;4. 高级查询技巧
4.1 多表连接查询
内连接(只返回匹配行):
SELECT u.username, o.order_date, o.amount FROM users u INNER JOIN orders o ON u.id = o.user_id;左连接(返回左表所有行):
SELECT u.username, COUNT(o.id) AS order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id;4.2 聚合函数与分组
常用聚合函数:
SELECT COUNT(*) AS total_users, AVG(age) AS avg_age, MAX(created_at) AS latest_user FROM users;分组统计:
SELECT DATE(created_at) AS signup_date, COUNT(*) AS daily_signups FROM users GROUP BY signup_date HAVING COUNT(*) > 5 ORDER BY signup_date DESC;4.3 子查询
WHERE子句中的子查询:
SELECT * FROM products WHERE price > (SELECT AVG(price) FROM products);FROM子句中的子查询:
SELECT u.username, o.order_count FROM users u JOIN ( SELECT user_id, COUNT(*) AS order_count FROM orders GROUP BY user_id ) o ON u.id = o.user_id;5. 索引与性能优化
5.1 索引管理
添加索引:
ALTER TABLE users ADD INDEX idx_username (username);创建复合索引:
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);查看表索引:
SHOW INDEX FROM users;5.2 查询优化
使用EXPLAIN分析查询:
EXPLAIN SELECT * FROM users WHERE username = 'john_doe';强制使用索引:
SELECT * FROM users FORCE INDEX (idx_username) WHERE username = 'john_doe';避免全表扫描的技巧:
-- 不好的写法 SELECT * FROM users WHERE YEAR(created_at) = 2023; -- 优化写法 SELECT * FROM users WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';6. 事务与锁机制
6.1 事务控制
基本事务:
START TRANSACTION; UPDATE accounts SET balance = balance - 100 WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 2; COMMIT; -- 出错时使用 ROLLBACK;设置隔离级别:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;6.2 锁机制
行锁示例:
SELECT * FROM orders WHERE id = 123 FOR UPDATE; -- 获取排他锁表锁(慎用):
LOCK TABLES orders WRITE; -- 执行操作... UNLOCK TABLES;7. 存储过程与触发器
7.1 存储过程
创建存储过程:
DELIMITER // CREATE PROCEDURE update_user_age(IN user_id INT, IN age_diff INT) BEGIN UPDATE users SET age = age + age_diff WHERE id = user_id; SELECT ROW_COUNT() AS affected_rows; END // DELIMITER ;调用存储过程:
CALL update_user_age(1, 1);7.2 触发器
创建触发器:
CREATE TRIGGER before_user_update BEFORE UPDATE ON users FOR EACH ROW BEGIN SET NEW.updated_at = NOW(); END;8. 实用技巧与注意事项
- 备份重要数据:
-- 导出表结构和数据 mysqldump -u username -p mydb > backup.sql- 批量更新时注意:
-- 每1000条提交一次事务 SET autocommit=0; UPDATE large_table SET col1 = 'value' WHERE condition; COMMIT; SET autocommit=1;- 处理大数据量表:
-- 分批次处理 DELETE FROM large_table WHERE id IN ( SELECT id FROM large_table WHERE condition LIMIT 10000 );- 监控慢查询:
-- 在my.cnf中配置 slow_query_log = 1 slow_query_log_file = /var/log/mysql/mysql-slow.log long_query_time = 2- 字符集问题排查:
SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';在实际项目中,我发现很多性能问题都源于不当的索引设计和低效的查询语句。特别是在处理百万级数据时,一个简单的JOIN操作如果没有正确使用索引,可能导致整个系统响应变慢。建议定期使用EXPLAIN分析关键查询,并建立适当的复合索引。
另一个常见问题是事务使用不当。长时间运行的事务会持有锁资源,导致其他操作阻塞。在编写事务代码时,应尽量缩短事务持续时间,避免在事务中进行耗时操作(如网络请求、文件IO等)。