人人都会AI编程

2.4 基础 SQL 分类:DDL、DML、DQL、DCL、TCL

更新时间:2026-07-10

SQL(Structured Query Language)是操作关系型数据库的标准语言。在日常开发中,你写的每一条 SQL 语句,按其功能都可以归入五大类别:DDL、DML、DQL、DCL、TCL。掌握这五种分类,既能帮助你快速了解一条语句的影响范围,也能在与 DBA 或同事沟通时更准确地描述问题。

DDL(Data Definition Language,数据定义语言)

DDL 负责定义和管理数据库对象的结构,比如库、表、索引、视图等。它的核心特点是操作的是结构而非数据,而且多数 DDL 语句在执行时会隐式提交当前事务,无法回滚。

常用语句:

  • CREATE:创建数据库、表、索引、视图、存储过程等。
  • ALTER:修改表结构,如添加列、修改列类型、重命名表。
  • DROP:删除数据库、表、索引等对象,不可恢复,慎重执行
  • TRUNCATE:清空表的所有数据,但保留表结构。它比 DELETE 更快,因为它不逐行记录日志,且自增计数器会被重置。

示例:

-- 创建数据库
CREATE DATABASE shop CHARSET utf8mb4;

-- 创建表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- 修改表结构:添加字段
ALTER TABLE users ADD COLUMN email VARCHAR(100);

-- 清空表数据(DDL,不能回滚)
TRUNCATE TABLE users;

实用提醒TRUNCATE 在功能上归类为 DDL,因为它会隐式提交且无法回滚,这与 DML 中的 DELETE 有本质区别。在生产环境执行任何 DDL 之前,务必先在测试环境验证,尤其是 ALTER 大表时可能锁表或引发性能问题。

DML(Data Manipulation Language,数据操作语言)

DML 负责对表中的数据进行增删改操作,即对记录(行)的操作。这些语句通常可以在事务中执行,并且可以通过 ROLLBACK 撤销。

常用语句:

  • INSERT:向表中插入新记录。
  • UPDATE:修改已存在的记录。
  • DELETE:从表中删除记录。

示例:

-- 插入单条
INSERT INTO users (username, email) VALUES ('alice', 'alice@example.com');

-- 批量插入(性能更高)
INSERT INTO users (username, email) VALUES
    ('bob', 'bob@example.com'),
    ('charlie', 'charlie@example.com');

-- 更新数据(务必带上WHERE条件)
UPDATE users SET email = 'newalice@example.com' WHERE id = 1;

-- 删除数据(同样要精确限定条件)
DELETE FROM users WHERE id = 3;

实用提醒:执行 UPDATEDELETE 时,永远先写出 WHERE 条件,最好先在 SELECT 中验证条件命中的行,防止误操作清空全表。此外,DELETE 逐行删除且记录日志,大表清空应使用 TRUNCATE 或分批删除。

DQL(Data Query Language,数据查询语言)

DQL 的核心就一条:SELECT。它的功能是从表中检索数据,可以组合出非常复杂的查询逻辑。SELECT 不会修改数据,也不需要在事务中执行,但它会受事务隔离级别影响(读取到哪个版本的数据)。

一个完整的 SELECT 语句结构大致如下:

SELECT [DISTINCT] 列名或表达式
FROM 表名
[WHERE 条件]
[GROUP BY 列名]
[HAVING 分组过滤]
[ORDER BY 列名 ASC|DESC]
[LIMIT 偏移量, 行数];

示例:

-- 基础查询
SELECT id, username, email FROM users WHERE id > 10;

-- 聚合查询
SELECT status, COUNT(*) AS cnt FROM orders GROUP BY status;

-- 多表关联
SELECT u.username, o.total_amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.created_at >= '2024-01-01';

-- 分页查询
SELECT * FROM articles ORDER BY created_at DESC LIMIT 10, 10;

实用提醒SELECT * 在生产代码里应尽量避免,只取需要的列,既能减少传输量,又能更好地利用覆盖索引。复杂的 SELECT 要习惯用 EXPLAIN 查看执行计划,这是 SQL 优化的起点。

DCL(Data Control Language,数据控制语言)

DCL 用于控制数据库的访问权限和安全策略,通常由 DBA 或运维人员使用,开发者在排查权限问题时也会接触到。

常用语句:

  • GRANT:授予用户或角色某个权限。
  • REVOKE:回收已授予的权限。

示例:

-- 创建用户
CREATE USER 'app_user'@'%' IDENTIFIED BY 'secure_password';

-- 授予对 shop 库所有表的查询和插入权限
GRANT SELECT, INSERT ON shop.* TO 'app_user'@'%';

-- 回收插入权限
REVOKE INSERT ON shop.* FROM 'app_user'@'%';

-- 刷新权限(使更改立即生效)
FLUSH PRIVILEGES;

实用提醒:遵循最小权限原则,应用程序使用的数据库账号,只授予其业务必需的权限(通常 SELECT、INSERT、UPDATE、DELETE),不要给予 DROPALTER 等结构变更权限。权限控制是防范 SQL 注入和误操作的重要防线。

TCL(Transaction Control Language,事务控制语言)

TCL 用于管理事务,保证一组 DML 操作要么全部成功,要么全部失败。InnoDB 引擎支持事务,MyISAM 则不支持。

常用语句:

  • START TRANSACTIONBEGIN:开启一个事务。
  • COMMIT:提交事务,将更改永久生效。
  • ROLLBACK:回滚事务,撤销所有未提交的更改。
  • SAVEPOINT:在事务中设置保存点,可以部分回滚到该点。
  • ROLLBACK TO [SAVEPOINT]:回滚到指定保存点。

示例:

-- 典型事务用法
START TRANSACTION;
    INSERT INTO orders (...) VALUES (...);
    UPDATE inventory SET stock = stock - 1 WHERE product_id = 100 AND stock > 0;
    -- 若库存不足,则手动回滚
    IF (ROW_COUNT() = 0) THEN
        ROLLBACK;
    ELSE
        COMMIT;
    END IF;

-- 使用保存点
START TRANSACTION;
    INSERT INTO logs (msg) VALUES ('step1');
    SAVEPOINT sp1;
    INSERT INTO logs (msg) VALUES ('step2');
    ROLLBACK TO sp1;   -- 撤销 step2,保留 step1
COMMIT;

实用提醒:在应用程序中,务必在合理的作用域内开启事务,并且注意事务不要过长。长事务会持有锁和 Undo Log,影响并发性能和数据库空间。一旦捕获到业务异常或数据库错误,应立即回滚,避免连接处于不一致状态。许多框架(如 Spring)支持声明式事务,务必理解其传播行为和隔离级别设置。

小结

这五类 SQL 各司其职:DDL 管结构,DML 管数据,DQL 管查询,DCL 管权限,TCL 管事务。在日常开发中,你写的大部分语句属于 DML 和 DQL,而 DDL 往往在表结构变更或初始化时使用,DCL 更多在运维环节出现,TCL 则贯穿所有涉及数据一致性的业务代码。建立清晰的分类意识,能帮你写 SQL 时更有章法,排查问题时更快定位。