MySQL 基础:DDL、DML、DQL、DCL 四大类 SQL 语句全解析

摘要:本文先介绍数据库SQL核心概念 ,接着阐述SQL 通用语法DDL、DML、DQL、DCL 四大分类,随后详细讲解各类语句操作,包括DDL 的数据库与表操作及数据类型,DML的数据增删改,DQL的查询语法与功能,DCL的用户管理和权限控制,助力掌握 MySQL 基础操作。

思维导图

1. MySQL 概述

1.1 数据库相关概念

本部分将讲解三个核心概念:数据库、数据库管理系统、SQL。

名称 全称 简称
数据库 存储数据的仓库,数据是有组织的进行存储 DataBase
数据库管理系统 操纵和管理数据库的大型软件 DataBase Management System
SQL 操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准 Structured Query Language

2. SQL语句

全称 Structured Query Language(结构化查询语言),是操作关系型数据库的编程语言,定义了一套操作关系型数据库的统一标准。无论使用 Oracle、SQL Server 还是 MySQL 等关系型数据库,均可以通过 SQL 语言进行统一操作,因此掌握 SQL 可灵活适配不同关系型数据库场景。

2.1 SQL 通用语法

在学习具体 SQL 语句前,需先了解 SQL 语言的通用规则

  1. SQL 语句可单行或多行书写,必须以分号结尾

  2. 可使用空格 / 缩进来增强语句可读性(不影响执行结果);

  3. MySQL 中的 SQL 语句不区分大小写,建议关键字使用大写,提高辨识度;

2.2 SQL 分类

根据功能,SQL 语句主要分为四类:DDL、DML、DQL、DCL,具体说明如下:

分类 说明
DDL 用于定义数据库对象(数据库、表、字段),如创建 / 删除数据库、创建 / 修改表结构等
DML 用于对数据库表中的数据进行增、删、改操作
DQL 用于查询数据库表中的记录,是业务中使用频次最高的 SQL 类型
DCL 用于管理数据库用户、控制数据库访问权限,如创建用户、授予 / 撤销权限等

2.3 DDL(数据定义语言)

DDL 主要用于操作数据库、表、字段等 "结构级" 对象,核心是 "定义结构",不涉及具体数据。

2.3.1 数据库操作
1. 查询所有数据库
sql 复制代码
show databases;

执行结果会显示当前 MySQL 服务器中所有已创建的数据库,例如系统默认数据库 information_schemamysqlsys 等。


2. 查询当前数据库
sql 复制代码
select database();

用于确认当前所处的数据库上下文(若未切换数据库,返回 NULL)。


3. 创建数据库
sql 复制代码
create database [ if not exists ] 数据库名 [ default charset 字符集 ] [ collate 排序规则 ];
  • if not exists:可选参数,避免重复创建同名数据库导致报错(若数据库已存在则不执行);

  • default charset:可选参数,指定数据库默认字符集;

  • collate:可选参数,指定字符排序规则(通常默认跟随字符集,无需手动设置)。


4. 删除数据库
sql 复制代码
drop database [ if exists ] 数据库名;
  • if exists:可选参数,避免删除不存在的数据库导致报错(若数据库不存在则不执行操作)。

5. 切换数据库
sql 复制代码
use 数据库名;

操作某数据库下的表前,必须先通过 use 切换到该数据库上下文。

2.3.2 表操作
2.3.2.1 表操作 - 查询与创建
1. 查询当前数据库所有表
sql 复制代码
show tables;

需先通过 use 切换到目标数据库,否则无法查询表。


2. 查看指定表结构
sql 复制代码
desc 表名;

返回表的字段名、数据类型、是否允许为 NULL、主键 / 外键、默认值等结构信息。


3. 查询指定表的建表语句
sql 复制代码
show create table 表名;

返回创建该表的完整 SQL 语句,包含默认存储引擎(如 InnoDB)、字符集等隐式配置。


4. 创建表结构
sql 复制代码
CREATE TABLE 表名(
​
  字段1 字段1类型 [ COMMENT 字段1注释 ],
​
  字段2 字段2类型 [ COMMENT 字段2注释 ],
​
  ...
​
  字段n 字段n类型 [ COMMENT 字段n注释 ]
​
) [ COMMENT 表注释 ];
  • 字段定义格式:字段名 类型 [约束] [注释]

  • 最后一个字段后不能加逗号,否则会语法报错;

  • COMMENT:可选参数,用于添加字段 / 表的说明,提高可读性。

2.3.2.2 表操作 - 数据类型

MySQL 中的数据类型主要分为三类:数值类型字符串类型日期时间类型 ,需根据业务场景选择合适的类型(如年龄用 TINYINT,手机号用 CHAR(11))。

1. 数值类型

适用于存储整数、小数等数值数据,核心是 "节省存储空间" 和 "保证精度"。

类型 大小 有符号(SIGNED)范围 无符号(UNSIGNED)范围 描述
TINYINT 1byte (-128, 127) (0, 255) 小整数值(如年龄、状态码)
SMALLINT 2bytes (-32768, 32767) (0, 65535) 中整数值(如数量较少的 ID)
MEDIUMINT 3bytes (-8388608, 8388607) (0, 16777215) 大整数值
INT/INTEGER 4bytes (-2147483648, 2147483647) (0, 4294967295) 常用大整数值(如用户 ID、订单 ID)
BIGINT 8bytes (-2^63, 2^63-1) (0, 2^64-1) 极大整数值(如海量数据的 ID)
FLOAT 4bytes (-3.4E+38, 3.4E+38) 0 和 (1.2E-38, 3.4E+38) 单精度浮点数(精度较低,不适合金额)
DOUBLE 8bytes (-1.8E+308, 1.8E+308) 0 和 (2.2E-308, 1.8E+308) 双精度浮点数(精度较高,仍不适合金额)
DECIMAL 可变 依赖 M(精度)和 D(标度) 依赖 M(精度)和 D(标度) 定点小数(精确存储,适合金额、分数等)

使用建议

  • 年龄:TINYINT UNSIGNED(无负数,范围 0-255 足够);

  • 分数(如满分 100,1 位小数):DOUBLE(4,1)(总长度 4,小数位 1,范围 0.0-100.0);

  • 金额(如保留 2 位小数):DECIMAL(10,2)(避免浮点数精度丢失)。

2. 字符串类型

适用于存储文本、符号等字符数据,核心是 "区分定长与变长"。

类型 大小 描述
CHAR 0-255 bytes 定长字符串(指定长度后,无论实际值多长,均占用固定字节)
VARCHAR 0-65535 bytes 变长字符串(仅占用实际值长度 + 1-2 字节的长度标识,节省空间)
TINYTEXT 0-255 bytes 短文本(适合存储少量文字,如备注)
TEXT 0-65535 bytes 长文本(适合存储文章、评论等)
MEDIUMTEXT 0-16777215 bytes 中等长度文本
LONGTEXT 0-4294967295 bytes 极大文本(适合存储超大文本,如日志)
TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB 同对应 TEXT 类型 二进制数据(如图片、文件,不推荐直接存储,建议存文件路径)

CHAR 与 VARCHAR 区别

  • CHAR(10):存储 "abc" 时,仍占用 10 字节(空格填充),性能高;

  • VARCHAR(10):存储 "abc" 时,仅占用 3 + 1 = 4 字节(1 字节标识长度),节省空间。

使用建议

  • 用户名(长度不定,最长 50):VARCHAR(50)

  • 性别(固定值 "男 / 女"):CHAR(1)

  • 手机号(固定 11 位):CHAR(11)

3. 日期时间类型

适用于存储日期、时间或混合时间数据,核心是 "匹配业务场景精度"。

类型 大小 范围 格式 描述
DATE 3bytes 1000-01-01 至 9999-12-31 YYYY-MM-DD 仅日期(如生日)
TIME 3bytes -838:59:59 至 838:59:59 HH:MM:SS 仅时间(如打卡时间)
YEAR 1byte 1901 至 2155 YYYY 仅年份(如毕业年份)
DATETIME 8bytes 1000-01-01 00:00:00 至 9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 日期 + 时间(如订单创建时间,不依赖时区)
TIMESTAMP 4bytes 1970-01-01 00:00:01 至 2038-01-19 03:14:07 YYYY-MM-DD HH:MM:SS 日期 + 时间(依赖时区,自动更新,适合记录 "最后修改时间")

使用建议

  • 生日:DATE

  • 订单创建时间:DATETIME

  • 数据最后修改时间:TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(自动更新)。

2.3.2.3 表操作 - 修改(修改表结构)
1. 添加字段
sql 复制代码
ALTER TABLE 表名 ADD 字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];

2. 修改数据类型
sql 复制代码
ALTER TABLE 表名 MODIFY 字段名 新数据类型 (长度);

3. 修改字段名和数据类型
sql 复制代码
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型 (长度) [ COMMENT 注释 ] [ 约束 ];

可同时修改字段名和类型,需注意新旧字段名的顺序。


4. 删除字段
sql 复制代码
ALTER TABLE 表名 DROP 字段名;

5. 修改表名
sql 复制代码
ALTER TABLE 表名 RENAME TO 新表名;
2.3.2.4 表操作 - 删除
1. 删除表
sql 复制代码
DROP TABLE [ IF EXISTS ] 表名;

if exists:避免删除不存在的表导致报错。

2. 删除表并重新创建(清空数据 + 保留结构)
sql 复制代码
TRUNCATE TABLE 表名;
  • 效果:删除表中所有数据,但保留表结构(相当于 "清空表");

  • 注意:数据无法恢复,且自增字段会重置为初始值(如 1)。

2.5 DML(数据操作语言)

DML 用于对表中的数据进行 "增、删、改" 操作,核心是 "操作数据",不改变表结构。

2.5.1 添加数据(INSERT)
1. 给指定字段添加数据
sql 复制代码
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
  • 字段名与值必须一一对应(顺序、数量、类型需匹配);

  • 字符串和日期类型的值必须用单引号包裹;

  • 字段值需符合表结构约束。

2. 给全部字段添加数据(省略字段名)
sql 复制代码
INSERT INTO 表名 VALUES (值1, 值2, ...);
  • 需按表中字段的默认顺序传入所有字段的值,不推荐(表结构变更后易报错)。
3. 批量添加数据
sql 复制代码
-- 方式1:指定字段批量插入
​
INSERT INTO 表名 (字段名1, 字段名2, ...)
​
VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
​
-- 方式2:全部字段批量插入
​
INSERT INTO 表名
​
VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
注意事项
  1. 字段顺序与值顺序必须一致;

  2. 字符串、日期类型必须用单引号包裹;

  3. 插入的值需符合字段约束(如长度、范围、非空等),否则报错。

2.5.2 修改数据(UPDATE)
sql 复制代码
UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ... [ WHERE 条件 ];

WHERE:可选参数,用于指定修改的范围(若省 WHERE,则修改表中所有数据,谨慎)。

注意事项
  1. WHERE 条件会修改全表数据,生产环境中需严格校验条件;

  2. 可同时修改多个字段,用逗号分隔字段赋值表达式。

2.5.3 删除数据(DELETE)
sql 复制代码
DELETE FROM 表名 [ WHERE 条件 ];
  • WHERE:可选参数,指定删除的范围(若省略 WHERE,则删除表中所有数据,需谨慎!)。
注意事项
  1. WHERE 条件会删除全表数据,且数据无法通过 ROLLBACK 恢复(除非开启事务);

  2. DELETE 只能删除行数据,不能删除单个字段的值(需用 UPDATE 将字段设为 NULL);

  3. DataGrip 等工具会对删除全表操作进行二次确认,避免误操作。

2.6 DQL(数据查询语言)

DQL 用于查询表中的记录,是业务中最常用的 SQL 类型,支持条件筛选、排序、分组、分页等复杂操作。

2.6.1 数据准备

先创建 emp 员工表并插入测试数据,后续案例基于该表展开。

2.6.2 DQL 基本语法

完整 DQL 语法结构(按编写顺序):

sql 复制代码
SELECT
​
字段列表  -- 要查询的字段(如 name, age 或 * 表示所有字段)
​
FROM
​
表名列表  -- 要查询的表(单表查询仅需写表名)
​
WHERE
​
条件列表  -- 行级筛选条件(如 age > 20)
​
GROUP BY
​
分组字段列表  -- 按指定字段分组(如按 gender 分组)
​
HAVING
​
分组后条件列表  -- 分组后的筛选条件(如 count(*) > 5)
​
ORDER BY
​
排序字段列表  -- 按指定字段排序(如 age ASC 升序)
​
LIMIT
​
分页参数  -- 分页查询(如 LIMIT 0, 10 表示第 1 页,10 条/页)

执行顺序(与编写顺序不同,需重点理解):

FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT

2.6.3 基础查询(无筛选条件)
1. 查询多个指定字段
sql 复制代码
SELECT 字段1, 字段2, ... FROM 表名;

2. 查询所有字段(不推荐)
sql 复制代码
SELECT * FROM 表名;

缺点:不直观、影响效率(若表字段多,会冗余返回不必要的字段),生产环境建议明确指定字段。


3. 字段设置别名
sql 复制代码
-- 方式1:使用 AS(推荐,可读性高)
​
SELECT 字段1 AS 别名1, 字段2 AS 别名2 FROM 表名;
​
-- 方式2:省略 AS(简洁)
​
SELECT 字段1 别名1, 字段2 别名2 FROM 表名;

别名含空格或特殊字符时,需用单引号包裹。


4. 去除重复记录
sql 复制代码
SELECT DISTINCT 字段列表 FROM 表名;

仅当所有指定字段的值完全相同时,才会被视为重复记录并去重。

2.6.4 条件查询(WHERE)

通过 WHERE 子句筛选符合条件的行数据,支持比较运算符和逻辑运算符。

1. 常用比较运算符
比较运算符 功能
> 大于
>= 大于等于
< 小于
<= 小于等于
= 等于
<>!= 不等于
BETWEEN ... AND ... 在指定范围(含边界)
IN(...) 在指定集合中
LIKE 占位符 模糊匹配
IS NULL 为空
IS NOT NULL 不为空
  • 模糊匹配占位符:
sql 复制代码
   `_`:匹配单个任意字符;
​
   `%`:匹配 0 个或多个任意字符。
2. 常用逻辑运算符
逻辑运算符 功能
AND&& 并且(多个条件同时成立)
OR 或 ` `
NOT! 非(否定条件)
2.6.5 聚合函数

聚合函数用于对一列数据进行 "纵向计算"(将列数据视为一个整体),返回单个结果值。

1. 常用聚合函数
函数 功能
count(字段) 统计非 NULL 值的记录数
max(字段) 求该列的最大值
min(字段) 求该列的最小值
avg(字段) 求该列的平均值
sum(字段) 求该列的总和

注意:NULL 值不参与任何聚合函数计算。

2. 语法
sql 复制代码
SELECT 聚合函数(字段列表) FROM 表名 \[ WHERE 条件 ];
2.6.6 分组查询(GROUP BY)

通过 GROUP BY 按指定字段分组,将相同值的行归为一组,然后对每组进行聚合计算(如统计每组人数、平均年龄)。

1. 语法
sql 复制代码
SELECT 分组字段, 聚合函数(字段) FROM 表名 \[ WHERE 条件 ] GROUP BY 分组字段 \[ HAVING 分组后条件 ];
  • WHERE:分组的筛选条件(筛选行数据,不满足条件的行不参与分组);

  • HAVING:分组的筛选条件(筛选分组结果,不满足条件的分组不显示)。

2. WHERE 与 HAVING 的区别
对比维度 WHERE HAVING
执行时机 分组前 分组后
作用对象 行数据 分组结果
支持的条件 不能使用聚合函数 可以使用聚合函数
3. 注意事项
  1. 分组后查询的字段只能是 "分组字段" 或 "聚合函数",查询其他字段无意义(结果不可控);

  2. 多字段分组时,按字段顺序依次分组(先按第一个字段分组,同组内再按第二个字段分组)。

2.6.7 排序查询(ORDER BY)

通过 ORDER BY 按指定字段对查询结果排序,支持升序和降序。

1. 语法
sql 复制代码
SELECT 字段列表 FROM 表名 [ WHERE 条件 ] [ GROUP BY 分组字段 ] [ HAVING 分组后条件 ] ORDER BY 字段1 排序方式1, 字段2 排序方式2 ...;
  • 排序方式:
sql 复制代码
   `ASC`:升序(默认,可省略);
​
   `DESC`:降序;

多字段排序:先按字段 1 排序,字段 1 值相同的行再按字段 2 排序。

2.6.8 分页查询(LIMIT)

通过 LIMIT 实现分页查询(避免一次性返回大量数据,优化性能),仅 MySQL 支持(其他数据库如 Oracle 用 ROWNUM)。

1. 语法
sql 复制代码
SELECT 字段列表 FROM 表名 [ 其他子句 ] LIMIT 起始索引, 查询记录数;
  • 起始索引:从 0 开始(表示第 1 条数据的索引为 0);

  • 计算公式:起始索引 = (页码 - 1) * 每页记录数

  • 若查询第 1 页数据,起始索引可省略。

2.6.9 DQL 执行顺序验证

通过别名测试可确认 DQL 执行顺序:

FROMWHEREGROUP BYHAVINGSELECTORDER BYLIMIT

2.7 DCL(数据控制语言)

DCL 用于管理数据库用户和控制访问权限,主要由 DBA(数据库管理员)操作,开发人员使用较少。

2.7.1 管理用户
1. 查询用户

MySQL 中所有用户信息存储在系统数据库 mysqluser 表中:

sql 复制代码
select * from mysql.user;
  • 核心字段:
sql 复制代码
   `Host`:用户可访问的主机(`localhost` 表示仅本地访问,`%` 表示任意主机访问);
​
   `User`:用户名;
​
   `authentication_string`:用户密码(加密存储)。
  • 注意:Host + User 唯一标识一个用户(同一用户名,不同主机视为不同用户)。

2. 创建用户
sql 复制代码
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
  • 主机名:
sql 复制代码
  `localhost`:仅允许本地(当前服务器)访问;
​
  `%`:允许任意主机访问(远程访问需开放 MySQL 端口 3306);

密码:长度至少 4 位(MySQL 8.0+ 默认密码策略较严格,需包含字母、数字、符号)。


3. 修改用户密码
sql 复制代码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql\_native\_password BY '新密码';

mysql_native_password:指定密码加密方式(兼容旧版本客户端,MySQL 8.0+ 推荐)。


4. 删除用户
sql 复制代码
DROP USER '用户名'@'主机名';
注意事项
  1. 必须指定 主机名(即使是 %),否则无法准确匹配用户;

  2. 开发环境中避免创建 % 主机的用户(安全风险),建议仅允许指定 IP 访问。

2.7.2 权限控制

MySQL 定义了多种权限,常用权限如下:

权限 说明
ALLALL PRIVILEGES 所有权限
SELECT 查询数据权限(仅 DQL)
INSERT 插入数据权限(仅 DML)
UPDATE 修改数据权限(仅 DML)
DELETE 删除数据权限(仅 DML)
ALTER 修改表结构权限(仅 DDL)
DROP 删除数据库 / 表 / 视图权限(仅 DDL)
CREATE 创建数据库 / 表权限(仅 DDL)
1. 查询用户权限
sql 复制代码
SHOW GRANTS FOR '用户名'@'主机名';

2. 授予权限
sql 复制代码
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
  • 权限列表:多个权限用逗号分隔(如 SELECT, INSERT),ALL 表示所有权限;

  • 数据库名。表名:

sql 复制代码
  `*.*`:所有数据库的所有表(全局权限);
​
  `itcast.*`:`itcast` 数据库的所有表;
​
  `itcast.emp`:`itcast` 数据库的 `emp` 表。

3. 撤销权限
sql 复制代码
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
注意事项
  1. 授予 / 撤销权限后,无需重启 MySQL,权限立即生效;

  2. 开发环境中遵循 "最小权限原则"(如仅给查询需求的用户授予 SELECT 权限),避免权限过大导致安全风险。