表设计规范
TIP
规定数据库表结构、字段类型、索引设计等规范,适用于 MySQL 8.4 数据库。
设计原则
| 原则 | 说明 |
|---|---|
| 必备字段 | 每张表必须包含通用审计字段(id、create_by、create_time 等) |
| 软删除 | 使用 del_flag 实现逻辑删除,不物理删除数据 |
| 乐观锁 | 使用 version 字段实现乐观锁,防止并发更新冲突 |
| 索引合理 | 高频查询字段建立索引,避免全表扫描 |
| 字段精简 | 字段数量建议不超过 30 个,超出考虑垂直拆分 |
必备字段
所有业务表必须包含以下字段:
| 字段 | 类型 | 约束 | 说明 |
|---|---|---|---|
id | BIGINT UNSIGNED | PRIMARY KEY, AUTO_INCREMENT | 主键 ID |
create_by | VARCHAR(64) | NOT NULL, DEFAULT '' | 创建人 |
create_time | DATETIME | NOT NULL, DEFAULT CURRENT_TIMESTAMP | 创建时间 |
last_update_by | VARCHAR(64) | NOT NULL, DEFAULT '' | 最后更新人 |
last_update_time | DATETIME | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 最后更新时间 |
del_flag | INT | NOT NULL, DEFAULT 0 | 删除标记(0=正常,1=删除) |
status | INT | NOT NULL, DEFAULT 0 | 状态(0=启用,1=禁用) |
version | INT | NOT NULL, DEFAULT 0 | 乐观锁版本号 |
建表示例
sql
CREATE TABLE `sys_user` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`account` VARCHAR(64) NOT NULL COMMENT '账号',
`user_name` VARCHAR(64) NOT NULL COMMENT '用户名',
`dept_id` BIGINT DEFAULT NULL COMMENT '部门ID',
`dept_code` VARCHAR(64) DEFAULT NULL COMMENT '部门编码',
`dept_level` INT DEFAULT NULL COMMENT '部门级别',
`company_id` BIGINT DEFAULT NULL COMMENT '公司ID',
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注',
`create_by` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '创建人',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`last_update_by` VARCHAR(64) NOT NULL DEFAULT '' COMMENT '最后更新人',
`last_update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
`del_flag` INT NOT NULL DEFAULT 0 COMMENT '删除标记(0=正常,1=删除)',
`status` INT NOT NULL DEFAULT 0 COMMENT '状态(0=启用,1=禁用)',
`version` INT NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_account` (`account`),
KEY `idx_user_name` (`user_name`),
KEY `idx_dept_id` (`dept_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';字段类型规范
整数类型
| 类型 | 范围 | 适用场景 |
|---|---|---|
TINYINT | -128 ~ 127 | 状态、标志位(sex、status、del_flag) |
SMALLINT | -32768 ~ 32767 | 短整数(level、type) |
INT | 常规范围 | 普通整数字段 |
BIGINT | 大范围 | 主键 ID、外键 ID |
字符串类型
| 类型 | 适用场景 | 示例 |
|---|---|---|
VARCHAR(n) | 变长字符串(用户名、账号、编码) | account VARCHAR(64) |
CHAR(n) | 固定长度字符串 | salt CHAR(32) |
TEXT | 长文本(备注、描述) | remark TEXT |
常用字段长度参考
| 字段 | 推荐类型 | 说明 |
|---|---|---|
| 账号 | VARCHAR(64) | 支持邮箱、用户名格式 |
| 用户名 | VARCHAR(64) | 中文 + 英文 |
| 手机号 | VARCHAR(20) | 国际号码兼容 |
| 邮箱 | VARCHAR(128) | 邮箱地址 |
| URL | VARCHAR(512) | 链接地址 |
| 备注 | VARCHAR(255) | 短备注 |
| 长描述 | TEXT | 长文本内容 |
日期时间类型
| 类型 | 格式 | 适用场景 |
|---|---|---|
DATETIME | YYYY-MM-DD HH:MM:SS | 审计字段(create_time、update_time) |
DATE | YYYY-MM-DD | 仅日期(birth_date) |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 需要自动转换时区的场景 |
索引设计规范
必须创建的索引
| 索引类型 | 字段 | 说明 |
|---|---|---|
| 主键索引 | id | 每张表必须有主键 |
| 唯一索引 | account、mobile | 业务唯一约束 |
| 普通索引 | dept_id、create_time | 高频查询条件 |
联合索引设计原则
- 遵循最左前缀原则
- 将高区分度字段放在前面
- 将等值查询字段放在范围查询字段前面
text
✅ idx_dept_id_status (dept_id, status) # 等值 + 等值
✅ idx_dept_id_create_time (dept_id, create_time) # 等值 + 范围
❌ idx_create_time_dept_id (create_time, dept_id) # 范围 + 等值(不符合最左前缀)索引数量控制
- 单表索引数量建议不超过 5 个
- 避免在低区分度字段上建索引(如 status、sex)
- 避免在大文本字段上建索引
关联表设计
一对多
主表 ID 作为从表外键:
sql
-- 用户表(主表)
CREATE TABLE `sys_user` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`dept_id` BIGINT DEFAULT NULL COMMENT '部门ID',
PRIMARY KEY (`id`)
);
-- 通过 dept_id 关联部门多对多
使用关联表存储关系:
sql
-- 用户角色关联表
CREATE TABLE `sys_user_role` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` BIGINT NOT NULL COMMENT '用户ID',
`role_id` BIGINT NOT NULL COMMENT '角色ID',
`create_by` VARCHAR(64) NOT NULL DEFAULT '',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`del_flag` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表';字段约束规范
NOT NULL 约束
- 业务必填字段必须
NOT NULL - 设置合理的
DEFAULT值
text
✅ account VARCHAR(64) NOT NULL COMMENT '账号'
✅ status INT NOT NULL DEFAULT 0 COMMENT '状态'
❌ account VARCHAR(64) DEFAULT NULL COMMENT '账号' -- 账号不应为空注释
- 每个字段必须有
COMMENT - 枚举值需在注释中列出含义
text
✅ status INT NOT NULL DEFAULT 0 COMMENT '状态(0=启用,1=禁用)'
✅ sex TINYINT DEFAULT NULL COMMENT '性别(1=男,2=女)'
❌ status INT NOT NULL DEFAULT 0 -- 缺少注释反例与正例
缺少必备字段
sql
-- ❌ 缺少审计字段
CREATE TABLE `sys_user` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`account` VARCHAR(64) NOT NULL,
`user_name` VARCHAR(64) NOT NULL,
PRIMARY KEY (`id`)
);
-- ✅ 包含所有必备字段
CREATE TABLE `sys_user` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`account` VARCHAR(64) NOT NULL,
`user_name` VARCHAR(64) NOT NULL,
`create_by` VARCHAR(64) NOT NULL DEFAULT '',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_update_by` VARCHAR(64) NOT NULL DEFAULT '',
`last_update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`del_flag` INT NOT NULL DEFAULT 0,
`status` INT NOT NULL DEFAULT 0,
`version` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
);字段过多
sql
-- ❌ 单表字段超过 30 个
CREATE TABLE `sys_user` (
-- 30+ 字段,难以维护
);
-- ✅ 垂直拆分,将不常用字段拆到扩展表
CREATE TABLE `sys_user` (
-- 核心字段
);
CREATE TABLE `sys_user_ext` (
`user_id` BIGINT NOT NULL,
-- 扩展字段
);缺少索引
sql
-- ❌ 高频查询字段无索引
CREATE TABLE `sys_user` (
`account` VARCHAR(64) NOT NULL,
`user_name` VARCHAR(64) NOT NULL
);
-- ✅ 合理索引
CREATE TABLE `sys_user` (
`account` VARCHAR(64) NOT NULL,
`user_name` VARCHAR(64) NOT NULL,
UNIQUE KEY `uk_account` (`account`),
KEY `idx_user_name` (`user_name`)
);表设计 Checklist
建表/改表前自查:
- 表名符合命名规范(
sys_前缀 + snake_case) - 包含所有必备字段(id、create_by、create_time、last_update_by、last_update_time、del_flag、status、version)
- 每张表有主键(
idBIGINT UNSIGNED AUTO_INCREMENT) - 字段类型选择合理(整数/字符串/日期)
- 字段设置了 NOT NULL 和 DEFAULT
- 每个字段有 COMMENT 注释
- 唯一约束字段建立唯一索引
- 高频查询字段建立普通索引
- 单表索引不超过 5 个
- 字符集使用 utf8mb4
- 存储引擎使用 InnoDB
- 表注释完整