在学习 MySQL 的时候,最容易先接触到的一组概念,就是DDL、DML、DQL。
很多初学者第一次看到这几个缩写时,都会觉得它们长得很像,甚至会下意识把它们混在一起记。结果就是:明明会写CREATE,却说不清它为什么不属于“操作数据”;明明会写SELECT,却总和INSERT、UPDATE放在同一类里。
其实这三个分类并不难,只要抓住一个核心思路就够了:
- DDL:管“结构”
- DML:管“数据”
- DQL:管“查询”
也就是说,表怎么建、字段怎么改、索引怎么配,这是 DDL;表里的记录怎么新增、修改、删除,这是 DML;数据怎么筛选、排序、统计、分页查出来,这是 DQL。
说明一下:严格来说,MySQL 官方文档更多是按
CREATE / ALTER / DROP、INSERT / UPDATE / DELETE、SELECT这些具体语句讲解;DQL更多是教学场景中的常见叫法,用来单独表示“查询语句”。
一、先从整体上区分:它们到底各管什么
如果只用一句话来概括:
- DDL(Data Definition Language):数据定义语言,负责定义数据库对象
- DML(Data Manipulation Language):数据操作语言,负责操作表中的数据
- DQL(Data Query Language):数据查询语言,负责把需要的数据查出来
可以先看一个更直观的对照表:
| 分类 | 全称 | 主要作用 | 常见语句 |
|---|---|---|---|
| DDL | Data Definition Language | 定义和修改数据库结构 | CREATE、ALTER、DROP |
| DML | Data Manipulation Language | 新增、修改、删除表数据 | INSERT、UPDATE、DELETE |
| DQL | Data Query Language | 查询数据 | SELECT |
你也可以把数据库理解成一套“房子系统”:
- DDL像画房子的设计图,决定房子有几间房、门开在哪、结构怎么搭
- DML像安排谁住进去、谁搬走、谁换房间
- DQL像查住户信息,看看谁住哪间房、哪些房间有人、哪些人年龄大于 18
这样记,基本就不容易乱。
二、DDL:数据定义语言,重点在“结构”
DDL 的核心关键词就两个字:结构。
它不关心表里现在有几条记录,它更关心的是:这个表存不存在、有哪些字段、字段类型是什么、主键怎么设、默认值怎么写。
常见的 DDL 语句主要有:
CREATE:创建数据库、表、索引等对象ALTER:修改已有对象的结构DROP:删除数据库、表、索引等对象
1. 创建表:CREATE
CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,ageINT,create_timeDATETIMEDEFAULTCURRENT_TIMESTAMP);这条语句会创建一张student表。
从这条 SQL 里我们其实已经能看到 DDL 的典型特征了:它描述的是“这张表长什么样”。
比如:
id INT PRIMARY KEY AUTO_INCREMENT:表示主键字段,自增name VARCHAR(50) NOT NULL:表示姓名不能为空,最大长度 50create_time DATETIME DEFAULT CURRENT_TIMESTAMP:表示创建时间默认取当前时间
也就是说,DDL 负责的是“规则”和“框架”,而不是具体数据内容。
2. 修改表结构:ALTER
ALTERTABLEstudentADDCOLUMNphoneVARCHAR(20);这条 SQL 的作用是在student表中新增一个phone字段。
注意它修改的是表结构,而不是某一行记录的值,所以它属于 DDL。
除了新增字段,ALTER TABLE还经常用来做这些事:
ALTERTABLEstudentMODIFYCOLUMNnameVARCHAR(100);ALTERTABLEstudentDROPCOLUMNphone;ALTERTABLEstudentADDCOLUMNgenderCHAR(1);分别表示:
- 修改字段类型或长度
- 删除字段
- 新增字段
在实际开发里,ALTER TABLE用得非常多,因为需求变化后,表结构经常需要调整。
但也正因为如此,对线上大表做结构变更一定要谨慎,因为某些修改可能会带来锁表、耗时长、影响业务访问等问题。
3. 删除表:DROP
DROPTABLEIFEXISTSstudent;这条语句的意思是:如果student表存在,就直接删除。
删除之后,表结构没了,表里的数据也一起没了。
所以这里要特别区分两个概念:
DROP TABLE:删的是整张表,结构和数据一起删除DELETE FROM student:删的是表里的记录,表本身还在
这是很多初学者一开始最容易混淆的地方。
4. DDL 的几个典型特征
学习 DDL 时,可以顺手记住这几个特点:
- 它操作的是数据库对象本身,比如数据库、表、索引、字段
- 它更关注“定义”和“变更规则”
- 它的影响通常比较大,尤其是
DROP和大表ALTER - 一旦误操作,后果往往比普通数据修改更严重
所以写 DDL 时,一定要比写普通查询更谨慎一些。
三、DML:数据操作语言,重点在“记录”
如果说 DDL 是在搭房子,那么 DML 就是在处理房子里的人。
它不去管表结构长什么样,而是专门操作表中的一条条记录。
DML 常见语句有:
INSERT:新增数据UPDATE:修改数据DELETE:删除数据
1. 新增数据:INSERT
INSERTINTOstudent(name,age)VALUES('张三',18);这条语句就是往student表里插入一条记录。
表结构已经由 DDL 定义好了,现在 DML 要做的,就是往这个结构里填具体数据。
如果一次插入多条数据,也可以这样写:
INSERTINTOstudent(name,age)VALUES('李四',19),('王五',20),('赵六',18);这种写法在批量初始化测试数据时很常见,也比一条一条插入更方便。
2. 修改数据:UPDATE
UPDATEstudentSETage=19WHEREname='张三';这条 SQL 的意思是,把姓名为“张三”的学生年龄修改为 19。
这里的重点不是SET,而是WHERE。
因为如果你写成这样:
UPDATEstudentSETage=19;那就不是改某一个人的年龄了,而是会把整张表所有记录的age都改成 19。
所以很多人刚学 SQL 时,老师都会反复强调一句话:
UPDATE不写WHERE,后果可能很严重。
3. 删除数据:DELETE
DELETEFROMstudentWHEREid=1;这条语句表示删除id = 1的这条记录。
同样地,这里最重要的仍然是WHERE条件。
如果直接写:
DELETEFROMstudent;那么整张表的数据都会被删除,但表结构依然保留。
也就是说,这和DROP TABLE完全不是一回事。
4. DML 的几个典型特征
DML 的本质是:对已有数据做增删改。
它的关注点不在“表怎么设计”,而在“记录怎么变化”。
可以记住这几个判断标准:
- 只要是在操作表中已有或即将新增的记录,大概率就是 DML
INSERT是加数据UPDATE是改数据DELETE是删数据- 写
UPDATE、DELETE时,一定先确认WHERE条件是否正确
在真实开发中,DML 通常还会和事务一起出现,因为很多业务并不是只改一张表、只改一条数据,而是要保证一组操作要么都成功,要么都失败。
四、DQL:数据查询语言,重点在“把数据查出来”
前面的 DDL 和 DML,一个管结构,一个管数据变更。
而 DQL 则专门负责另一件事:查数据。
在 MySQL 里,DQL 最核心的语句就是:
SELECT
但SELECT真正强大的地方,不只是“查出来”,而是可以搭配很多子句一起完成筛选、排序、统计、分页等操作。
常见搭配有:
WHERE:条件过滤ORDER BY:排序GROUP BY:分组HAVING:分组后过滤LIMIT:限制条数或分页
1. 基础查询:SELECT
SELECTid,name,ageFROMstudent;这条语句会查询student表中的id、name、age三个字段。
如果你写成SELECT * FROM student;,表示查询所有字段。
不过在实际开发里,除非是临时调试,否则一般不建议长期依赖SELECT *,因为:
- 可读性一般
- 可能查出不需要的字段
- 表字段变多后,传输和解析成本也会增加
所以更推荐明确写出自己真正需要的列。
2. 条件查询:WHERE
SELECTid,name,ageFROMstudentWHEREage>=18;WHERE的作用就是先把符合条件的数据筛出来。
它可以理解为查询的第一道过滤网。
除了简单比较,还可以搭配更多条件:
SELECTid,name,ageFROMstudentWHEREage>=18ANDname!='张三';也可以使用LIKE、IN、BETWEEN等:
SELECT*FROMstudentWHEREnameLIKE'张%';SELECT*FROMstudentWHEREageIN(18,19,20);SELECT*FROMstudentWHEREageBETWEEN18AND20;所以学 DQL 时,WHERE往往是必须最先掌握的一部分。
3. 排序:ORDER BY
SELECTid,name,ageFROMstudentORDERBYageDESC;这条 SQL 表示按照年龄从大到小排序。
如果你写的是:
ORDERBYageASC那就是升序排列。
其中:
ASC:升序,默认可以省略DESC:降序
如果有多个排序条件,也可以这样写:
SELECTid,name,ageFROMstudentORDERBYageDESC,idASC;意思是先按年龄降序排;如果年龄相同,再按id升序排。
4. 分组统计:GROUP BY
SELECTage,COUNT(*)AScntFROMstudentGROUPBYage;这条语句的意思是:按年龄分组,并统计每个年龄有多少人。
这类写法在业务里非常常见,比如:
- 按部门统计人数
- 按订单状态统计数量
- 按日期统计访问量
- 按分类统计商品数
所以GROUP BY的本质不是“查明细”,而是“做汇总”。
5. 分组后过滤:HAVING
很多初学者会把WHERE和HAVING搞混。
它们最大的区别是:
WHERE:先筛选行,再分组HAVING:先分组,再筛选组
看个例子:
SELECTage,COUNT(*)AScntFROMstudentGROUPBYageHAVINGCOUNT(*)>=2;这条 SQL 的意思是:按年龄分组后,只保留人数大于等于 2 的年龄组。
如果你把这里的HAVING换成WHERE,语义就不对了,因为COUNT(*)是分组后的统计结果。
6. 分页或限制条数:LIMIT
SELECTid,name,ageFROMstudentLIMIT0,10;这条 SQL 表示从第 1 条开始,取 10 条数据。
它在分页查询里特别常见。
比如:
LIMIT 0, 10:第 1 页,每页 10 条LIMIT 10, 10:第 2 页,每页 10 条LIMIT 20, 10:第 3 页,每页 10 条
通常分页公式可以记成:
起始下标 = (页码 - 1) * 每页条数所以第 3 页每页 10 条,就是LIMIT 20, 10。
五、把三者串起来看:一套完整 SQL 流程其实很清楚
只看定义有时候不够直观,我们可以把 DDL、DML、DQL 放到一个完整流程里理解。
第一步:先建表,这是 DDL
CREATETABLEstudent(idINTPRIMARYKEYAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,ageINT,create_timeDATETIMEDEFAULTCURRENT_TIMESTAMP);这一步决定的是:我要用什么结构存学生信息。
也就是先把“容器”搭出来。
第二步:再插入数据,这是 DML
INSERTINTOstudent(name,age)VALUES('张三',18),('李四',19),('王五',18),('赵六',20);这一步是在往刚才建好的容器里放数据。
注意,这里已经不再改结构了,而是在往结构里填内容。
第三步:修改或删除某些数据,这还是 DML
UPDATEstudentSETage=21WHEREname='赵六';DELETEFROMstudentWHEREname='李四';这一步说明:数据不是一成不变的,后续可能还要继续维护。
所以 DML 是数据库日常使用中非常高频的一类操作。
第四步:把数据查出来分析,这是 DQL
SELECTid,name,ageFROMstudentWHEREage>=18ORDERBYageDESC;如果还想统计不同年龄的人数:
SELECTage,COUNT(*)AScntFROMstudentGROUPBYageORDERBYageASC;你会发现,完整流程其实就是:
- 先用 DDL 定规则
- 再用 DML 填数据、改数据
- 最后用 DQL 取数据、分析数据
这样一串起来,三个分类一下就顺了。
六、初学 MySQL 时最容易混淆的几个点
这一部分其实很重要,因为很多人不是不会写 SQL,而是容易在分类和语义上混。
1.DROP和DELETE不是一回事
很多人看到“删除”两个字,就下意识觉得是同一类。
但实际上:
DROP TABLE student:删除整张表,属于 DDLDELETE FROM student WHERE id = 1:删除表中的记录,属于 DML
一个删结构,一个删数据,影响完全不是一个级别。
2.ALTER修改的是表结构,不是数据
比如:
ALTERTABLEstudentADDCOLUMNphoneVARCHAR(20);这不是给某个学生设置手机号,而是给整张表增加一个“手机号字段”。
所以它属于 DDL,而不是 DML。
3.UPDATE、DELETE不加WHERE很危险
这个问题前面提过,但值得单独再强调一次。
因为真实开发里,最常见的误操作之一,就是条件没写对,或者干脆忘了写。
建议养成一个习惯:
- 先写
SELECT确认影响范围 - 再写
UPDATE或DELETE - 执行前再看一眼条件是否准确
这个习惯非常值。
4.WHERE和HAVING不要混用
简单记法就是:
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负责定义和修改数据库结构,比如
CREATE、ALTER、DROP - DML负责操作表中的数据,比如
INSERT、UPDATE、DELETE - DQL负责查询数据,核心语句就是
SELECT
如果你把它们放到真实使用流程里理解,会更容易记住:
- 先用DDL建表、定字段
- 再用DML插入、修改、删除记录
- 最后用DQL把数据查出来做展示或统计
学 SQL 的第一步,不一定是背很多语法,而是先把这三类语句各自“管什么”搞清楚。
一旦这条线理顺了,后面无论是写 CRUD,还是学多表查询、索引、事务,都会顺很多。