-- 书写规范
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 创建数据库
sql复制代码
-- 基础创建
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 数据库维护
sql复制代码
-- 查询所有数据库
SHOW DATABASES;
-- 查看数据库信息
SHOW CREATE DATABASE school;
-- 修改数据库字符集
ALTER DATABASE school CHARACTER SET utf8;
-- 删除数据库
DROP DATABASE school;
DROP DATABASE IF EXISTS school; -- 安全删除
2.1.3 数据库连接管理
sql复制代码
-- 使用数据库
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 创建表
sql复制代码
-- 基础表创建
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 表结构维护
sql复制代码
-- 查看表结构
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 插入数据
sql复制代码
-- 指定列插入
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 更新数据
sql复制代码
-- 单表更新
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 删除数据
sql复制代码
-- 条件删除
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 基本语法结构
sql复制代码
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 选择列
sql复制代码
-- 选择所有列
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 比较运算符
sql复制代码
-- 基本比较
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 范围查询
sql复制代码
-- 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 模糊查询
sql复制代码
-- % 匹配任意字符
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 排序
sql复制代码
-- 单字段排序
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 分页查询
sql复制代码
-- 基础分页
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 聚合函数
sql复制代码
-- 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 分组查询
sql复制代码
-- 基本分组
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 内连接
sql复制代码
-- 等值连接
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 外连接
sql复制代码
-- 左外连接
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 交叉连接
sql复制代码
-- 显式交叉连接
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 标量子查询
sql复制代码
-- 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 行子查询
sql复制代码
SELECT * FROM students
WHERE (class_id, score) IN (
SELECT class_id, MAX(score)
FROM students
GROUP BY class_id
);
4.6.3 表子查询
sql复制代码
-- 派生表
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 相关子查询
sql复制代码
-- 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 集合操作
sql复制代码
-- 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 视图
sql复制代码
-- 创建视图
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 索引
sql复制代码
-- 创建索引
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 = '张三';
-- 创建存储过程
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 索引优化策略
sql复制代码
-- 复合索引最左前缀原则
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 查询缓存
sql复制代码
-- 查看查询缓存状态
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 用户权限管理
sql复制代码
-- 创建用户
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 数据备份与恢复
sql复制代码
-- 导出数据(命令行)
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