一、先看 DDL 的整体结构(骨架)
大部分ddl都是长一下这个结构的样子:
sql
CREATE TABLE `表名` (
-- 第一部分:字段定义(列名 + 类型 + 属性 + 注释)
`字段名` 数据类型 字段属性 COMMENT '字段注释',
-- 第二部分:索引/约束定义(主键、唯一键、普通索引)
PRIMARY KEY (...),
UNIQUE KEY (...),
KEY (...),
-- 第三部分:表级配置(存储引擎、字符集、自增起始值等)
) ENGINE=InnoDB AUTO_INCREMENT=xxx DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='表注释';
二、逐类拆解关键字
第一类:字段定义核心关键字(每行字段的组成)
| 关键字 / 语法 | 例子(从表中摘) | 含义 + 作用 + 业务场景 |
|---|---|---|
CREATE TABLE |
CREATE TABLE ```order\ (` |
创建表的核心语法,指定要创建的表名(反引号 ` 是避免表名和关键字冲突) |
字段名 |
id/order_code/tracking_no |
列的名称,必须唯一,命名要贴合业务(比如order_code就是订单号) |
数据类型 |
int(11)/varchar(50)/decimal(11,3)/timestamp |
定义字段存储的数据类型: ①int(11) :整数,11 是显示宽度(无实际存储意义),存account_id/shop_id等数字 ID; ② unsigned :搭配 int,表示无符号(只能存非负数),比如id不会是负数; ③ varchar(50) :可变长度字符串,50 是最大长度,存order_code/tracking_no等文本(节省空间); ④ decimal(11,3) :高精度小数,11 位总长度、3 位小数,存freight_fee(运费),避免浮点数精度丢失; ⑤ timestamp :时间戳,存create_time/update_time等时间; ⑥ tinyint(2) :微整型,存kd_status/source等枚举类小数字(0/1/2 等) |
NOT NULL |
id int(11) unsigned NOT NULL |
++字段不允许为空++,是强制数据完整性的约束: 比如order_code/tracking_no是核心字段,必须填,否则订单无意义; 反例:abnormal_problem_reason(异常原因)只有异常订单才填,所以可以NULL |
DEFAULT '值' |
account_id int(11) NOT NULL DEFAULT '0' |
字段默认值: ① ++DEFAULT '0':数字字段默认填 0++ ,比如account_id未指定时默认 0; ② DEFAULT CURRENT_TIMESTAMP:create_time默认值为当前时间(创建记录时自动填) |
AUTO_INCREMENT |
id int(11) unsigned NOT NULL AUTO_INCREMENT |
自增属性:仅用于主键(通常是id)。 ++新增记录时 id自动 + 1,保证主键唯一++ (比如新增订单时不用手动填 id,数据库自动生成) |
NULL |
date_create timestamp NULL DEFAULT NULL |
++字段允许为空++(可省略,因为默认允许) 比如date_shipping(出库时间)只有发货后才填,未发货时为空 |
ON UPDATE CURRENT_TIMESTAMP |
update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP |
自动更新时间:update_time在记录创建时填当前时间,++每次修改记录时自动刷新为当前时间++,用于追踪数据最后修改时间(排查问题时能知道订单最后改了什么) |
COMMENT |
COMMENT '海外仓订单'/COMMENT '订单号' |
字段 / 表的注释: ① 字段注释:解释字段含义,比如status注释写清 "C: 待发货审核",避免后续看不懂; ② 表注释:解释整张表的用途,比如 "海外仓订单" |
第二类:索引 / 约束关键字
核心是 "约束保证数据正确,索引加速查询"
| 关键字 | 例子 | 含义 + 作用 + 业务场景 |
|---|---|---|
| PRIMARY KEY | PRIMARY KEY (id) |
主键约束: ① 作用:保证字段值++唯一且非空++,一张表只能有 1 个主键; ② 业务意义:id是订单的 "物理唯一标识",不管订单号怎么变,id永远唯一(比如重复订单号但 id 不同,能区分); ③ 底层:InnoDB 引擎中,主键是聚簇索引,数据按主键排序存储,查询效率最高 |
| UNIQUE KEY | UNIQUE KEY uniq_order (order_code,tracking_no) |
唯一键约束: ① 作用:保证组合字段值++唯一++(可以有多个唯一键),但允许字段为空(和主键的区别); ② 命名:uniq_order是唯一键的名称(自定义,方便维护); ③ 业务意义:order_code+tracking_no唯一,避免 "同一个订单号 + 同一个物流单号" 重复创建 |
| KEY (等价于INDEX) | KEY idx_kd_code (kd_code)/KEY idx_shopify_order_id (shopify_order_id) |
普通索引(非唯一): ① 作用:加速查询,不保证字段唯一; ② 命名:idx_字段名是通用规范(idx=index),比如idx_kd_code是给xx单号加索引; ③ 业务意义: 1、查 "某个单号的订单":WHERE kd_code='XXX',加索引后不用全表扫描,速度快; 2、查 "某个订单对应的海外仓订单":WHERE order_id='12449537622182',索引加速 |
第三类:表级配置关键字
(整表的存储规则,一般是通用的,了解即可)
| 关键字 | 含义 + 作用 + 业务场景 |
|---|---|
ENGINE=InnoDB |
存储引擎: ① InnoDB 是 MySQL 默认引擎,支持事务、行级锁、外键、崩溃恢复; ② 业务意义:海外仓订单数据重要,InnoDB 的事务特性能保证 "创建订单 + 创建明细" 要么都成功,要么都失败(避免数据不一致) |
AUTO_INCREMENT=60549744 |
自增主键的起始值:表示下一个新增订单的id从 60549744 开始 |
DEFAULT CHARSET=utf8mb4 |
字符集: ① utf8mb4是 utf8 的超集,支持 emoji、生僻字; ② 业务意义:订单可能包含海外字符(比如客户地址、商品名称),避免乱码 |
ROW_FORMAT=DYNAMIC |
行存储格式: ① 动态行格式,针对varchar等可变长度字段,只存储实际长度的数据(节省磁盘空间); ② 业务意义:订单表字段多个,动态格式能减少存储空间,提升查询效率 |
三、怎么快速看懂陌生表的 DDL
- 先看表注释:知道这张表是干嘛的(比如 "海外仓订单");
- 再看主键 :找到物理唯一标识(比如
id); - 再看 UNIQUE KEY :找到业务唯一的字段组合(比如
order_code+tracking_no); - 再看 KEY(普通索引) :知道哪些字段常用查询(比如
shopify_order_id); - 最后看字段属性 :重点看
NOT NULL的字段(核心业务字段)、DEFAULT(默认规则)。