一、SQL 概述
SQL(Structured Query Language,结构化查询语言)是管理关系型数据库的标准语言,如同数据库的“指挥官”,通过不同类型的语句操控数据库,实现数据的增删改查等操作。其主要分为以下几类语句(如图 1:SQL 分类示意图,该图以清晰的层级或分区形式,分别标注数据查询语言(DQL)、数据操作语言(DML)、数据定义语言(DDL)、数据控制语言(DCL)、事务控制语言(TCL),直观展示各类语句的分类结构):
• 数据查询语言(DQL):以 SELECT 语句为代表,用于从数据库中检索数据,如从员工表中找出薪资高于某个值的员工信息。
• 数据操作语言(DML):包含 INSERT(插入数据)、UPDATE(更新数据)、DELETE(删除数据)语句,用于对数据进行具体操作。
• 数据定义语言(DDL):如 CREATE(创建数据库对象)、ALTER(修改数据库对象结构)、DROP(删除数据库对象)等,用于定义和管理数据库结构。
• 数据控制语言(DCL):主要是 GRANT(授予用户权限)和 REVOKE(收回用户权限),用于控制用户对数据库的访问权限。
• 事务控制语言(TCL):例如 COMMIT(提交事务)、ROLLBACK(回滚事务)、SAVEPOINT(设置保存点),用于管理数据库事务,保证数据操作的一致性和完整性。
二、数据查询语言(DQL)
SELECT 语句
• 基本语法:
SELECT [DISTINCT] column1, column2, ...
FROM table_name
[WHERE condition]
[GROUP BY column1, column2, ...]
[HAVING group_condition]
[ORDER BY column1 [ASC|DESC], ...]
[LIMIT offset, count];
• 使用规范:关键字大写增强可读性;表名和列名采用小写加下划线命名法;复杂查询使用缩进和换行。
• 应用场景:单表或多表检索数据(如订单表与客户表连接查询特定时间段订单)、聚合计算(统计各部门平均薪资)、数据排序和筛选(按销售额降序排列商品)。
• 常见错误:GROUP BY 子句遗漏非聚合列;混淆 WHERE(行级过滤,分组前筛选)与 HAVING(组级过滤,分组聚合后筛选)的使用时机。
• 实战示例:
-- 多表连接查询
SELECT e.employee_id, e.name, d.department_name, j.job_title
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN jobs j ON e.job_id = j.job_id
WHERE e.hire_date BETWEEN '2019-01-01' AND '2021-12-31'
ORDER BY d.department_name, e.name;
-- 使用窗口函数
SELECT
employee_id,
name,
salary,
department,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as dept_rank
FROM employees;
三、数据操作语言(DML)
INSERT 语句
• 基本语法(支持单行、多行及从其他表插入):
-- 单行插入
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);
-- 多行插入
INSERT INTO table_name (column1, column2, ...)
VALUES
(value1, value2, ...),
(value1, value2, ...),
...;
-- 从其他表插入
INSERT INTO table_name (column1, column2, ...)
SELECT column1, column2, ...
FROM source_table
WHERE condition;
• 使用规范:明确指定列名;批量插入控制行数(500 - 1000 行);大容量插入考虑高效方式(如 MySQL 的 LOAD DATA INFILE)。
• 常见错误:列与值数量不匹配、违反约束、未处理 NULL 值。
• 实战示例:
-- 安全插入示例
INSERT INTO employees (emp_id, name, email, hire_date)
VALUES
(1001, '张三', 'zhangsan@example.com', '2023-01-15'),
(1002, '李四', 'lisi@example.com', '2023-02-20')
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email);
-- 从临时表插入
INSERT INTO product_sales (product_id, sale_date, quantity)
SELECT p.product_id, CURRENT_DATE, t.quantity
FROM temp_import t
JOIN products p ON t.product_code = p.code;
UPDATE 语句
• 基本语法:
UPDATE table_name
SET column1 = value1, column2 = value2, ...
[WHERE condition]
[ORDER BY column1, ...]
[LIMIT row_count];
• 使用规范:必须包含 WHERE 条件(除非更新所有行);大批量更新分批进行;更新前用 SELECT 验证条件。
• 常见错误:忘记 WHERE 条件致全表更新、多表更新语法错、未考虑触发器影响。
• 实战示例:
-- 安全更新示例
UPDATE employees
SET salary = salary * 1.05
WHERE department = 'IT' AND performance_rating >= 4;
-- 使用 `JOIN` 更新
UPDATE orders o
JOIN customers c ON o.customer_id = c.customer_id
SET o.discount = 0.1
WHERE c.membership_level = 'GOLD'
AND o.order_date >= '2023-01-01';
DELETE 语句
• 基本语法:
DELETE FROM table_name
[WHERE condition]
[ORDER BY column1, ...]
[LIMIT row_count];
• 使用规范:包含 WHERE 条件;删除前备份数据;大表分批删除。
• 常见错误:忘记 WHERE 条件致全表删除、未考虑外键约束、未关闭自动提交致误删无法回滚。
• 实战示例:
-- 安全删除示例
-- 先验证要删除的记录
SELECT * FROM log_entries
WHERE created_at < '2022-01-01';
-- 再执行删除
DELETE FROM log_entries
WHERE created_at < '2022-01-01'
LIMIT 1000; -- 分批删除
-- 使用事务确保安全
BEGIN;
DELETE FROM order_items WHERE order_id = 1001;
DELETE FROM orders WHERE order_id = 1001;
COMMIT;
四、数据定义语言(DDL)
CREATE 语句
• 常用 CREATE 语句(创建数据库、表、索引):
-- 创建数据库
CREATE DATABASE db_name
[CHARACTER SET charset_name]
[COLLATE collation_name];
-- 创建表
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] table_name (
column1 datatype [column_constraint],
column2 datatype [column_constraint],
...,
[table_constraint]
) [ENGINE=engine_name] [CHARACTER SET charset_name];
-- 创建索引
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
ON table_name (column1 [ASC|DESC], ...);
• 使用规范:表名和列名有意义;选合适数据类型;定义主键和约束;为常用查询条件创建索引。
• 常见错误:过度用 TEXT/BLOB 类型、未设置主键、索引过多影响写入性能。
• 实战示例:
-- 添加新列
ALTER TABLE employees
ADD COLUMN mobile VARCHAR(20) AFTER email;
-- 修改列类型
-- 先检查数据是否兼容
SELECT MAX(LENGTH(notes)) FROM products;
-- 再执行修改
ALTER TABLE products
MODIFY COLUMN notes TEXT;
-- 添加外键约束
ALTER TABLE orders
ADD CONSTRAINT fk_customer
FOREIGN KEY (customer_id) REFERENCES customers(customer_id);
DROP 语句
• 基本语法(删除表、数据库、索引、视图):
DROP TABLE [IF EXISTS] table_name;
DROP DATABASE [IF EXISTS] db_name;
DROP INDEX index_name ON table_name;
DROP VIEW [IF EXISTS] view_name;
• 使用规范:生产环境执行前备份;检查对象依赖关系;用 IF EXISTS 避免错误。
• 常见错误:误删生产表、未删除依赖对象、未考虑级联删除影响。
五、数据控制语言(DCL)
GRANT 和 REVOKE
• 基本语法(授权与撤销权限):
-- 授权
GRANT privilege1, privilege2, ...
ON database_name.table_name
TO 'username'@'host';
-- 撤销权限
REVOKE privilege1, privilege2, ...
ON database_name.table_name
FROM 'username'@'host';
-- 示例
GRANT SELECT, INSERT ON mydb.* TO 'app_user'@'%';
REVOKE DELETE ON mydb.sensitive_table FROM 'app_user'@'%';
• 使用规范:遵循最小权限原则;定期审查权限;为不同应用创建单独用户。
• 常见错误:授予过多权限、使用通配符主机(‘%’)不安全、忘记刷新权限(FLUSH PRIVILEGES)。
六、事务控制语言(TCL)
• 事务语句:
START TRANSACTION; -- 或 BEGIN
-- SQL 语句
COMMIT; -- 或 ROLLBACK
SAVEPOINT savepoint_name;
ROLLBACK TO savepoint_name;
• 使用规范:保持事务短小;避免事务中用户交互;处理事务异常。
• 常见错误:长事务导致锁竞争;未处理事务异常;嵌套事务使用不当。
• 实战示例:
-- 事务示例
START TRANSACTION;
INSERT INTO orders (order_date, customer_id, total)
VALUES (CURRENT_DATE, 1001, 500.00);
-- 获取最后插入的 ID
SET @order_id = LAST_INSERT_ID();
INSERT INTO order_items (order_id, product_id, quantity, price)
VALUES
(@order_id, 101, 2, 100.00),
(@order_id, 205, 1, 300.00);
-- 验证库存
SELECT product_id, quantity FROM inventory
WHERE product_id IN (101, 205) FOR UPDATE;
UPDATE inventory
SET quantity = quantity - CASE product_id
WHEN 101 THEN 2
WHEN 205 THEN 1
END
WHERE product_id IN (101, 205);
COMMIT;
七、高级 SQL 特性
公用表表达式(CTE)
CTE 是临时命名结果集,可在查询中复用。例如:
WITH department_stats AS (
SELECT
department_id,
COUNT(*) as emp_count,
AVG(salary) as avg_salary
FROM employees
GROUP BY department_id
)
SELECT
d.department_name,
ds.emp_count,
ds.avg_salary
FROM department_stats ds
JOIN departments d ON ds.department_id = d.department_id
WHERE ds.emp_count > 5
ORDER BY ds.avg_salary DESC;
窗口函数
窗口函数可在结果集分区上计算,如排名、累计求和等。示例:
SELECT
employee_id,
name,
department,
salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as dept_rank,
salary - LAG(salary) OVER (PARTITION BY department ORDER BY salary) as salary_diff
FROM employees;
JSON 支持(MySQL 示例)
在 MySQL 中,可创建包含 JSON 列的表,并对 JSON 数据操作。
-- 创建包含 JSON 列的表
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
details JSON,
price DECIMAL(10,2)
);
-- 插入 JSON 数据
INSERT INTO products (name, details, price)
VALUES (
'Smartphone',
'{"brand": "Apple", "model": "iPhone 13", "specs": {"storage": "128GB", "color": "Midnight"}}',
799.00
);
-- 查询 JSON 数据
SELECT
name,
details->>"$.brand" as brand,
details->>"$.specs.storage" as storage
FROM products
WHERE details->>"$.brand" = 'Apple';
八、性能优化建议
• 索引优化:为 WHERE、JOIN、ORDER BY 子句中的列创建索引;避免过度索引;复合索引注意列顺序(选择性高的列在前)。
• 查询优化:用 EXPLAIN 分析执行计划;避免 SELECT *;用 LIMIT 限制结果集大小。
• 设计优化:规范化设计(必要时合理反规范化);选合适数据类型;大数据量表考虑分区表。
九、学习总结与反思
梳理 SQL 知识时,发现自身不足:窗口函数复杂场景应用不熟练、EXPLAIN 输出解读能力待提升、事务隔离级别理解不深、SQL 注入防护在框架中的最佳实践了解不全。后续计划:深入研究特定数据库高级特性;通过项目练习复杂查询优化;学习数据库设计模式与反模式;研究分布式数据库中 SQL 实现差异,持续提升 SQL 技能。
通过以上全面解析,涵盖 SQL 从基础语句到高级特性及优化,帮助读者系统掌握 SQL 知识,在实际应用中更高效地管理和操作数据库。