一、SQL 语句分类与核心概述
SQL(Structured Query Language)是操作关系型数据库的标准语言,MySQL 作为主流关系型数据库,其 SQL 语句主要分为以下几类:
DDL(数据定义语言):用于定义数据库对象(表、索引、视图等)。DML(数据操作语言):用于操作表中的数据(增、删、改)。DQL(数据查询语言):用于查询数据(单表查询、多表关联查询等)。DCL(数据控制语言):用于控制数据库权限(用户管理、权限分配等)。TCL(事务控制语言):用于管理事务(提交、回滚等)。
参考资料:
MySQL 8.0 官方文档 - SQL 语法指南SQL 标准规范(ANSI/ISO)
二、DDL(数据定义语言)
1. CREATE(创建对象)
语法格式
sql
CREATE DATABASE [IF NOT EXISTS] database_name; -- 创建数据库
CREATE TABLE [IF NOT EXISTS] table_name (
column1 data_type [constraint],
column2 data_type [constraint],
...
[PRIMARY KEY (column_list)] -- 主键约束
);
参数说明
IF NOT EXISTS:避免重复创建导致报错。data_type:常见类型包括INT、VARCHAR、DATE、TEXT等。constraint:约束条件,如NOT NULL、UNIQUE、DEFAULT、FOREIGN KEY(外键)。
应用场景
创建数据库及表结构,例如用户信息表:
sql
CREATE DATABASE IF NOT EXISTS mydb;
USE mydb;
CREATE TABLE IF NOT EXISTS users (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
注意事项
表名、字段名需避免使用 MySQL 关键字(如SELECT、FROM)。外键约束需确保关联表已存在,且数据类型一致。
常见错误
错误 1:Unknown column 'xxx' in 'field list' 原因:字段名拼写错误或未定义。错误 2:Duplicate entry for key 'PRIMARY' 原因:主键重复,需确保主键唯一。
2. ALTER(修改表结构)
语法格式
sql
ALTER TABLE table_name
ADD COLUMN column_name data_type [constraint] [AFTER column_name]; -- 添加字段
ALTER TABLE table_name
MODIFY COLUMN column_name new_data_type; -- 修改字段类型
ALTER TABLE table_name
RENAME COLUMN old_name TO new_name; -- 重命名字段
ALTER TABLE table_name
DROP COLUMN column_name; -- 删除字段
应用场景
新增字段:ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;修改字段长度:ALTER TABLE users MODIFY COLUMN username VARCHAR(100);
注意事项
生产环境中谨慎使用ALTER TABLE,大表操作可能导致锁表。字段类型修改需确保数据兼容(如VARCHAR转INT会丢失非数字数据)。
3. DROP(删除对象)
语法格式
sql
DROP DATABASE [IF EXISTS] database_name; -- 删除数据库
DROP TABLE [IF EXISTS] table_name; -- 删除表
注意事项
DROP操作不可逆,建议先备份数据。避免在生产环境直接使用,可通过TRUNCATE TABLE清空表数据(保留表结构)。
三、DML(数据操作语言)
1. INSERT(插入数据)
语法格式
sql
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...); -- 单条插入
INSERT INTO table_name VALUES (value1, value2, ...), (value3, value4, ...); -- 批量插入
应用场景
sql
INSERT INTO users (username, email)
VALUES ('Alice', 'alice@example.com');
注意事项
字段顺序需与VALUES顺序一致,且数据类型匹配。主键字段若设置为AUTO_INCREMENT,插入时可不指定。
常见错误
错误:Data truncation: Data too long for column 'xxx' 原因:插入值超过字段长度限制。
2. UPDATE(更新数据)
语法格式
sql
UPDATE table_name
SET column1 = value1, column2 = value2
[WHERE condition]; -- 条件过滤,避免全表更新
应用场景
sql
UPDATE users
SET email = 'new_alice@example.com'
WHERE user_id = 1;
注意事项
务必添加WHERE条件,否则会更新表中所有记录。使用事务(BEGIN/COMMIT)确保数据一致性。
3. DELETE(删除数据)
语法格式
sql
DELETE FROM table_name [WHERE condition];
应用场景
sql
DELETE FROM users WHERE user_id = 100;
注意事项
无WHERE条件时会删除全表数据,谨慎操作。DELETE会逐行删除并记录日志,清空大表建议用TRUNCATE(但会重置自增主键)。
四、DQL(数据查询语言)—— 核心语句
1. SELECT 基础查询
语法格式
sql
SELECT [DISTINCT] column1, column2, ...
FROM table_name
[WHERE condition] -- 过滤行
[GROUP BY column] -- 分组
[HAVING condition] -- 对分组结果过滤
[ORDER BY column [ASC/DESC]] -- 排序
[LIMIT offset, count]; -- 分页
应用场景
查询唯一邮箱:SELECT DISTINCT email FROM users;按创建时间降序排序:SELECT * FROM users ORDER BY create_time DESC;分页查询(第 2 页,每页 10 条):SELECT * FROM users LIMIT 10, 10;
常用函数
函数类型函数名说明聚合函数COUNT()统计行数SUM()求和AVG()平均值字符串函数CONCAT()拼接字符串SUBSTRING()截取子字符串日期函数NOW()获取当前时间DATE_FORMAT()格式化日期
示例:统计用户数量
sql
SELECT COUNT(*) AS total_users FROM users;
2. 多表关联查询
内连接(INNER JOIN)
sql
SELECT u.username, o.order_id
FROM users u
INNER JOIN orders o ON u.user_id = o.user_id; -- 关联条件
左连接(LEFT JOIN)
sql
SELECT u.username, o.order_id
FROM users u
LEFT JOIN orders o ON u.user_id = o.user_id; -- 保留左表所有记录
右连接(RIGHT JOIN)
sql
SELECT u.username, o.order_id
FROM users u
RIGHT JOIN orders o ON u.user_id = o.user_id; -- 保留右表所有记录
注意事项
关联字段需有索引,否则影响查询性能。避免笛卡尔积(缺少关联条件导致结果集爆炸)。
3. 子查询
语法格式
sql
SELECT * FROM users
WHERE user_id IN (SELECT user_id FROM orders WHERE total_amount > 1000);
应用场景
查询有大额订单的用户信息。
五、DCL(数据控制语言)—— 权限管理
1. 用户管理
创建用户
sql
CREATE USER 'user1'@'localhost' IDENTIFIED BY 'password'; -- 本地用户
CREATE USER 'user2'@'%' IDENTIFIED BY 'password'; -- 允许远程访问
修改密码
sql
ALTER USER 'user1'@'localhost' IDENTIFIED WITH mysql_native_password BY 'new_password';
删除用户
sql
DROP USER 'user1'@'localhost';
2. 权限分配
语法格式
sql
GRANT privilege_type ON database.table TO 'user'@'host'; -- 授予权限
REVOKE privilege_type ON database.table FROM 'user'@'host'; -- 回收权限
常用权限
SELECT、INSERT、UPDATE、DELETE:表操作权限。ALL PRIVILEGES:所有权限(谨慎使用)。
示例:授予查询权限
sql
GRANT SELECT ON mydb.users TO 'viewer'@'localhost';
六、TCL(事务控制语言)
语法格式
sql
START TRANSACTION; -- 开启事务
INSERT INTO orders (order_id, user_id) VALUES (1001, 1);
UPDATE users SET balance = balance - 100 WHERE user_id = 1; -- 扣减余额
COMMIT; -- 提交事务(永久生效)
-- 若中途出错:
ROLLBACK; -- 回滚事务(撤销操作)
注意事项
事务需满足 ACID 特性(原子性、一致性、隔离性、持久性)。长事务可能导致锁竞争,需尽量缩短事务范围。
七、常见优化与最佳实践
索引优化
为查询条件字段(WHERE、JOIN、ORDER BY)添加索引。避免过度索引(影响写入性能),使用EXPLAIN分析查询执行计划。
sql
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com'; -- 查看索引使用情况
** 避免 SELECT * ** 只查询需要的字段,减少数据传输量:
sql
SELECT username, email FROM users;
批量操作 使用INSERT ... VALUES (...),(...)替代单条插入,提升效率。
八、思考与实践(待解决问题)
事务隔离级别如何选择?
不同隔离级别(如READ COMMITTED、REPEATABLE READ)的性能差异和适用场景是什么?参考:MySQL 事务隔离级别官方文档 索引失效的常见原因有哪些?
例如:使用函数计算字段、模糊查询以%开头、数据类型隐式转换等。 如何优化复杂的多表连接查询?
尝试改写子查询为 JOIN,或使用索引覆盖查询。
九、总结
本文系统整理了 MySQL 核心 SQL 语句,涵盖语法、场景、注意事项及优化策略。实际开发中需结合业务需求,遵循 “最小权限原则” 和 “性能优先原则”,并通过官方文档与实践持续深化理解。
参考资料:
MySQL 8.0 官方文档《高性能 MySQL》(第 3 版)SQL 注入防护指南