mysql语句:DML、DDL、DQL、TCL、DCL

分类

类别核心功能典型命令事务支持操作对象
DDL定义或修改数据库结构CREATE、ALTER、DROP自动提交表、索引、视图
DML操作数据(增删改)INSERT、UPDATE、DELETE需显式提交表中的数据
DQL查询数据SELECT无影响数据查询结果
TCL控制事务边界COMMIT、ROLLBACK、SAVEPOINT事务相关事务状态
DCL管理访问权限GRANT、REVOKE自动提交用户/角色权限

注意

  • DDL 与事务的冲突:执行 DDL 语句(如 ALTER TABLE)会隐式提交当前未提交的事务。
  • DQL 的归属争议:严格来说 SELECT 属于 DQL,但有时也被归类到 DML。
  • TCL 的依赖条件:需使用支持事务的引擎(如 InnoDB),否则 ROLLBACK 无效。

数据定义语言(DDL)

DDL (Data Definition Language)是数据定义语言的缩写,简单来说,就是对数据库内部的对象进行创建、删除、修改的操作语言。

数据定义语言(Data Definition Language,DDL)是 SQL 语言集中负责数据结构定义与数据库对象定义的语言。

·DDL 的主要功能是定义数据库对象

典型命令:CREATE(创建表)、ALTER(修改表结构)、DROP(删除表)、TRUNCATE(清空表)、RENAME(重命名表)

数据操纵语言(DML)

DML 是数据库操作语言(Data Manipulation Language)的缩写,是指对数据库中表记录的操作,主要包括表记录的插入、更新、删除和查询,是开发人员日常使用最频繁的操作

数据操纵语言(Data Manipulation Language, DML)是用于数据库操作,对数据库其中的对象和数据运行访问工作的编程语句。

DML 的主要功能是 访问数据,因此其语法都是以读写数据库为主

DML 的核心指令是 INSERT、UPDATE、DELETE、SELECT这四个指令合称 CRUD(Create, Read, Update, Delete),即增删改查

典型命令:INSERT(插入数据)、UPDATE(更新数据)、DELETE(删除数据)

数据查询语言 (DQL)

DQL(Data Query Language):由于select不会对表进行破坏,所以有的地方也会把select单独区分开叫做数据库查询语言 DQL(Data Query Language)

特点:

  • 不修改数据,但可能消耗大量 I/O 资源(尤其未命中索引时)。
  • 支持复杂逻辑(如 JOIN、GROUP BY、子查询)。

典型命令:SELECT(查询数据)

事务控制语言(TCL)

事务控制语言 (Transaction Control Language, TCL) 用于管理数据库中的事务。

这些用于管理由 DML 语句所做的更改。它还允许将语句分组为逻辑事务

特点:

  • 确保数据的 ACID 特性(原子性、一致性、隔离性、持久性)。
  • InnoDB 引擎支持,MyISAM 引擎不支持。

典型命令:COMMIT(提交事务)、ROLLBACK(回滚事务)、SAVEPOINT(设置保存点)

数据控制语言(DCL)

数据控制语言 (Data Control Language, DCL) 是一种可对数据访问权进行控制的指令,它可以控制特定用户账户对数据表、查看表、预存程序、用户自定义函数等数据库对象的控制权。

典型命令:GRANT(授权)、REVOKE(撤销权限)

特点:

  • 控制用户或角色对库、表、字段的访问权限。
  • 权限信息存储在 mysql.user、mysql.db 等系统表中

DCL 以控制用户的访问权限为主,因此其指令作法并不复杂,可利用 DCL 控制的权限有:CONNECT、SELECT、INSERT、UPDATE、DELETE、EXECUTE、USAGE、REFERENCES。

根据不同的 DBMS 以及不同的安全性实体,其支持的权限控制也有所不同。

数据定义 DDL

数据库操作(DATABASE)

创建数据库

CREATE DATABASE test;

删除

DROP DATABASE test;

选择

USE test;

数据表操作(TABLE)

创建数据表

普通创建

CREATE TABLE user (
  id int(10) unsigned NOT NULL COMMENT 'Id',
  username varchar(64) NOT NULL DEFAULT 'default' COMMENT '用户名',
  password varchar(64) NOT NULL DEFAULT 'default' COMMENT '密码',
  email varchar(64) NOT NULL DEFAULT 'default' COMMENT '邮箱'
) COMMENT='用户表';

根据已有的表创建新表

CREATE TABLE vip_user AS
SELECT * FROM user;

删除数据表

DROP TABLE user;

修改数据表

列操作

添加列

ALTER TABLE user
ADD age int(3);

删除列

ALTER TABLE user
DROP COLUMN age;

修改列

ALTER TABLE `user`
MODIFY COLUMN age tinyint;
主键操作

添加主键

ALTER TABLE user
ADD PRIMARY KEY (id);

删除主键

ALTER TABLE user
DROP PRIMARY KEY;

增删改 DML

插入数据

INSERT INTO 语句用于向表中插入新记录。

插入完整的行

# 插入一行
INSERT INTO user
VALUES (10, 'root', 'root', 'xxxx@163.com');
# 插入多行
INSERT INTO user
VALUES (10, 'root', 'root', 'xxxx@163.com'), (12, 'user1', 'user1', 'xxxx@163.com'), (18, 'user2', 'user2', 'xxxx@163.com');

插入行的一部分

INSERT INTO user(username, password, email)
VALUES ('admin', 'admin', 'xxxx@163.com');

插入查询出来的数据

INSERT INTO user(username)
SELECT name
FROM account;

更新数据

UPDATE 语句用于更新表中的记录

UPDATE user
SET username='robot', password='robot'
WHERE username = 'root';

删除数据

DELETE 语句用于删除表中的记录。

TRUNCATE TABLE 可以清空表,也就是删除所有行

说明:TRUNCATE 语句不属于 DML 语法而是 DDL 语法

删除表中的指定数据

DELETE FROM user
WHERE username = 'robot';

清空表中的数据

TRUNCATE TABLE user;

数据查询 DQL

DQL(Data Query Language):由于select不会对表进行破坏,所以有的地方也会把select单独区分开叫做数据库查询语言 DQL(Data Query Language)

查询数据

基本查询命令select、limit

SELECT 语句用于从数据库中查询数据。

DISTINCT 用于返回唯一不同的值。它作用于所有列,也就是说所有列的值都相同才算相同

LIMIT 限制返回的行数。可以有两个参数,

  • 第一个参数为起始行,从 0 开始;
  • 第二个参数为返回的总行数。

ASC:升序(默认)

DESC:降序

查询单列
SELECT prod_name
FROM products;
查询多列
SELECT prod_id, prod_name, prod_price
FROM products;
查询所有列
SELECT *
FROM products;
查询不同的值
SELECT DISTINCT
vend_id FROM products;
限制查询结果
-- 返回前 5 行
SELECT * FROM mytable LIMIT 5;
SELECT * FROM mytable LIMIT 0, 5;
-- 返回第 3 ~ 5 行
SELECT * FROM mytable LIMIT 2, 3;

排序

order by 用于对结果集按照一个列或者多个列进行排序。

默认按照升序对记录进行排序,如果需要按照降序对记录进行排序,可以使用 desc 关键字。

order by 对多列排序的时候,先排序的列放前面,后排序的列放后面。并且,不同的列可以有不同的排序规则

SELECT * FROM products
ORDER BY prod_price DESC, prod_name ASC;

分组

group by

group by:group by 子句将记录分组到汇总行中

group by 为每个组返回一个记录

group by 通常还涉及聚合count,max,sum,avg 等。

group by 可以按一列或多列进行分组

group by 按分组字段进行排序后,order by 可以以汇总字段来进行排序。

分组
SELECT cust_name, COUNT(cust_address) AS addr_num
FROM Customers GROUP BY cust_name;
分组后排序
SELECT cust_name, COUNT(cust_address) AS addr_num
FROM Customers GROUP BY cust_name
ORDER BY cust_name DESC;

having

having 用于对汇总的 group by 结果进行过滤

having 一般都是和 group by 连用

where 和 having 可以在相同的查询中。

使用 WHERE 和 HAVING 过滤数据

SELECT cust_name, COUNT(*) AS NumberOfOrders
FROM Customers
WHERE cust_email IS NOT NULL
GROUP BY cust_name
HAVING COUNT(*) > 1;

having vs where

where:过滤过滤指定的行,后面不能加聚合函数(分组函数)。where 在group by 前

having:过滤分组,一般都是和 group by 连用,不能单独使用。having 在 group by 之后

子查询

基本概念

查询就是指将一个 select 查询(子查询)的结果作为另一个 SQL 语句(主查询)的数据来源或者判断条件

子查询是嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句中的完整 SELECT 语句

‌结构‌:

  • 外层查询称为主查询
  • 内层嵌套的查询称为子查询

用在 WHERE 子句和 FROM 子句后边:

  • 当用于 WHERE 子句时,根据不同的运算符,子查询可以返回单行单列、多行单列、单行多列数据。子查询就是要返回能够作为 WHERE 子句查询条件的值
  • 当用于 FROM 子句时,一般返回多行多列数据,相当于返回一张临时表,这样才符合 FROM 后面是表的规则。这种做法能够实现多表联合查询

执行顺序‌:通常先执行子查询,然后将结果传递给主查询使用

基本语法

WHERE 子句的子查询的基本语法如下:

  • 子查询需要放在括号( )内。
  • operator 表示用于 where 子句的运算符。
select column_name [, column_name ]
from   table1 [, table2 ]
where  column_name operator
    (select column_name [, column_name ]
    from table1 [, table2 ]
    [where])

FROM 子句的子查询的基本语法:用于 FROM 的子查询返回的结果相当于一张临时表,所以需要使用 AS 关键字为该临时表起一个名字。

select column_name [, column_name ]
from (select column_name [, column_name ]
      from table1 [, table2 ]
      [where]) as temp_table_name
where  condition

示例

示例如下:

  • 作为过滤条件
    SELECT * FROM products WHERE 
    	price > 
    		(SELECT AVG(price) FROM products);
    
    
  • FROM 子句中的子查询(派生表)
    SELECT * FROM 
    	(SELECT * FROM students WHERE score > 90) 
    	AS top_students;
    
    
  • SELECT 子句中的子查询‌
    SELECT 
    	name, 
    	(SELECT COUNT(*) FROM orders WHERE cust_id = c.id) AS order_count 
    FROM customers c;
    
    
  • ‌HAVING 子句中的子查询
    SELECT deptno, AVG(sal) FROM emp 
    GROUP BY deptno 
    HAVING AVG(sal) > (SELECT AVG(sal) FROM emp);
    
    

连接JOIN

基本概念

JOIN 子句用于将两个或者多个表联合起来进行查询

连接表的本质就是将不同表的记录合并起来,形成一张新表,这张新表只是临时的,它仅存在于本次查询期间

基本语法如下: table1.common_column1 = table2.common_column2 是连接条件,只有满足此条件的记录才会合并为一行

其他的也可以,例如 =、>、<、<>、<=、>=、!=、between、like 或者 not,但是最常见的是使用 =

select table1.column1, table2.column2...
from table1
join table2
on table1.common_column1 = table2.common_column2;

如果两张表的关联字段名相同,也可以使用 USING子句来代替 ON,举例如下

# join....on
select c.cust_name, o.order_num
from Customers c
inner join Orders o
on c.cust_id = o.cust_id
order by c.cust_name;

# 如果两张表的关联字段名相同,也可以使用USING子句:join....using()
select c.cust_name, o.order_num
from Customers c
inner join Orders o
using(cust_id)
order by c.cust_name;

连接中ON 和 WHERE 的区别联系

连接表时,SQL 会根据连接条件生成一张新的临时表。ON 就是连接条件,它决定临时表的生成

WHERE 是在临时表生成以后,再对临时表中的数据进行过滤,生成最终的结果集,这个时候已经没有 JOIN-ON 了。

SQL 先根据 ON 生成一张临时表,然后再根据 WHERE 对临时表进行筛选

内连接(交集)

查询的是相关的数据表之间有交集的那部分的数据

-- 内连接
/*
	显示内连接
		SELECT 列名 FROM 表名1 [INNER] JOIN 表名2 ON 关联条件;
*/
-- 查询用户信息和对应的订单信息
SELECT * FROM USER INNER JOIN orderlist ON orderlist.uid = user.id;

/*
	隐式内连接
	标准语法:
		SELECT 列名 FROM 表名1,表名2 WHERE 关联条件;
*/
-- 查询用户姓名,年龄。和订单编号
SELECT 
	u.name,
	u.age,
	o.number
FROM
	USER u,
	orderlist o
WHERE
	o.uid = u.id;

隐式内连接

“隐式内连接”,也就是没有 INNER JOIN 关键字,使用 WHERE 语句实现内连接的功能

# 隐式内连接
select c.cust_name, o.order_num
from Customers c, Orders o
where c.cust_id = o.cust_id
order by c.cust_name;
显式内连接
# 显式内连接
select c.cust_name, o.order_num
from Customers c inner join Orders o
using(cust_id)
order by c.cust_name;

外连接

左外连接

左外连接:查询左表所有数据,并将两表有交集的数据,补充到查询的所有左表的数据中

可以理解为左表要补充 数据

右外连接:查询右表所有数据,并将两表有交集的数据,补充到查询的所有左表的数据中

可以理解为右表要补充 数据

左右表判断:table_a 插入 table_b,

  • 左连接:LEFT JOIN 左侧的表是主表(左表保留全量数据)
    右连接:RIGHT JOIN 右侧的表是主表(右表保留全量数据)
-- 左表:table_a | 右表:table_b
SELECT * 
FROM table_a 
LEFT JOIN table_b ON ... ;

-- 左表:table_b | 右表:table_a
SELECT * 
FROM table_b 
RIGHT JOIN table_a ON ... ;

全外连接(并集)

同时保留两个表中所有的记录,即使其中一方没有匹配项。
对等性:FULL OUTER JOIN 包含了 LEFT JOIN 和 RIGHT JOIN 的结果。

未匹配的记录填充 NULL:如果某条记录在一张表中没有匹配项,则其对应的字段以 NULL 表示。

在这里插入图片描述

SELECT column_name(s)
FROM table1
FULL OUTER JOIN table2
ON table1.column_name=table2.column_name;

对比

连接类型保留数据范围典型用途
INNER JOIN仅匹配成功的记录精确关联查询
LEFT JOIN左表全量 + 右表匹配项主表数据完整性保障
RIGHT JOIN右表全量 + 左表匹配项较少使用

组合UNION

基本概念

UNION 用于将多个 SELECT 语句的结果集合并为单个结果集,自动去重重复行

UNION 运算符将两个或更多查询的结果组合起来,并生成一个结果集,其中包含来自 UNION 中参与查询的提取行。

UNION 基本规则:

  • 所有查询的列数和列顺序必须相同
  • 每个查询中涉及表的列的数据类型必须相同或兼容
  • 通常返回的列名取自第一个查询

默认地,UNION 操作符选取不同的值如果允许重复的值,请使用 UNION ALL

SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

注意:

  • 列数与数据类型必须兼容:
    • 所有 SELECT 的列数必须相同。
    • 对应列的数据类型需兼容(如 VARCHAR 与 TEXT 兼容,INT 与 DECIMAL 需隐式转换)。
  • 列名与别名:最终结果集的列名以 第一个 SELECT 的列名或别名 为准。如下示例

    UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名

    SELECT id AS user_id, name FROM employees
    UNION
    SELECT contractor_id, contractor_name FROM contractors;
    -- 结果列名显示为 user_id、name
    
    
  • 去重与保留重复:
    • UNION:自动去重(性能较低)。
    • UNION ALL:保留所有行(高效,优先使用)

使用示例

合并两个部门的员工名单:

-- 查询正式员工和外包员工的姓名、部门
SELECT name, department FROM employees  -- 表1
UNION
SELECT name, department FROM contractors; -- 表2

统计所有用户的登录总次数:

SELECT 'Web' AS source, COUNT(*) AS total_logins FROM web_logins
UNION
SELECT 'App', COUNT(*) FROM app_logins;

JOIN vs UNION

JOIN 中连接表的列可能不同,但在 UNION 中,所有查询的列数和列顺序必须相同

UNION 将查询之后的行放在一起(垂直放置),但 JOIN 将查询之后的列放在一起(水平放置),即它构成一个笛卡尔积。

函数

不同数据库的函数往往各不相同,因此不可移植,如AVG()等函数

性能优先:避免在 WHERE 条件中对字段使用函数(如 WHERE YEAR(date) = 2025),否则索引可能失效。可改用范围查询:

WHERE date >= '2025-01-01' AND date < '2026-01-01'

字符串函数

函数功能说明示例注意事项
CONCAT(str1, str2)拼接字符串SELECT CONCAT(first_name, ’ ', last_name) FROM employees;若任一参数为 NULL,返回 NULL
SUBSTRING(str, start, length)截取子字符串SELECT SUBSTRING(‘2023Q4’, 5, 1) AS quarter; → ‘Q’索引从 1 开始
LENGTH(str)返回字节数(中文通常占3字节)SELECT LENGTH(‘数据’) → 6需与 CHAR_LENGTH()(字符数)区分
REPLACE(str, old, new)替换指定子串SELECT REPLACE(‘Hello SQL’, ‘SQL’, ‘MySQL’) → ‘Hello MySQL’严格区分大小写
TRIM([BOTH/LEADING/TRAILING] ‘x’ FROM str)去除首尾指定字符SELECT TRIM(LEADING ‘0’ FROM ‘000123’) → ‘123’默认去除空格

数值函数

函数功能说明示例注意事项
ROUND(num, decimals)四舍五入保留小数位数SELECT ROUND(3.1415, 2) → 3.14第二参数为负数时向整数位舍入
CEIL(num)向上取整SELECT CEIL(2.3) → 3常用于分页计算(总页数)
ABS(num)绝对值SELECT ABS(-15) → 15支持整数和浮点数
MOD(num1, num2)取余运算SELECT MOD(10, 3) → 1等价于 % 运算符
RAND()生成 0~1 的随机数SELECT RAND() → 0.7632…可配合 ORDER BY RAND() 随机排序

日期时间函数

函数功能说明示例注意事项
NOW()当前日期和时间SELECT NOW() → 2025-07-15 15:48:00返回结果带时区(会话时区)
DATE_FORMAT(date, format)格式化日期SELECT DATE_FORMAT(NOW(), ‘%Y年%m月%d日’) → ‘2025年07月15日’%H 为 24 小时制小时
DATEDIFF(date1, date2)计算日期差(天数)SELECT DATEDIFF(‘2025-12-31’, NOW()) → 169仅比较日期部分
DATE_ADD(date, INTERVAL expr unit)日期加减运算SELECT DATE_ADD(NOW(), INTERVAL 7 DAY) → 2025-07-22 15:48:00支持 YEAR、MONTH、MINUTE 等单位
TIMESTAMPDIFF(unit, start, end)计算时间差(灵活单位)SELECT TIMESTAMPDIFF(MONTH, ‘2025-01-01’, NOW()) → 6支持秒、小时、周等单位

聚合函数

函数功能说明示例注意事项
COUNT(expr)统计行数(排除 NULL)SELECT COUNT(DISTINCT user_id) FROM orders; COUNT(*)统计所有行
SUM(expr)求和SELECT SUM(price * quantity) AS total FROM order_items;自动跳过 NULL 值
AVG(expr)平均值SELECT AVG(salary) FROM employees WHERE dept = ‘IT’;结果为浮点数(即使整数列)
GROUP_CONCAT(expr [SEPARATOR sep])合并分组后的字符串SELECT dept, \GROUP_CONCAT(name SEPARATOR ', ') FROM employees GROUP BY dept;默认长度限制 1024 字符(可通过 SET 调整)
MAX(expr)/MIN(expr)最大/最小值SELECT MAX(temperature), MIN(temperature) FROM sensors;支持日期、字符串比较

事务处理TCL

MySQL 默认是隐式提交,每执行一条语句就把这条语句当成一个事务然后进行提交

当出现 START TRANSACTION 语句时,会关闭隐式提交
当 COMMIT 或 ROLLBACK 语句执行后,事务会自动关闭重新恢复隐式提交

通过 set autocommit=0 可以取消自动提交,直到 set autocommit=1 才会提交

autocommit 标记是针对每个连接而不是针对服务器的

指令:

  • START TRANSACTION - 指令用于标记事务的起始点
  • SAVEPOINT - 指令用于创建保留点
  • ROLLBACK TO - 指令用于回滚到指定的保留点;如果没有设置保留点,则回退到 START TRANSACTION 语句处
  • COMMIT - 提交事务
-- 开始事务
START TRANSACTION;

-- 插入操作 A
INSERT INTO `user`
VALUES (1, 'root1', 'root1', 'xxxx@163.com');

-- 创建保留点 updateA
SAVEPOINT updateA;

-- 插入操作 B
INSERT INTO `user`
VALUES (2, 'root2', 'root2', 'xxxx@163.com');

-- 回滚到保留点 updateA
ROLLBACK TO updateA;

-- 提交事务,只有操作 A 生效
COMMIT;

权限控制DCL

要授予用户帐户权限,可以用GRANT命令。要撤销用户的权限,可以用REVOKE命令

这个平时使用比较少,就不说嘛详细了,后续使用了再补充…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值