MySQL 常用 SQL 语句
1. 数据定义语言(DDL)
1.1 CREATE 语句
# 创建数据库
CREATE DATABASE database_name
[CHARACTER SET charset_name]
[COLLATE collation_name];
# 创建表
CREATE TABLE table_name (
column1 datatype [constraints],
column2 datatype [constraints],
...
[table_constraints]
) [ENGINE=engine_name];
# 示例:创建用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL,
email VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
1.2 ALTER 语句
# 修改表结构
ALTER TABLE table_name
[ADD column_name datatype [constraints]]
[MODIFY column_name datatype [constraints]]
[DROP column_name]
[RENAME TO new_table_name];
# 示例:添加列
ALTER TABLE users ADD phone VARCHAR(20);
# 示例:修改列属性
ALTER TABLE users MODIFY email VARCHAR(150) NOT NULL;
# 示例:添加索引
ALTER TABLE users ADD INDEX idx_username (username);
1.3 DROP 语句
# 删除数据库
DROP DATABASE database_name;
# 删除表
DROP TABLE table_name;
# 删除索引
DROP INDEX index_name ON table_name;
2. 数据操作语言(DML)
2.1 INSERT 语句
# 插入单行数据
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
# 插入多行数据
INSERT INTO table_name (column1, column2, ...)
VALUES
(value1, value2, ...),
(value1, value2, ...);
# 从其他表插入数据
INSERT INTO table1 (column1, column2, ...)
SELECT column1, column2, ...
FROM table2
WHERE condition;
2.2 UPDATE 语句
# 更新数据
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
# 示例:更新用户邮箱
UPDATE users
SET email = '[email protected]'
WHERE id = 1;
# 使用子查询更新
UPDATE table1 t1
SET column1 = (SELECT column2 FROM table2 t2 WHERE t1.id = t2.id);
2.3 DELETE 语句
# 删除数据
DELETE FROM table_name
WHERE condition;
# 示例:删除指定用户
DELETE FROM users
WHERE id = 1;
# 删除全表数据
DELETE FROM table_name;
# 使用 JOIN 删除数据
DELETE t1 FROM table1 t1
JOIN table2 t2 ON t1.id = t2.id
WHERE condition;
3. 数据查询语言(DQL)
3.1 基本查询
# 基本 SELECT 语句
SELECT column1, column2, ...
FROM table_name
WHERE condition
GROUP BY column
HAVING group_condition
ORDER BY column [ASC|DESC]
LIMIT offset, count;
# 示例:查询用户列表
SELECT id, username, email
FROM users
WHERE created_at >= '2024-01-01'
ORDER BY created_at DESC
LIMIT 10;
3.2 JOIN 查询
# INNER JOIN
SELECT t1.column1, t2.column2
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;
# LEFT JOIN
SELECT t1.column1, t2.column2
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id;
# RIGHT JOIN
SELECT t1.column1, t2.column2
FROM table1 t1
RIGHT JOIN table2 t2 ON t1.id = t2.id;
3.3 子查询
# WHERE 子句中的子查询
SELECT column1
FROM table1
WHERE column2 IN (SELECT column2 FROM table2);
# FROM 子句中的子查询
SELECT t1.column1
FROM (SELECT * FROM table2) t1;
# 相关子查询
SELECT *
FROM table1 t1
WHERE column1 > (
SELECT AVG(column1)
FROM table1 t2
WHERE t2.group = t1.group
);
4. 数据控制语言(DCL)
4.1 用户管理
# 创建用户
CREATE USER 'username'@'host'
IDENTIFIED BY 'password';
# 修改密码
ALTER USER 'username'@'host'
IDENTIFIED BY 'new_password';
# 删除用户
DROP USER 'username'@'host';
4.2 权限管理
# 授予权限
GRANT privilege_type
ON database_name.table_name
TO 'username'@'host';
# 撤销权限
REVOKE privilege_type
ON database_name.table_name
FROM 'username'@'host';
# 查看权限
SHOW GRANTS FOR 'username'@'host';
5. 事务控制语言(TCL)
# 开始事务
START TRANSACTION;
或
BEGIN;
# 提交事务
COMMIT;
# 回滚事务
ROLLBACK;
# 设置保存点
SAVEPOINT savepoint_name;
# 回滚到保存点
ROLLBACK TO savepoint_name;
注意事项
- 在执行 DELETE 或 UPDATE 操作前,建议 先用 SELECT 验证条件
- 大批量数据操作时,注意使用事务和批量操作语句
- 复杂查询要注意性能优化,可以通过 EXPLAIN 分析执行计划
- 使用 JOIN 时要注意连接条件,避免笛卡尔积
- 合理使用索引提高查询性能
最佳实践
- 使用预处理语句防止 SQL 注入
- 使用合适的字段类型和长度
- 遵循最小权限原则进行权限管理
- 合理使用事务确保数据一致性
- 定期检查和优化 SQL 语句性能
6. MySQL 5.7 与 8.0 SQL 使用差异
6.1 GROUP BY 语句
-- MySQL 5.7
-- GROUP BY 隐式排序
SELECT name, COUNT(*)
FROM users
GROUP BY name; -- 结果会自动按 name 排序
-- MySQL 8.0
-- GROUP BY 不再隐式排序
SELECT name, COUNT(*)
FROM users
GROUP BY name; -- 结果不保证顺序
-- 如需排序,必须显式指定
SELECT name, COUNT(*)
FROM users
GROUP BY name
ORDER BY name;
6.2 用户管理和权限
-- MySQL 5.7
GRANT ALL PRIVILEGES ON database.* TO 'user'@'host' IDENTIFIED BY 'password';
-- MySQL 8.0
-- 需要先创建用户,再授权
CREATE USER 'user'@'host' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON database.* TO 'user'@'host';
6.3 默认认证方式
-- MySQL 5.7
-- 默认使用 mysql_native_password
-- MySQL 8.0
-- 默认使用 caching_sha2_password
-- 如需使用旧认证方式,需要显式指定
CREATE USER 'user'@'host'
IDENTIFIED WITH mysql_native_password BY 'password';
-- 或修改已有用户的认证方式
ALTER USER 'user'@'host'
IDENTIFIED WITH mysql_native_password BY 'password';
6.4 索引
-- MySQL 8.0 新增功能:不可见索引
CREATE INDEX idx_name ON users(name) INVISIBLE;
ALTER TABLE users ALTER INDEX idx_name VISIBLE;
-- MySQL 8.0 新增功能:降序索引
CREATE INDEX idx_age_desc ON users(age DESC);
-- MySQL 8.0 新增功能:函数索引
CREATE INDEX idx_upper_name ON users((UPPER(name)));
6.5 公用表表达式(CTE)
-- MySQL 8.0 新增功能:WITH 子句
WITH RECURSIVE cte AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;
6.6 窗口函数
-- MySQL 8.0 新增功能:窗口函数
SELECT
name,
salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) as salary_rank,
LAG(salary) OVER (ORDER BY salary DESC) as prev_salary
FROM employees;
6.7 CHECK 约束
-- MySQL 8.0 新增功能:CHECK 约束
CREATE TABLE employees (
id INT PRIMARY KEY,
age INT CHECK (age >= 18),
salary DECIMAL(10,2) CHECK (salary > 0)
);
6.8 JSON 功能增强
-- MySQL 5.7
-- 基本 JSON 操作
SELECT JSON_EXTRACT(data, '$.name') FROM users;
-- MySQL 8.0
-- 新增 JSON 表格函数
SELECT * FROM
JSON_TABLE(
'[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]',
'$[*]' COLUMNS(
name VARCHAR(50) PATH '$.name',
age INT PATH '$.age'
)
) AS jt;
6.9 其他重要差异
-
字符集:
- 5.7 默认字符集为 latin1
- 8.0 默认字符集为 utf8mb4
-
临时表:
- 5.7 使用 MEMORY 存储引擎
- 8.0 使用 TempTable 存储引擎
-
自增列:
- 8.0 自增列值持久化到重启后
-
外键命名:
- 8.0 支持显式指定外键名称
注意事项:
- 升级到 8.0 时需要注意认证方式的变化
- GROUP BY 语句可能需要显式添加 ORDER BY
- 创建用户和授权需要分开操作
- 注意默认字符集的变化
- 可以利用 8.0 的新特性优化查询性能
6.10 修改密码方式的差异
-- MySQL 5.7 修改密码的方式:
-- 方式1:使用 SET PASSWORD 命令
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
-- 方式2:使用 UPDATE 命令直接更新 mysql.user 表
UPDATE mysql.user
SET authentication_string = PASSWORD('new_password')
WHERE User = 'root' AND Host = 'localhost';
FLUSH PRIVILEGES;
-- 方式3:使用 GRANT 命令
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'new_password';
-- MySQL 8.0 修改密码的方式:
-- 方式1:使用 ALTER USER 命令(推荐)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
-- 方式2:使用 SET PASSWORD 命令(新语法)
SET PASSWORD FOR 'root'@'localhost' = 'new_password';
-- 或者当前用户
SET PASSWORD = 'new_password';
-- 注意:MySQL 8.0 中
-- 1. 移除了 PASSWORD() 函数
-- 2. 不再支持通过直接更新 mysql.user 表的方式修改密码
-- 3. GRANT 命令不再支持同时设置密码
主要区别:
- MySQL 8.0 移除了 PASSWORD() 函数
- MySQL 8.0 不再支持直接更新用户表修改密码
- MySQL 8.0 的 GRANT 语句不再包含设置密码的功能
- MySQL 8.0 推荐使用 ALTER USER 命令修改密码
- MySQL 8.0 的密码管理更加严格和安全