DDL 是什么?建库建表时必须知道的“结构开关”
DDL(Data Definition Language)是定义数据库骨架的语言,它不碰数据本身,只管“有没有这张表”“字段叫什么”“主键在哪”。一旦执行
CREATE、
ALTER、
DROP,结构就变了,且多数操作不可回滚。
CREATE DATABASE IF NOT EXISTS db_name DEFAULT CHARSET utf8mb4;—— 加
IF NOT EXISTS避免脚本重复执行报错
CREATE TABLE里别漏掉
NOT NULL和
DEFAULT,否则插入空值可能意外失败或存入
0/
''
TRUNCATE TABLE t1;比
DELETE FROM t1;快得多,但会重置自增 ID,且无法加 WHERE 条件
ALTER TABLE修改列类型时,若已有数据不兼容新类型(比如把
VARCHAR(10)改成
CHAR(2)),MySQL 会直接报错
ERROR 1265 (01000): Data truncated for column
DML 和 DQL 别混:增删改是 DML,查是 DQL
严格来说,
SELECT属于 DQL(Data Query Language),不是 DML。DML 只负责变更数据:
INSERT、
UPDATE、
DELETE。这点在权限配置和 binlog 解析时特别关键——比如你只给用户 DML 权限,他连
SELECT都不能执行。
INSERT INTO t1 (a,b) VALUES (1,'x'),(2,'y');—— 多行插入比循环单条快一个数量级,但注意 max_allowed_packet 限制
UPDATE t1 SET status = 1 WHERE id IN (SELECT id FROM tmp_ids);—— MySQL 8.0+ 支持,但老版本会报错
You can't specify target table 't1' for update in FROM clause,得用 JOIN 绕过
DELETE FROM t1 LIMIT 1000;—— 加
LIMIT防止误删全表;线上大表删除建议分批 + sleep,避免锁表太久
SELECT * FROM t1 WHERE name LIKE '%abc';—— 左模糊无法走索引,查得慢还容易拖垮连接数
DCL 权限控制:GRANT 不等于“给所有权限”
GRANT和
REVOKE管的是“谁能干什么”,不是功能开关。常见误区是以为
GRANT SELECT ON db.* TO 'u'@'%'就能让用户连上数据库——其实他还需要
USAGE权限(即连接权限),而这个权限是创建用户时自动赋予的;但若用
CREATE USER单独建号,没显式
GRANT,就连不上。 生产环境禁止用
GRANT ALL PRIVILEGES,哪怕只给一个开发库;最小权限原则:只开
SELECT, INSERT, UPDATE,禁用
DROP和
ALTER
GRANT SELECT (id,name) ON db.t1 TO 'u'@'%';—— 列级授权,用户只能查这两列,其他字段返回
NULL(需 MySQL 8.0+) 权限修改后,记得执行
FLUSH PRIVILEGES;—— 大多数情况不用,但若直接改了
mysql.user表,就必须刷
TCL 事务控制:COMMIT 前 rollback 才有效
TCL(Transaction Control Language)只对支持事务的引擎(如 InnoDB)生效,MyISAM 完全无视
BEGIN/
COMMIT。而且事务边界很脆弱:客户端断连、超时、甚至某些 SQL 语句(如
DLL)会隐式触发
COMMIT。
START TRANSACTION;或
BEGIN;后,所有后续 DML 都在同一个事务里,直到
COMMIT或
ROLLBACK
SAVEPOINT sp1;+
ROLLBACK TO sp1;可实现部分回滚,但嵌套太深会影响性能,也难维护 执行
CREATE TABLE、
DROP TABLE后,当前事务会自动提交——这是很多人踩坑的地方:以为还能
ROLLBACK,结果结构已变 长事务(>10s)会拖慢 purge 线程,堆积 undo log,严重时导致磁盘爆满;线上应监控
information_schema.INNODB_TRX表
DDL 的隐式提交、DQL 和 DML 的权限分离、TCL 在 DDL 前的失效点——这些不是冷知识,而是每天上线、迁移、排障时真实卡住人的地方。
