3、SQL语言概述:SQL标准、DDL、DML、DCL、TCL分类及各自作用
SQL(Structured Query Language,结构化查询语言)是关系型数据库系统的通用语言,也是数据库系统工程师日常工作中使用频率最高的技能。无论是数据查询、表结构维护、用户权限管理,还是事务控制,都离不开SQL。本章将系统梳理SQL标准的演进历程,并深入剖析SQL语言的五大功能分类——DDL、DML、DCL、TCL以及DQL(查询语言),帮助学习者建立完整的SQL知识框架,为后续的数据库设计、性能调优和运维管理打下坚实基础。
3.1 SQL标准演进与语言定位
SQL最早由IBM在20世纪70年代开发,最初称为SEQUEL(Structured English Query Language)。1986年,美国国家标准协会(ANSI)发布了第一个SQL标准,随后国际标准化组织(ISO)也采纳该标准。经过近四十年的发展,SQL标准不断吸收新的数据库技术成果,从简单的表操作扩展到对象关系特性、XML处理、窗口函数、JSON支持等现代功能。
| 标准版本 | 发布时间 | 主要新增特性 | 工程意义 |
|---|---|---|---|
| SQL-86 | 1986年 | 基础DDL/DML语法 | 奠定关系数据库语言基础 |
| SQL-92 | 1992年 | 连接查询、集合操作、约束定义 | 成为主流数据库兼容基准 |
| SQL:1999 | 1999年 | 递归查询、触发器、对象类型 | 引入面向对象扩展 |
| SQL:2003 | 2003年 | XML函数、窗口函数、序列 | 增强分析能力 |
| SQL:2016 | 2016年 | JSON支持、行模式匹配 | 适配现代应用开发 |
| SQL:2023 | 2023年 | 增强JSON、属性图查询 | 面向多模型数据 |
LIMIT、Oracle的ROWNUM、SQL Server的TOP都用于限制返回行数,但语法各不相同。作为数据库工程师,既要掌握标准SQL,也要熟悉所管理数据库的方言特性。
3.2 DDL(数据定义语言)——构建数据库骨架
DDL(Data Definition Language)负责定义和管理数据库对象的生命周期,包括创建、修改和删除。这些操作通常会自动提交事务,无法回滚,因此执行时需要格外谨慎。
3.2.1 DDL核心操作与判断方法
- CREATE:创建数据库、表、索引、视图、存储过程等对象
- ALTER:修改已有对象的结构,如添加列、修改数据类型、增加约束
- DROP:删除对象及其数据,不可恢复
- TRUNCATE:清空表数据但保留表结构(部分数据库归类为DDL)
- RENAME:重命名对象
-- 创建用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 添加索引
CREATE INDEX idx_users_email ON users(email);
-- 修改表结构
ALTER TABLE users ADD COLUMN phone VARCHAR(20) AFTER email;
-- 删除表(危险操作)
DROP TABLE users;
DROP或TRUNCATE前,必须确认备份完整,并建议在维护窗口执行。对于大表的ALTER TABLE操作,MySQL 5.6+可使用ALGORITHM=INPLACE减少锁表时间。
3.2.2 DDL实战场景:表结构变更流程
某电商平台订单表需要新增“优惠券ID”字段,并建立索引以优化按优惠券查询的报表效率。操作流程如下:
- 评估影响:检查表大小(约500万行)、当前业务低峰期时段
- 备份策略:使用
mysqldump或Percona XtraBackup进行物理备份 - 执行变更:
ALTER TABLE orders ADD COLUMN coupon_id INT NULL, ADD INDEX idx_coupon (coupon_id); - 验证:检查表结构、索引是否生效,执行
EXPLAIN验证查询计划 - 监控:观察主从延迟、CPU/IO指标,确认无异常
3.3 DML(数据操作语言)——操纵数据内容
DML(Data Manipulation Language)用于对表中的数据进行增、删、改操作。与DDL不同,DML操作受事务控制,可以通过COMMIT提交或ROLLBACK回滚,这是保障数据一致性的关键机制。
3.3.1 DML核心语法与事务关联
| 操作 | 语法示例 | 事务特性 | 性能注意 |
|---|---|---|---|
| INSERT | INSERT INTO t (col1, col2) VALUES (v1, v2); |
可回滚 | 批量插入使用多VALUES或LOAD DATA |
| UPDATE | UPDATE t SET col1 = v1 WHERE id = 100; |
可回滚 | 必须带WHERE,否则全表更新 |
| DELETE | DELETE FROM t WHERE status = 'expired'; |
可回滚 | 大批量删除建议分批LIMIT |
UPDATE或DELETE前,建议先使用相同条件的SELECT COUNT(*)评估影响行数。对于关键业务表,可以先开启事务执行,确认影响范围后再COMMIT。
3.3.2 DML案例:订单状态批量更新
某物流系统需要将“已签收”超过30天的订单状态从delivered更新为completed。初始数据:订单表orders共1200万行,目标更新约35万行。
-- 开启事务
START TRANSACTION;
-- 分批更新,每批5000行
UPDATE orders
SET status = 'completed', updated_at = NOW()
WHERE status = 'delivered'
AND delivered_at < DATE_SUB(NOW(), INTERVAL 30 DAY)
LIMIT 5000;
-- 检查影响行数,确认无误后提交
COMMIT;
该方案通过LIMIT分批执行,避免一次性锁大量行导致主从延迟或锁等待。实际执行中循环调用该语句直至影响行数为0,整个过程约需执行70次,每次耗时约0.8秒,对业务影响极小。
3.4 DQL(数据查询语言)——数据价值的核心出口
DQL(Data Query Language)以SELECT为核心,是日常使用频率最高的SQL类型。虽然标准分类中常将SELECT归入DML,但在工程实践中通常单独划分,因为查询不修改数据且语法复杂度远高于其他DML操作。
3.4.1 SELECT执行逻辑与优化要点
- FROM:确定数据来源表,多表时确定连接顺序
- WHERE:行级过滤,尽早缩小数据范围
- GROUP BY:分组聚合
- HAVING:分组后过滤
- SELECT:投影所需列
- ORDER BY:排序
- LIMIT:限制返回行数
-- 查询每个分类下销量前3的商品
SELECT category_id, product_id, sales_volume
FROM (
SELECT category_id, product_id, sales_volume,
ROW_NUMBER() OVER (PARTITION BY category_id ORDER BY sales_volume DESC) AS rn
FROM product_sales
) t
WHERE rn <= 3;
SELECT *,只取所需列;WHERE条件中的函数会导致索引失效;多表连接时小表驱动大表;合理使用覆盖索引减少回表。
3.5 DCL(数据控制语言)——权限与安全防线
DCL(Data Control Language)管理数据库用户的访问权限,是数据库安全体系的核心。主要操作包括GRANT(授权)和REVOKE(回收权限)。
3.5.1 权限分类与授权策略
| 权限级别 | 示例 | 适用场景 |
|---|---|---|
| 全局权限 | GRANT ALL ON *.* TO 'admin'@'%' |
数据库管理员 |
| 数据库权限 | GRANT SELECT, INSERT ON mydb.* TO 'app'@'10.0.%' |
应用账号 |
| 表权限 | GRANT SELECT ON mydb.orders TO 'analyst'@'localhost' |
数据分析师 |
| 列权限 | GRANT SELECT (name, email) ON mydb.users TO 'support'@'%' |
客服脱敏访问 |
mysql.user表,清理长期不用的账号;使用REVOKE及时回收离职员工的权限;敏感操作(如DROP)不应授予应用账号。
3.6 TCL(事务控制语言)——数据一致性的守护者
TCL(Transaction Control Language)管理事务的提交、回滚和保存点,确保数据库操作的原子性和一致性。事务的ACID特性(原子性、一致性、隔离性、持久性)是关系数据库可靠性的基石。
3.6.1 TCL核心命令与使用场景
- COMMIT:提交当前事务,使更改永久生效
- ROLLBACK:回滚当前事务,撤销所有未提交的更改
- SAVEPOINT:在事务中设置保存点,可部分回滚
- SET TRANSACTION:设置事务隔离级别
-- 转账操作:A账户扣款,B账户入账
START TRANSACTION;
UPDATE accounts SET balance = balance - 1000 WHERE account_id = 'A';
-- 模拟异常:检查A账户余额是否足够
IF (SELECT balance FROM accounts WHERE account_id = 'A') < 0 THEN
ROLLBACK;
ELSE
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 'B';
COMMIT;
END IF;
3.6.2 事务隔离级别与并发控制
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 默认数据库 |
|---|---|---|---|---|
| READ UNCOMMITTED | 可能 | 可能 | 可能 | — |
| READ COMMITTED | 避免 | 可能 | 可能 | Oracle, SQL Server |
| REPEATABLE READ | 避免 | 避免 | 可能 | MySQL |
| SERIALIZABLE | 避免 | 避免 | 避免 | — |
SELECT ... FOR UPDATE显式加锁。
3.7 常见误区与总结复盘
在实际工作中,数据库工程师常犯以下错误,需要特别警惕:
- 误区一:混淆DDL与DML的事务特性。DDL隐式提交无法回滚,DML受事务控制可回滚。
- 误区二:在
WHERE条件中对索引列使用函数,导致索引失效。如WHERE DATE(created_at) = '2024-01-01'应改为WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02'。 - 误区三:忽视权限最小化原则,给应用账号授予
ALL PRIVILEGES,增加安全风险。 - 误区四:长事务未及时提交,导致锁持有时间过长,引发大量锁等待和主从延迟。
- 误区五:使用
DELETE删除全表数据,应使用TRUNCATE(不可回滚但更快)或分批删除。