【MySQL | 第一篇】SQL语句怎么分?DDL、DML、DQL 一篇讲清楚

在学习 MySQL 的时候,最容易先接触到的一组概念,就是 DDL、DML、DQL

很多初学者第一次看到这几个缩写时,都会觉得它们长得很像,甚至会下意识把它们混在一起记。结果就是:明明会写 CREATE,却说不清它为什么不属于"操作数据";明明会写 SELECT,却总和 INSERTUPDATE 放在同一类里。

其实这三个分类并不难,只要抓住一个核心思路就够了:

  • DDL:管"结构"
  • DML:管"数据"
  • DQL:管"查询"

也就是说,表怎么建、字段怎么改、索引怎么配 ,这是 DDL;表里的记录怎么新增、修改、删除 ,这是 DML;数据怎么筛选、排序、统计、分页查出来,这是 DQL。

说明一下:严格来说,MySQL 官方文档更多是按 CREATE / ALTER / DROPINSERT / UPDATE / DELETESELECT 这些具体语句讲解;DQL 更多是教学场景中的常见叫法,用来单独表示"查询语句"。


一、先从整体上区分:它们到底各管什么

如果只用一句话来概括:

  • DDL(Data Definition Language):数据定义语言,负责定义数据库对象
  • DML(Data Manipulation Language):数据操作语言,负责操作表中的数据
  • DQL(Data Query Language):数据查询语言,负责把需要的数据查出来

可以先看一个更直观的对照表:

分类 全称 主要作用 常见语句
DDL Data Definition Language 定义和修改数据库结构 CREATEALTERDROP
DML Data Manipulation Language 新增、修改、删除表数据 INSERTUPDATEDELETE
DQL Data Query Language 查询数据 SELECT

你也可以把数据库理解成一套"房子系统":

  • DDL 像画房子的设计图,决定房子有几间房、门开在哪、结构怎么搭
  • DML 像安排谁住进去、谁搬走、谁换房间
  • DQL 像查住户信息,看看谁住哪间房、哪些房间有人、哪些人年龄大于 18

这样记,基本就不容易乱。


二、DDL:数据定义语言,重点在"结构"

DDL 的核心关键词就两个字:结构

它不关心表里现在有几条记录,它更关心的是:这个表存不存在、有哪些字段、字段类型是什么、主键怎么设、默认值怎么写。

常见的 DDL 语句主要有:

  • CREATE:创建数据库、表、索引等对象
  • ALTER:修改已有对象的结构
  • DROP:删除数据库、表、索引等对象

1. 创建表:CREATE

sql 复制代码
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

这条语句会创建一张 student 表。

从这条 SQL 里我们其实已经能看到 DDL 的典型特征了:它描述的是"这张表长什么样"。

比如:

  • id INT PRIMARY KEY AUTO_INCREMENT:表示主键字段,自增
  • name VARCHAR(50) NOT NULL:表示姓名不能为空,最大长度 50
  • create_time DATETIME DEFAULT CURRENT_TIMESTAMP:表示创建时间默认取当前时间

也就是说,DDL 负责的是"规则"和"框架",而不是具体数据内容。

2. 修改表结构:ALTER

sql 复制代码
ALTER TABLE student ADD COLUMN phone VARCHAR(20);

这条 SQL 的作用是在 student 表中新增一个 phone 字段。

注意它修改的是表结构,而不是某一行记录的值,所以它属于 DDL。

除了新增字段,ALTER TABLE 还经常用来做这些事:

sql 复制代码
ALTER TABLE student MODIFY COLUMN name VARCHAR(100);
ALTER TABLE student DROP COLUMN phone;
ALTER TABLE student ADD COLUMN gender CHAR(1);

分别表示:

  • 修改字段类型或长度
  • 删除字段
  • 新增字段

在实际开发里,ALTER TABLE 用得非常多,因为需求变化后,表结构经常需要调整。

但也正因为如此,对线上大表做结构变更一定要谨慎,因为某些修改可能会带来锁表、耗时长、影响业务访问等问题。

3. 删除表:DROP

sql 复制代码
DROP TABLE IF EXISTS student;

这条语句的意思是:如果 student 表存在,就直接删除。

删除之后,表结构没了,表里的数据也一起没了

所以这里要特别区分两个概念:

  • DROP TABLE:删的是整张表,结构和数据一起删除
  • DELETE FROM student:删的是表里的记录,表本身还在

这是很多初学者一开始最容易混淆的地方。

4. DDL 的几个典型特征

学习 DDL 时,可以顺手记住这几个特点:

  • 它操作的是数据库对象本身,比如数据库、表、索引、字段
  • 它更关注"定义"和"变更规则"
  • 它的影响通常比较大,尤其是 DROP 和大表 ALTER
  • 一旦误操作,后果往往比普通数据修改更严重

所以写 DDL 时,一定要比写普通查询更谨慎一些。


三、DML:数据操作语言,重点在"记录"

如果说 DDL 是在搭房子,那么 DML 就是在处理房子里的人。

它不去管表结构长什么样,而是专门操作表中的一条条记录。

DML 常见语句有:

  • INSERT:新增数据
  • UPDATE:修改数据
  • DELETE:删除数据

1. 新增数据:INSERT

sql 复制代码
INSERT INTO student (name, age) VALUES ('张三', 18);

这条语句就是往 student 表里插入一条记录。

表结构已经由 DDL 定义好了,现在 DML 要做的,就是往这个结构里填具体数据。

如果一次插入多条数据,也可以这样写:

sql 复制代码
INSERT INTO student (name, age) VALUES
('李四', 19),
('王五', 20),
('赵六', 18);

这种写法在批量初始化测试数据时很常见,也比一条一条插入更方便。

2. 修改数据:UPDATE

sql 复制代码
UPDATE student SET age = 19 WHERE name = '张三';

这条 SQL 的意思是,把姓名为"张三"的学生年龄修改为 19。

这里的重点不是 SET,而是 WHERE

因为如果你写成这样:

sql 复制代码
UPDATE student SET age = 19;

那就不是改某一个人的年龄了,而是会把整张表所有记录的 age 都改成 19。

所以很多人刚学 SQL 时,老师都会反复强调一句话:

UPDATE 不写 WHERE,后果可能很严重。

3. 删除数据:DELETE

sql 复制代码
DELETE FROM student WHERE id = 1;

这条语句表示删除 id = 1 的这条记录。

同样地,这里最重要的仍然是 WHERE 条件。

如果直接写:

sql 复制代码
DELETE FROM student;

那么整张表的数据都会被删除,但表结构依然保留。

也就是说,这和 DROP TABLE 完全不是一回事。

4. DML 的几个典型特征

DML 的本质是:对已有数据做增删改

它的关注点不在"表怎么设计",而在"记录怎么变化"。

可以记住这几个判断标准:

  • 只要是在操作表中已有或即将新增的记录,大概率就是 DML
  • INSERT 是加数据
  • UPDATE 是改数据
  • DELETE 是删数据
  • UPDATEDELETE 时,一定先确认 WHERE 条件是否正确

在真实开发中,DML 通常还会和事务一起出现,因为很多业务并不是只改一张表、只改一条数据,而是要保证一组操作要么都成功,要么都失败。


四、DQL:数据查询语言,重点在"把数据查出来"

前面的 DDL 和 DML,一个管结构,一个管数据变更。

而 DQL 则专门负责另一件事:查数据

在 MySQL 里,DQL 最核心的语句就是:

  • SELECT

SELECT 真正强大的地方,不只是"查出来",而是可以搭配很多子句一起完成筛选、排序、统计、分页等操作。

常见搭配有:

  • WHERE:条件过滤
  • ORDER BY:排序
  • GROUP BY:分组
  • HAVING:分组后过滤
  • LIMIT:限制条数或分页

1. 基础查询:SELECT

sql 复制代码
SELECT id, name, age FROM student;

这条语句会查询 student 表中的 idnameage 三个字段。

如果你写成 SELECT * FROM student;,表示查询所有字段。

不过在实际开发里,除非是临时调试,否则一般不建议长期依赖 SELECT *,因为:

  • 可读性一般
  • 可能查出不需要的字段
  • 表字段变多后,传输和解析成本也会增加

所以更推荐明确写出自己真正需要的列。

2. 条件查询:WHERE

sql 复制代码
SELECT id, name, age
FROM student
WHERE age >= 18;

WHERE 的作用就是先把符合条件的数据筛出来。

它可以理解为查询的第一道过滤网。

除了简单比较,还可以搭配更多条件:

sql 复制代码
SELECT id, name, age
FROM student
WHERE age >= 18 AND name != '张三';

也可以使用 LIKEINBETWEEN 等:

sql 复制代码
SELECT * FROM student WHERE name LIKE '张%';
SELECT * FROM student WHERE age IN (18, 19, 20);
SELECT * FROM student WHERE age BETWEEN 18 AND 20;

所以学 DQL 时,WHERE 往往是必须最先掌握的一部分。

3. 排序:ORDER BY

sql 复制代码
SELECT id, name, age
FROM student
ORDER BY age DESC;

这条 SQL 表示按照年龄从大到小排序。

如果你写的是:

sql 复制代码
ORDER BY age ASC

那就是升序排列。

其中:

  • ASC:升序,默认可以省略
  • DESC:降序

如果有多个排序条件,也可以这样写:

sql 复制代码
SELECT id, name, age
FROM student
ORDER BY age DESC, id ASC;

意思是先按年龄降序排;如果年龄相同,再按 id 升序排。

4. 分组统计:GROUP BY

sql 复制代码
SELECT age, COUNT(*) AS cnt
FROM student
GROUP BY age;

这条语句的意思是:按年龄分组,并统计每个年龄有多少人。

这类写法在业务里非常常见,比如:

  • 按部门统计人数
  • 按订单状态统计数量
  • 按日期统计访问量
  • 按分类统计商品数

所以 GROUP BY 的本质不是"查明细",而是"做汇总"。

5. 分组后过滤:HAVING

很多初学者会把 WHEREHAVING 搞混。

它们最大的区别是:

  • WHERE:先筛选行,再分组
  • HAVING:先分组,再筛选组

看个例子:

sql 复制代码
SELECT age, COUNT(*) AS cnt
FROM student
GROUP BY age
HAVING COUNT(*) >= 2;

这条 SQL 的意思是:按年龄分组后,只保留人数大于等于 2 的年龄组。

如果你把这里的 HAVING 换成 WHERE,语义就不对了,因为 COUNT(*) 是分组后的统计结果。

6. 分页或限制条数:LIMIT

sql 复制代码
SELECT id, name, age
FROM student
LIMIT 0, 10;

这条 SQL 表示从第 1 条开始,取 10 条数据。

它在分页查询里特别常见。

比如:

  • LIMIT 0, 10:第 1 页,每页 10 条
  • LIMIT 10, 10:第 2 页,每页 10 条
  • LIMIT 20, 10:第 3 页,每页 10 条

通常分页公式可以记成:

text 复制代码
起始下标 = (页码 - 1) * 每页条数

所以第 3 页每页 10 条,就是 LIMIT 20, 10


五、把三者串起来看:一套完整 SQL 流程其实很清楚

只看定义有时候不够直观,我们可以把 DDL、DML、DQL 放到一个完整流程里理解。

第一步:先建表,这是 DDL

sql 复制代码
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

这一步决定的是:我要用什么结构存学生信息。

也就是先把"容器"搭出来。

第二步:再插入数据,这是 DML

sql 复制代码
INSERT INTO student (name, age) VALUES
('张三', 18),
('李四', 19),
('王五', 18),
('赵六', 20);

这一步是在往刚才建好的容器里放数据。

注意,这里已经不再改结构了,而是在往结构里填内容。

第三步:修改或删除某些数据,这还是 DML

sql 复制代码
UPDATE student SET age = 21 WHERE name = '赵六';

DELETE FROM student WHERE name = '李四';

这一步说明:数据不是一成不变的,后续可能还要继续维护。

所以 DML 是数据库日常使用中非常高频的一类操作。

第四步:把数据查出来分析,这是 DQL

sql 复制代码
SELECT id, name, age
FROM student
WHERE age >= 18
ORDER BY age DESC;

如果还想统计不同年龄的人数:

sql 复制代码
SELECT age, COUNT(*) AS cnt
FROM student
GROUP BY age
ORDER BY age ASC;

你会发现,完整流程其实就是:

  1. 先用 DDL 定规则
  2. 再用 DML 填数据、改数据
  3. 最后用 DQL 取数据、分析数据

这样一串起来,三个分类一下就顺了。


六、初学 MySQL 时最容易混淆的几个点

这一部分其实很重要,因为很多人不是不会写 SQL,而是容易在分类和语义上混。

1. DROPDELETE 不是一回事

很多人看到"删除"两个字,就下意识觉得是同一类。

但实际上:

  • DROP TABLE student:删除整张表,属于 DDL
  • DELETE FROM student WHERE id = 1:删除表中的记录,属于 DML

一个删结构,一个删数据,影响完全不是一个级别。

2. ALTER 修改的是表结构,不是数据

比如:

sql 复制代码
ALTER TABLE student ADD COLUMN phone VARCHAR(20);

这不是给某个学生设置手机号,而是给整张表增加一个"手机号字段"。

所以它属于 DDL,而不是 DML。

3. UPDATEDELETE 不加 WHERE 很危险

这个问题前面提过,但值得单独再强调一次。

因为真实开发里,最常见的误操作之一,就是条件没写对,或者干脆忘了写。

建议养成一个习惯:

  • 先写 SELECT 确认影响范围
  • 再写 UPDATEDELETE
  • 执行前再看一眼条件是否准确

这个习惯非常值。

4. WHEREHAVING 不要混用

简单记法就是:

  • WHERE 是对"行"做过滤
  • HAVING 是对"分组结果"做过滤

只要你在条件里用到了 COUNT()SUM()AVG() 这类聚合函数,就要优先想想是不是应该写在 HAVING 里。

5. SELECT 不只是"查一下",它其实是最常用也最灵活的一类 SQL

很多人一开始觉得 DQL 最简单,因为就是 SELECT

但学到后面你会发现,真正最能拉开差距的,往往也是查询能力。

因为查询不仅仅是"看数据",它还涉及:

  • 多条件组合
  • 排序
  • 聚合统计
  • 分组过滤
  • 分页
  • 多表关联

所以 DQL 往往是 SQL 学习里最值得反复练的一部分。


七、DDL、DML、DQL 怎么记才不容易忘

如果你想快速记忆,可以直接记这三句话:

  • DDL 管结构
  • DML 管增删改
  • DQL 管查询

如果想记得更形象一点,可以继续用"房子"的比喻:

  • DDL:先设计房子,有几层、几个房间、门窗怎么开
  • DML:安排住户入住、搬走、换房间
  • DQL:查询谁住在哪、哪层住得最多、哪些房间是空的

再换成数据库本身的视角就是:

  • 表结构 = 房子框架
  • 表数据 = 住户信息
  • 查询结果 = 你查到的住户名单

八、总结

MySQL 里最常见的一组 SQL 分类,就是 DDL、DML、DQL

虽然这三个缩写看起来有点像,但它们的职责其实非常清楚:

  • DDL 负责定义和修改数据库结构,比如 CREATEALTERDROP
  • DML 负责操作表中的数据,比如 INSERTUPDATEDELETE
  • DQL 负责查询数据,核心语句就是 SELECT

如果你把它们放到真实使用流程里理解,会更容易记住:

  1. 先用 DDL 建表、定字段
  2. 再用 DML 插入、修改、删除记录
  3. 最后用 DQL 把数据查出来做展示或统计

学 SQL 的第一步,不一定是背很多语法,而是先把这三类语句各自"管什么"搞清楚。

一旦这条线理顺了,后面无论是写 CRUD,还是学多表查询、索引、事务,都会顺很多。

相关推荐
键盘上的猫头鹰1 小时前
【MySQL 教程(五)】SQL函数详解:字符、数字、日期、转换与通用函数
数据库·mysql·数据分析
Gauss松鼠会2 小时前
GaussDB(DWS)数据融合:Oracle增量数据迁移到DWS
java·数据库·算法·oracle·性能优化·gaussdb
风,停下2 小时前
SQLite表结构转换为MySql表(C#SqlSuga)
mysql·sqlite·c#
云和恩墨2 小时前
数据库一体机简史:德维特与微软的“复仇者联盟”
数据库·microsoft
ULIi096kr2 小时前
Redis 分布式锁进阶第七十四篇
数据库·redis·分布式
有梦想的小何2 小时前
库存快照报表升级实战:SQL 窗口函数 + 分区管理(MySQL 8.0)
数据库·sql·mysql
牙痛不能吃糖,哭2 小时前
DDL 数据库操作和表操作语句
数据库
承渊政道2 小时前
【MySQL数据库学习】(MySQL库的操作和表的操作)
数据库·学习·mysql·ubuntu·bash·数据库架构·数据库系统
No8g攻城狮2 小时前
【人大金仓】人大金仓数据库V9数据库兼容模式为oracle如何更改为pg的解决方案
数据库·安全·oracle·国产信创