当前位置: 首页 > backend >正文

MySQL 的 DDL / DML / DQL / DCL 做一次系统梳理:概念区别→常用语法→特点与注意点→实战小例子→常见面试/坑点速记

一、四大类的定位(先看这张速查表)

类别全称主要作用典型语句是否改动数据是否改动结构事务性权限相关
DDLData Definition Language定义/变更数据库对象结构CREATE / ALTER / DROP / RENAME / TRUNCATE否(但会影响数据存在形态,TRUNCATE 会清空)有些操作可原子化(8.0起部分原子DDL),通常自动提交
DMLData Manipulation Language新增/修改/删除数据INSERT / UPDATE / DELETE / REPLACE支持事务
DQLData Query Language查询数据SELECT(含 JOIN/GROUP BY/HAVING/WINDOW 等)参与事务一致性(快照读/锁定读)
DCLData Control Language账户、权限与角色控制CREATE USER / GRANT / REVOKE / DROP USER / CREATE ROLE不涉及业务事务

另外常见还有 TCL(Transaction Control Language)START TRANSACTION / COMMIT / ROLLBACK / SAVEPOINT / SET TRANSACTION,配合 DML 使用。


二、DDL(定义结构)

1)创建库/表

-- 创建数据库
CREATE DATABASE IF NOT EXISTS shopDEFAULT CHARACTER SET utf8mb4DEFAULT COLLATE utf8mb4_0900_ai_ci;-- 创建表(InnoDB、主键、自增、唯一索引、外键)
CREATE TABLE IF NOT EXISTS shop.user (id        BIGINT PRIMARY KEY AUTO_INCREMENT,username  VARCHAR(50) NOT NULL UNIQUE,email     VARCHAR(100),created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;-- 订单表,外键参照 user(id)
CREATE TABLE shop.orders (id        BIGINT PRIMARY KEY AUTO_INCREMENT,user_id   BIGINT NOT NULL,amount    DECIMAL(10,2) NOT NULL,status    ENUM('PENDING','PAID','CANCELLED') NOT NULL DEFAULT 'PENDING',created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,CONSTRAINT fk_orders_userFOREIGN KEY (user_id) REFERENCES shop.user(id)ON UPDATE CASCADEON DELETE RESTRICT
) ENGINE=InnoDB;

2)修改、删除结构

-- 增加列 / 修改列类型 / 重命名列
ALTER TABLE shop.user ADD COLUMN phone VARCHAR(20) AFTER email;
ALTER TABLE shop.user MODIFY COLUMN phone VARCHAR(30);
ALTER TABLE shop.user RENAME COLUMN phone TO mobile;-- 索引:创建/删除(也可写在 ALTER TABLE 中)
CREATE INDEX idx_orders_userid ON shop.orders(user_id);
DROP INDEX idx_orders_userid ON shop.orders;-- 重命名表 / 删除表 / 清空表
RENAME TABLE shop.orders TO shop.order_main;
DROP TABLE IF EXISTS shop.order_main;
TRUNCATE TABLE shop.user; -- 清空数据、重置自增,速度快,DDL 语句

DDL 特点与注意

  • 自动提交:DDL 通常隐式提交事务,不会被后续 ROLLBACK 回滚。

  • 元数据锁(MDL)ALTER/CREATE/DROP 会对表加 MDL,可能阻塞业务。

  • TRUNCATE vs DELETETRUNCATE 是 DDL,清空全表、重置自增、不可逐行触发触发器;DELETE 是 DML,可带 WHERE、可回滚(在事务中)。

  • 字符集:MySQL 8.x 推荐 utf8mb4;避免历史 utf8(不完整)。


三、DML(操作数据)

1)INSERT(含批量、插入或更新)

-- 单行/多行插入
INSERT INTO shop.user (username, email) VALUES('alice', 'alice@x.com'),('bob', 'bob@x.com');-- 基于查询插入
INSERT INTO shop.orders (user_id, amount, status)
SELECT id, 99.99, 'PENDING' FROM shop.user WHERE username='alice';-- Upsert:主键/唯一键冲突时更新(MySQL 常用)
INSERT INTO shop.user (id, username, email)
VALUES (1, 'alice', 'a@x.com')
ON DUPLICATE KEY UPDATE email = VALUES(email), updated_at = CURRENT_TIMESTAMP;-- 插入忽略错误(如唯一键冲突直接跳过)
INSERT IGNORE INTO shop.user (username, email) VALUES ('alice', 'dup@x.com');

2)UPDATE / DELETE

-- 更新
UPDATE shop.user
SET email='alice_new@x.com'
WHERE username='alice';-- 带 JOIN 的更新(MySQL 支持)
UPDATE shop.orders o
JOIN shop.user u ON o.user_id = u.id
SET o.status='CANCELLED'
WHERE u.username='bob';-- 删除:务必加 WHERE,结合事务
DELETE FROM shop.orders WHERE status='CANCELLED' AND created_at < NOW() - INTERVAL 30 DAY;

3)REPLACE(MySQL 特有)

-- 如果存在相同主键/唯一键记录:先删后插;否则直接插
REPLACE INTO shop.user (id, username, email) VALUES (1, 'alice', 're@x.com');

DML 特点与注意

  • 事务支持(InnoDB):用 START TRANSACTION ... COMMIT/ROLLBACK 保证原子性。

  • 批量写入:合并多行 INSERT 明显快于逐行。

  • UpsertINSERT ... ON DUPLICATE KEY UPDATE 优于先查后更;REPLACE删除重建(触发删除副作用)。

  • 安全更新模式:某些客户端默认不允许无条件 UPDATE/DELETE;建议总是加 WHERELIMIT(如果语义允许)。


四、DQL(查询数据)

1)基础查询

-- 投影/过滤/排序/分页
SELECT id, username, email
FROM shop.user
WHERE email LIKE '%@x.com'
ORDER BY id DESC
LIMIT 10 OFFSET 0;

2)聚合与分组

SELECT u.id, u.username, COUNT(o.id) AS order_cnt, SUM(o.amount) AS total_amount
FROM shop.user u
LEFT JOIN shop.orders o ON o.user_id = u.id AND o.status='PAID'
GROUP BY u.id, u.username
HAVING COUNT(o.id) > 0
ORDER BY total_amount DESC;

3)子查询 / CTE(8.0+)

-- 子查询
SELECT * FROM shop.user
WHERE id IN (SELECT user_id FROM shop.orders WHERE amount > 100);-- CTE(WITH)可读性更好
WITH big_order AS (SELECT user_id, amount FROM shop.orders WHERE amount > 100
)
SELECT u.username, b.amount
FROM shop.user u
JOIN big_order b ON b.user_id = u.id;

4)窗口函数(8.0+)

-- 计算每个用户订单累积金额与序号
SELECTo.id, o.user_id, o.amount,SUM(o.amount) OVER (PARTITION BY o.user_id ORDER BY o.created_at) AS running_total,ROW_NUMBER() OVER (PARTITION BY o.user_id ORDER BY o.amount DESC) AS rn
FROM shop.orders o;

5)一致性与锁

  • 快照读:普通 SELECT 读取一致性视图,不加锁。

  • 锁定读SELECT ... FOR UPDATE / LOCK IN SHARE MODE 会加行锁,常用于事务内检查后再修改。

  • EXPLAIN:优化查询前先 EXPLAIN 看执行计划;必要时建索引或调整 SQL。


五、DCL(账户、权限、角色)

1)账户与密码

-- 创建用户(限制来源主机)
CREATE USER 'reporter'@'%' IDENTIFIED BY 'StrongP@ssw0rd';-- 修改密码 / 失效
ALTER USER 'reporter'@'%' IDENTIFIED BY 'StrongerP@ss1';
DROP USER 'reporter'@'%';

2)授权与回收

-- 授权(最小权限原则)
GRANT SELECT ON shop.* TO 'reporter'@'%';
GRANT SELECT, INSERT, UPDATE, DELETE ON shop.orders TO 'reporter'@'%';-- 查看与回收
SHOW GRANTS FOR 'reporter'@'%';
REVOKE INSERT, UPDATE, DELETE ON shop.orders FROM 'reporter'@'%';

3)角色(8.0+)

CREATE ROLE 'read_only';
GRANT SELECT ON shop.* TO 'read_only';
GRANT 'read_only' TO 'reporter'@'%';
SET DEFAULT ROLE 'read_only' TO 'reporter'@'%';

说明:MySQL 8 起支持动态权限(如 REPLICATION SLAVE ADMIN 等),用于管理运维功能;常见业务中以对象级(库/表/列/过程)权限为主。


六、TCL(事务控制,配合 DML)

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- MySQL 默认START TRANSACTION;UPDATE shop.orders SET status='PAID' WHERE id=1001;SAVEPOINT s1;UPDATE shop.user SET email='oops@x.com' WHERE id=1;ROLLBACK TO s1; -- 撤销误操作
COMMIT;

要点

  • 尽量短事务,避免长时间持锁。

  • 明确隔离级别对“幻读/不可重复读”的影响;需要强一致时用 SELECT ... FOR UPDATE


七、典型对比与坑点速记

  1. DROP vs TRUNCATE vs DELETE

  • DROP TABLE:删表定义+数据,结构直接没了。

  • TRUNCATE TABLE:清空数据、重置自增,快,不可逐行回滚/触发器。

  • DELETE FROM t:逐行删除,可加 WHERE,在事务内可回滚。

  1. INSERT 冲突处理

  • INSERT ... ON DUPLICATE KEY UPDATE(推荐)

  • REPLACE INTO:实际是删后重插,可能触发“删除副作用”。

  1. 索引

  • where/join/order by/group by 的列要评估索引;避免函数包裹导致索引失效(如 WHERE DATE(created_at)=...)。

  • 组合索引遵循最左前缀

  1. 外键

  • 需要事务型引擎 InnoDB;明确 ON DELETE/UPDATE CASCADE|RESTRICT|SET NULL 语义。

  • 大吞吐写场景要评估外键带来的约束检查成本。

  1. 字符集与排序规则

  • 统一 utf8mb4,跨库/表/连接保持一致,避免“问号/乱码”。

  1. 原子 DDL(8.0+)

  • 部分 DDL 具备原子性(失败自动回滚元数据),但依旧会隐式提交,不能当普通事务使用。


八、从零到一:小实战脚本(可直接粘贴)

-- 1. 结构(DDL)
CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARACTER SET utf8mb4;
USE demo;CREATE TABLE user (id BIGINT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100),created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;CREATE TABLE orders (id BIGINT PRIMARY KEY AUTO_INCREMENT,user_id BIGINT NOT NULL,amount DECIMAL(10,2) NOT NULL,status ENUM('PENDING','PAID','CANCELLED') NOT NULL DEFAULT 'PENDING',created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES user(id)
) ENGINE=InnoDB;CREATE INDEX idx_orders_userid ON orders(user_id);-- 2. 数据(DML)
INSERT INTO user (username, email) VALUES('alice', 'alice@x.com'),('bob', 'bob@x.com');INSERT INTO orders (user_id, amount, status)
SELECT id, 128.88, 'PAID' FROM user WHERE username='alice';-- 3. 查询(DQL)
SELECT u.username, COUNT(o.id) AS cnt, SUM(o.amount) AS total
FROM user u
LEFT JOIN orders o ON o.user_id = u.id
GROUP BY u.id, u.username
HAVING total IS NOT NULL
ORDER BY total DESC;-- 4. 权限(DCL)
CREATE USER 'reporter'@'%' IDENTIFIED BY 'StrongP@ss';
GRANT SELECT ON demo.* TO 'reporter'@'%';


九、记忆

  • 改结构用 DDL;

  • 改数据用 DML;

  • 查数据是 DQL;

  • 管权限用 DCL;

  • 管事务用 TCL。

  • 安全与性能两条线:权限最小化(DCL)、索引+EXPLAIN(DQL)、短事务(TCL)、避免无 WHERE 的批量 DML

  • 面试常问:DELETE vs TRUNCATE vs DROPON DUPLICATE KEY UPDATE事务隔离级别最左前缀原则SELECT ... FOR UPDATE 场景。

http://www.xdnf.cn/news/17983.html

相关文章:

  • redis的key过期删除策略和内存淘汰机制
  • JavaWeb开发_Day14
  • Python虚拟环境与包管理工具(uv、Conda)
  • 发文暴论!线性注意力is all you need!
  • 【LeetCode每日一题】
  • Python---异常链(Exception Chaining)
  • sharding-jdbc读写分离配置
  • Spring——关于Bean以及自动配置
  • FTP上传文件错误
  • BM25算法和传统的TF-IDF算法的区别
  • IEEEtaes.cls解析
  • Trae中`settings.json`文件的Java配置项功能详解(二)
  • 343整数拆分
  • 双椒派E2000D开发板LED驱动开发实战指南
  • 随机整数列表处理:偶数索引降序排序
  • 杂记 03
  • 软件需求工程详解
  • 【自用】JavaSE--特殊文件Properties与XML、日志技术
  • 项目管理进阶——解读大型IT系统集成项目实施要点培训【附全文阅读】
  • 主从复制+哨兵
  • GPFS集群性能压测
  • MySQL的下载安装(MSI和ZIP版本都有)
  • Linux上配置环境变量
  • UDP/TCP套接字编程简单实战指南
  • 【总结型】c语言中的位运算
  • Hugging Face 与 NLP
  • Express开发快速学习
  • Spring Cloud系列—Alibaba Seata分布式事务
  • B站 韩顺平 笔记 (Day 20)
  • 创建maven module中的override