文章目录
-
- [一、SQL 基础](#一、SQL 基础)
-
- [1.1 SQL 语法规范](#1.1 SQL 语法规范)
- [1.2 SQL 分类体系](#1.2 SQL 分类体系)
- 二、数据库管理(DDL)
-
- [2.1 数据库生命周期管理](#2.1 数据库生命周期管理)
-
- [2.1.1 创建数据库](#2.1.1 创建数据库)
- [2.1.2 数据库维护](#2.1.2 数据库维护)
- [2.1.3 数据库连接管理](#2.1.3 数据库连接管理)
- [2.2 表结构设计与管理](#2.2 表结构设计与管理)
-
- [2.2.1 数据类型详解](#2.2.1 数据类型详解)
- [2.2.2 创建表](#2.2.2 创建表)
- [2.2.3 表结构维护](#2.2.3 表结构维护)
- 三、数据操作(DML)
-
- [3.1 插入数据](#3.1 插入数据)
- [3.2 更新数据](#3.2 更新数据)
- [3.3 删除数据](#3.3 删除数据)
- 四、数据查询(DQL)
-
- [4.1 查询基础](#4.1 查询基础)
-
- [4.1.1 基本语法结构](#4.1.1 基本语法结构)
- [4.1.2 选择列](#4.1.2 选择列)
- [4.2 条件查询](#4.2 条件查询)
-
- [4.2.1 比较运算符](#4.2.1 比较运算符)
- [4.2.2 范围查询](#4.2.2 范围查询)
- [4.2.3 模糊查询](#4.2.3 模糊查询)
- [4.3 排序与分页](#4.3 排序与分页)
-
- [4.3.1 排序](#4.3.1 排序)
- [4.3.2 分页查询](#4.3.2 分页查询)
- [4.4 聚合查询](#4.4 聚合查询)
-
- [4.4.1 聚合函数](#4.4.1 聚合函数)
- [4.4.2 分组查询](#4.4.2 分组查询)
- [4.5 连接查询](#4.5 连接查询)
-
- [4.5.1 内连接](#4.5.1 内连接)
- [4.5.2 外连接](#4.5.2 外连接)
- [4.5.3 交叉连接](#4.5.3 交叉连接)
- [4.6 子查询](#4.6 子查询)
-
- [4.6.1 标量子查询](#4.6.1 标量子查询)
- [4.6.2 行子查询](#4.6.2 行子查询)
- [4.6.3 表子查询](#4.6.3 表子查询)
- [4.6.4 相关子查询](#4.6.4 相关子查询)
- [4.7 集合操作](#4.7 集合操作)
- 五、高级特性
-
- [5.1 视图](#5.1 视图)
- [5.2 索引](#5.2 索引)
- [5.3 事务控制](#5.3 事务控制)
- [5.4 存储过程与函数](#5.4 存储过程与函数)
- 六、性能优化
-
- [6.1 查询优化原则](#6.1 查询优化原则)
- [6.2 索引优化策略](#6.2 索引优化策略)
- [6.3 查询缓存](#6.3 查询缓存)
- 七、安全管理
-
- [7.1 用户权限管理](#7.1 用户权限管理)
- [7.2 数据备份与恢复](#7.2 数据备份与恢复)
一、SQL 基础
1.1 SQL 语法规范
-- 书写规范
SELECT * FROM users; -- 以分号结尾
SELECT * -- 可多行书写
FROM users
WHERE age > 18;
-- 大小写(建议)
SELECT * FROM users; -- 关键字大写,表名小写
select * from users; -- MySQL 不区分,都可执行
1.2 SQL 分类体系
| 类别 |
全称 |
作用 |
关键命令 |
| DDL |
数据定义语言 |
定义数据库对象 |
CREATE, DROP, ALTER |
| DML |
数据操纵语言 |
操作数据记录 |
INSERT, DELETE, UPDATE |
| DQL |
数据查询语言 |
查询数据 |
SELECT, WHERE, JOIN |
| DCL |
数据控制语言 |
控制访问权限 |
GRANT, REVOKE |
二、数据库管理(DDL)
2.1 数据库生命周期管理
2.1.1 创建数据库
-- 基础创建
CREATE DATABASE school;
-- 安全创建(避免重复)
CREATE DATABASE IF NOT EXISTS school;
-- 创建时指定字符集
CREATE DATABASE school
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 完整语法
CREATE DATABASE [IF NOT EXISTS] database_name
[CHARACTER SET charset_name]
[COLLATE collation_name];
2.1.2 数据库维护
-- 查询所有数据库
SHOW DATABASES;
-- 查看数据库信息
SHOW CREATE DATABASE school;
-- 修改数据库字符集
ALTER DATABASE school CHARACTER SET utf8;
-- 删除数据库
DROP DATABASE school;
DROP DATABASE IF EXISTS school; -- 安全删除
2.1.3 数据库连接管理
-- 使用数据库
USE school;
-- 查看当前数据库
SELECT DATABASE();
-- 查看连接信息
SHOW PROCESSLIST;
2.2 表结构设计与管理
2.2.1 数据类型详解
| 类别 |
类型 |
描述 |
示例 |
| 数值型 |
INT |
整数 |
age INT |
|
BIGINT |
大整数 |
id BIGINT |
|
DECIMAL |
精确小数 |
price DECIMAL(10,2) |
|
FLOAT/DOUBLE |
浮点数 |
score DOUBLE |
| 字符串 |
CHAR |
定长字符串 |
gender CHAR(1) |
|
VARCHAR |
变长字符串 |
name VARCHAR(50) |
|
TEXT |
长文本 |
content TEXT |
| 日期时间 |
DATE |
日期 |
birthday DATE |
|
DATETIME |
日期时间 |
create_time DATETIME |
|
TIMESTAMP |
时间戳 |
update_time TIMESTAMP |
| 其他 |
BLOB |
二进制数据 |
image BLOB |
|
BOOLEAN |
布尔值 |
is_active BOOLEAN |
2.2.2 创建表
-- 基础表创建
CREATE TABLE students (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT DEFAULT 18,
email VARCHAR(100) UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
);
-- 带索引和约束
CREATE TABLE courses (
course_id INT PRIMARY KEY,
course_name VARCHAR(100) NOT NULL,
credit DECIMAL(3,1),
teacher_id INT,
INDEX idx_teacher (teacher_id),
CONSTRAINT chk_credit CHECK (credit BETWEEN 0 AND 10)
);
2.2.3 表结构维护
-- 查看表结构
DESC students;
DESCRIBE students;
SHOW COLUMNS FROM students;
-- 查看建表语句
SHOW CREATE TABLE students;
-- 修改表名
ALTER TABLE students RENAME TO new_students;
RENAME TABLE students TO new_students;
-- 修改表字符集
ALTER TABLE students CHARACTER SET utf8mb4;
-- 添加列
ALTER TABLE students ADD COLUMN phone VARCHAR(20);
-- 修改列
ALTER TABLE students CHANGE COLUMN phone mobile VARCHAR(15);
ALTER TABLE students MODIFY COLUMN mobile VARCHAR(20);
-- 删除列
ALTER TABLE students DROP COLUMN mobile;
-- 复制表结构
CREATE TABLE students_backup LIKE students;
-- 复制表结构和数据
CREATE TABLE students_copy AS SELECT * FROM students;
-- 删除表
DROP TABLE IF EXISTS students;
三、数据操作(DML)
3.1 插入数据
-- 指定列插入
INSERT INTO students (name, age, email)
VALUES ('张三', 20, 'zhangsan@example.com');
-- 插入多行数据
INSERT INTO students (name, age, email) VALUES
('李四', 21, 'lisi@example.com'),
('王五', 22, 'wangwu@example.com'),
('赵六', 23, 'zhaoliu@example.com');
-- 插入查询结果
INSERT INTO student_archive
SELECT * FROM students WHERE graduation_year < 2020;
-- 使用 SET 语法
INSERT INTO students
SET name = '张三', age = 20, email = 'zhangsan@example.com';
-- 忽略重复键
INSERT IGNORE INTO students (id, name) VALUES (1, '张三');
3.2 更新数据
-- 单表更新
UPDATE students
SET age = age + 1,
updated_at = NOW()
WHERE id = 1;
-- 使用子查询更新
UPDATE students s
JOIN classes c ON s.class_id = c.id
SET s.status = 'graduated'
WHERE c.graduation_year = 2023;
-- 批量更新
UPDATE products
SET price = price * 0.9
WHERE category = 'electronics';
-- 使用 CASE 条件更新
UPDATE students
SET grade = CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
ELSE 'D'
END;
3.3 删除数据
-- 条件删除
DELETE FROM students WHERE id = 1;
-- 关联删除
DELETE s FROM students s
JOIN scores sc ON s.id = sc.student_id
WHERE sc.score < 60;
-- 清空表数据的不同方式
DELETE FROM students; -- 逐行删除,可回滚
TRUNCATE TABLE students; -- 快速清空,不可回滚
DROP TABLE students; -- 删除表结构和数据
-- 使用 JOIN 删除
DELETE s, sc
FROM students s
LEFT JOIN scores sc ON s.id = sc.student_id
WHERE s.graduation_year < 2020;
四、数据查询(DQL)
4.1 查询基础
4.1.1 基本语法结构
SELECT [DISTINCT] column_list
FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}]
[HAVING having_condition]
[ORDER BY {col_name | expr | position} [ASC | DESC]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[FOR UPDATE | LOCK IN SHARE MODE]
4.1.2 选择列
-- 选择所有列
SELECT * FROM students;
-- 选择特定列
SELECT id, name, age FROM students;
-- 使用表达式
SELECT
name,
age,
YEAR(NOW()) - YEAR(birthdate) AS current_age,
CONCAT(name, '(', age, ')') AS name_with_age
FROM students;
-- 去除重复
SELECT DISTINCT class_id FROM students;
-- 使用别名
SELECT
s.name AS student_name,
c.name AS class_name
FROM students s
JOIN classes c ON s.class_id = c.id;
4.2 条件查询
4.2.1 比较运算符
-- 基本比较
SELECT * FROM students WHERE age > 20;
SELECT * FROM products WHERE price <= 100;
SELECT * FROM users WHERE status = 'active';
-- NULL 值处理
SELECT * FROM students WHERE email IS NULL;
SELECT * FROM students WHERE email IS NOT NULL;
-- NULL 安全比较
SELECT * FROM students WHERE age <=> NULL;
4.2.2 范围查询
-- BETWEEN
SELECT * FROM students WHERE age BETWEEN 18 AND 25;
-- IN
SELECT * FROM students WHERE class_id IN (1, 3, 5);
SELECT * FROM students WHERE class_id NOT IN (2, 4);
-- 使用子查询
SELECT * FROM students
WHERE class_id IN (SELECT id FROM classes WHERE teacher = '王老师');
4.2.3 模糊查询
-- % 匹配任意字符
SELECT * FROM students WHERE name LIKE '张%';
SELECT * FROM students WHERE name LIKE '%三%';
-- _ 匹配单个字符
SELECT * FROM students WHERE name LIKE '_三';
SELECT * FROM students WHERE name LIKE '张_';
-- 转义特殊字符
SELECT * FROM products WHERE name LIKE '%100%%' ESCAPE '';
-- 正则表达式
SELECT * FROM students WHERE name REGEXP '^张';
SELECT * FROM students WHERE email REGEXP '@gmail\.com$';
4.3 排序与分页
4.3.1 排序
-- 单字段排序
SELECT * FROM students ORDER BY age DESC;
-- 多字段排序
SELECT * FROM students
ORDER BY class_id ASC, score DESC;
-- 使用表达式排序
SELECT * FROM students
ORDER BY
CASE WHEN grade = 'A' THEN 1
WHEN grade = 'B' THEN 2
ELSE 3
END,
score DESC;
-- NULL 值排序
SELECT * FROM students
ORDER BY score IS NULL, score DESC;
4.3.2 分页查询
-- 基础分页
SELECT * FROM students LIMIT 10 OFFSET 0; -- 第1页
SELECT * FROM students LIMIT 10 OFFSET 10; -- 第2页
-- 简写形式
SELECT * FROM students LIMIT 0, 10; -- 第1页
SELECT * FROM students LIMIT 10, 10; -- 第2页
-- 动态分页
SET @page = 2;
SET @page_size = 10;
SELECT * FROM students
LIMIT @page_size
OFFSET (@page - 1) * @page_size;
-- 结合排序的分页
SELECT * FROM students
ORDER BY created_at DESC
LIMIT 10 OFFSET 0;
4.4 聚合查询
4.4.1 聚合函数
-- COUNT 计数
SELECT COUNT(*) FROM students;
SELECT COUNT(DISTINCT class_id) FROM students;
SELECT COUNT(id) FROM students WHERE age > 20;
-- SUM 求和
SELECT SUM(score) FROM exams;
SELECT SUM(score) AS total_score FROM exams WHERE student_id = 1;
-- AVG 平均值
SELECT AVG(score) FROM exams;
SELECT AVG(score) AS average_score FROM exams WHERE exam_date = '2023-06-01';
-- MAX/MIN 最值
SELECT MAX(score), MIN(score) FROM exams;
SELECT name, MAX(score) AS highest_score FROM students s
JOIN exams e ON s.id = e.student_id
GROUP BY s.id;
-- GROUP_CONCAT 组内连接
SELECT class_id,
GROUP_CONCAT(name ORDER BY score DESC) AS student_list
FROM students
GROUP BY class_id;
4.4.2 分组查询
-- 基本分组
SELECT class_id, COUNT(*) AS student_count
FROM students
GROUP BY class_id;
-- 多字段分组
SELECT class_id, gender, COUNT(*) AS count
FROM students
GROUP BY class_id, gender;
-- HAVING 筛选分组
SELECT class_id, AVG(score) AS avg_score
FROM students
GROUP BY class_id
HAVING AVG(score) > 80;
-- ROLLUP 汇总
SELECT class_id, gender, COUNT(*)
FROM students
GROUP BY class_id, gender WITH ROLLUP;
-- 分组排序
SELECT class_id, name, score
FROM students
ORDER BY class_id, score DESC;
4.5 连接查询
4.5.1 内连接
-- 等值连接
SELECT s.name, c.class_name
FROM students s
INNER JOIN classes c ON s.class_id = c.id;
-- 多表连接
SELECT s.name, c.class_name, t.teacher_name
FROM students s
INNER JOIN classes c ON s.class_id = c.id
INNER JOIN teachers t ON c.teacher_id = t.id;
-- 自连接
SELECT e1.employee_name, e2.employee_name AS manager_name
FROM employees e1
INNER JOIN employees e2 ON e1.manager_id = e2.id;
4.5.2 外连接
-- 左外连接
SELECT s.name, c.class_name
FROM students s
LEFT JOIN classes c ON s.class_id = c.id;
-- 右外连接
SELECT s.name, c.class_name
FROM students s
RIGHT JOIN classes c ON s.class_id = c.id;
-- 全外连接(MySQL 模拟)
SELECT s.name, c.class_name
FROM students s
LEFT JOIN classes c ON s.class_id = c.id
UNION
SELECT s.name, c.class_name
FROM students s
RIGHT JOIN classes c ON s.class_id = c.id
WHERE s.id IS NULL;
4.5.3 交叉连接
-- 显式交叉连接
SELECT s.name, c.course_name
FROM students s
CROSS JOIN courses c;
-- 隐式交叉连接
SELECT s.name, c.course_name
FROM students s, courses c;
4.6 子查询
4.6.1 标量子查询
-- WHERE 子句
SELECT * FROM students
WHERE age > (SELECT AVG(age) FROM students);
-- SELECT 子句
SELECT name,
(SELECT COUNT(*) FROM scores WHERE student_id = s.id) AS score_count
FROM students s;
-- HAVING 子句
SELECT class_id, AVG(score)
FROM students
GROUP BY class_id
HAVING AVG(score) > (SELECT AVG(score) FROM students);
4.6.2 行子查询
SELECT * FROM students
WHERE (class_id, score) IN (
SELECT class_id, MAX(score)
FROM students
GROUP BY class_id
);
4.6.3 表子查询
-- 派生表
SELECT s.name, t.avg_score
FROM students s
JOIN (
SELECT student_id, AVG(score) AS avg_score
FROM scores
GROUP BY student_id
HAVING AVG(score) > 80
) t ON s.id = t.student_id;
-- 使用 WITH 子句(CTE)
WITH top_students AS (
SELECT student_id, AVG(score) AS avg_score
FROM scores
GROUP BY student_id
HAVING AVG(score) > 90
)
SELECT s.name, ts.avg_score
FROM students s
JOIN top_students ts ON s.id = ts.student_id;
4.6.4 相关子查询
-- EXISTS
SELECT * FROM students s
WHERE EXISTS (
SELECT 1 FROM scores sc
WHERE sc.student_id = s.id AND sc.score = 100
);
-- NOT EXISTS
SELECT * FROM classes c
WHERE NOT EXISTS (
SELECT 1 FROM students s
WHERE s.class_id = c.id AND s.gender = '女'
);
4.7 集合操作
-- UNION(去重)
SELECT name FROM current_students
UNION
SELECT name FROM graduated_students;
-- UNION ALL(不去重)
SELECT name FROM current_students
UNION ALL
SELECT name FROM graduated_students;
-- INTERSECT(交集)- MySQL 8.0+
SELECT name FROM students
INTERSECT
SELECT name FROM honors_students;
-- EXCEPT(差集)- MySQL 8.0+
SELECT name FROM students
EXCEPT
SELECT name FROM failed_students;
五、高级特性
5.1 视图
-- 创建视图
CREATE VIEW student_scores AS
SELECT s.name, sc.course, sc.score
FROM students s
JOIN scores sc ON s.id = sc.student_id;
-- 带检查选项
CREATE VIEW active_students AS
SELECT * FROM students WHERE status = 'active'
WITH CHECK OPTION;
-- 更新视图
ALTER VIEW student_scores AS
SELECT s.name, sc.course, sc.score, sc.exam_date
FROM students s
JOIN scores sc ON s.id = sc.student_id;
-- 删除视图
DROP VIEW IF EXISTS student_scores;
5.2 索引
-- 创建索引
CREATE INDEX idx_student_name ON students(name);
CREATE INDEX idx_student_class ON students(class_id, name);
CREATE FULLTEXT INDEX idx_content ON articles(content);
-- 查看索引
SHOW INDEX FROM students;
-- 删除索引
DROP INDEX idx_student_name ON students;
-- 分析索引使用
EXPLAIN SELECT * FROM students WHERE name = '张三';
5.3 事务控制
-- 开启事务
START TRANSACTION;
BEGIN;
-- 设置保存点
SAVEPOINT sp1;
-- 回滚到保存点
ROLLBACK TO sp1;
-- 提交事务
COMMIT;
-- 设置事务隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 查看隔离级别
SELECT @@transaction_isolation;
5.4 存储过程与函数
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE GetStudentCount(IN classId INT, OUT total INT)
BEGIN
SELECT COUNT(*) INTO total
FROM students
WHERE class_id = classId;
END //
DELIMITER ;
-- 调用存储过程
CALL GetStudentCount(1, @count);
SELECT @count;
-- 创建函数
DELIMITER //
CREATE FUNCTION GetStudentName(studentId INT)
RETURNS VARCHAR(50)
READS SQL DATA
BEGIN
DECLARE studentName VARCHAR(50);
SELECT name INTO studentName
FROM students
WHERE id = studentId;
RETURN studentName;
END //
DELIMITER ;
-- 使用函数
SELECT GetStudentName(1);
六、性能优化
6.1 查询优化原则
- 使用合适的索引
- 避免 SELECT
- 合理使用 JOIN
- 避免在 WHERE 子句中使用函数
- 使用 EXPLAIN 分析查询
6.2 索引优化策略
-- 复合索引最左前缀原则
CREATE INDEX idx_name_age ON students(name, age);
-- 有效查询: WHERE name = ? AND age = ?
-- 有效查询: WHERE name = ?
-- 无效查询: WHERE age = ?
-- 覆盖索引
CREATE INDEX idx_covering ON students(name, age, email);
SELECT name, age FROM students WHERE name = '张三'; -- 使用覆盖索引
-- 索引下推(MySQL 5.6+)
SET optimizer_switch = 'index_condition_pushdown=on';
6.3 查询缓存
-- 查看查询缓存状态
SHOW VARIABLES LIKE 'query_cache%';
-- 使用 SQL_CACHE
SELECT SQL_CACHE * FROM students WHERE id = 1;
-- 使用 SQL_NO_CACHE
SELECT SQL_NO_CACHE * FROM large_table;
七、安全管理
7.1 用户权限管理
-- 创建用户
CREATE USER 'readonly'@'localhost' IDENTIFIED BY 'password';
-- 授予权限
GRANT SELECT ON school.* TO 'readonly'@'localhost';
GRANT INSERT, UPDATE ON school.students TO 'editor'@'%';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
-- 回收权限
REVOKE INSERT ON school.students FROM 'editor'@'%';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'admin'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
7.2 数据备份与恢复
-- 导出数据(命令行)
mysqldump -u root -p school > school_backup.sql
-- 导入数据
mysql -u root -p school < school_backup.sql
-- 导出特定表
mysqldump -u root -p school students courses > tables_backup.sql