6.7 KiB
6.7 KiB
04 — 数据库表设计规则
适用:所有涉及建表、改表、索引设计的 AI 开发任务。
命名规则
| 元素 | 规则 | 示例(正确 → 错误) |
|---|---|---|
| 表名 | 小写,下划线分隔,单数名词 | task_apply → ❌ TaskApply task_applies |
| 字段名 | 小写,下划线分隔 | create_time task_id → ❌ createdAt taskId |
| 主键 | 统一用 id |
id → ❌ task_id pk_id |
| 外键 | 关联表名_id |
task_id user_id → ❌ tid uid |
| 布尔字段 | del_flag 或明确业务含义的 is_ 前缀 |
del_flag is_active → ❌ deleted status |
| 时间字段 | _time 后缀 |
create_time update_time → ❌ created_at updateTime |
| 金额字段 | _amount 后缀 |
reward_amount → ❌ reward price |
| 索引名 | idx_表名_字段 |
idx_task_status → ❌ index1 task_status_idx |
| 唯一索引 | uk_表名_字段 |
uk_user_phone → ❌ uq_phone |
| 关联表 | 两表名用下划线连接 | task_apply user_role → ❌ apply_task |
长度控制
表名超过 3 个单词或 30 个字符时缩写。前缀也要缩成一个单词。
| 完整 | 缩写 | JeecgBoot 实际案例 |
|---|---|---|
| department | dept | sys_depart_role_permission → sys_dept_role_perm |
| permission | perm | 同上 |
| announcement | notice | sys_announcement_send → sys_notice_send |
| message | msg | sys_message_template → sys_msg_template |
-- ❌ JeecgBoot 原版 — 太长
sys_depart_role_permission -- 26 字符
sys_permission_data_rule -- 24 字符
-- ✅ 缩写后
sys_dept_role_perm -- 19 字符
sys_perm_data_rule -- 20 字符
字段类型规范
| 场景 | 类型 | 说明 |
|---|---|---|
| 主键 | BIGINT 自增 或 VARCHAR(32) |
推荐 BIGINT 自增;分布式用雪花ID |
| 短文本 | VARCHAR(N) |
姓名(50)、标题(200)、URL(500) |
| 长文本 | TEXT / LONGTEXT |
文章、JSON、描述 |
| 金额 | DECIMAL(12,2) |
禁止用 FLOAT/DOUBLE |
| 状态/类型 | VARCHAR(20) 或 TINYINT |
枚举值,必须有注释说明 |
| 布尔 | TINYINT(1) |
0=否 1=是,注释必须写清含义 |
| 时间 | DATETIME |
禁止用 TIMESTAMP(2038 问题) |
| 日期 | DATE |
生日、截止日期 |
| 数量 | INT 或 BIGINT |
每张表必须有的字段
CREATE TABLE xxx (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
-- [业务字段]
create_by VARCHAR(32) NULL DEFAULT NULL COMMENT '创建人',
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_by VARCHAR(32) NULL DEFAULT NULL COMMENT '更新人',
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
del_flag TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0-正常 1-已删除',
INDEX idx_xxx_create_time (create_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='表说明';
强制要求:
create_by— 创建人,建议保留;系统自动填充时可为空create_time— 创建时间,必须有update_by— 更新人,建议保留;系统自动填充时可为空update_time— 更新时间,必须有(ON UPDATE CURRENT_TIMESTAMP自动更新)del_flag— 逻辑删除标记,除非明确不需要软删除- 每张表必须有
COMMENT - 引擎统一
InnoDB,字符集utf8mb4
索引规则
| 规则 | 说明 |
|---|---|
| 主键 | 每张表必须有,推荐自增 BIGINT |
| 外键 | 必须加索引(MySQL 自动加,但显式声明更清晰) |
| 查询条件 | WHERE 条件字段必须加索引 |
| 排序字段 | ORDER BY 字段考虑加索引 |
| 联合索引 | 遵循最左前缀原则,区分度高的在前 |
| 唯一约束 | 业务唯一字段必须加唯一索引 |
| 禁止 | ❌ 不加索引的 WHERE / JOIN / ORDER BY |
| 禁止 | ❌ 在大字段(TEXT/BLOB)上建索引 |
| 禁止 | ❌ 过多索引(单表建议 ≤ 5 个) |
索引命名
INDEX idx_表名_字段 -- 普通索引
UNIQUE uk_表名_字段 -- 唯一索引
INDEX idx_表名_字段1_字段2 -- 联合索引
字段约束规则
| 规则 | 示例 |
|---|---|
| 主键 | PRIMARY KEY 或 NOT NULL AUTO_INCREMENT |
| 非空 | 业务必填字段 NOT NULL |
| 默认值 | 有默认值的字段 DEFAULT xxx,禁止依赖代码设默认值 |
| 唯一 | 业务唯一字段 UNIQUE |
| 外键 | 尽量用逻辑外键(代码维护),不推荐物理外键(FOREIGN KEY) |
禁止清单
| ❌ 禁止 | 原因 |
|---|---|
| 表名/字段名用大写或驼峰 | 跨平台兼容 |
| 金额用 FLOAT/DOUBLE | 精度丢失 |
| 时间用 TIMESTAMP | 2038 年溢出 |
| 用物理外键 | 分库分表/数据迁移困难 |
| 不加注释 | 无人知道字段含义 |
| 字符串代替布尔 | 空间浪费,索引效率低 |
| 大表无索引 | 性能灾难 |
| 字段用 NULL 代替默认值 | 查询需额外处理 IS NULL |
| 在代码里设默认值 | 数据一致性依赖应用层 |
修改表规则
-- ✅ 正确:显式命名约束
ALTER TABLE task ADD COLUMN priority TINYINT NOT NULL DEFAULT 0 COMMENT '优先级:0-普通 1-紧急';
ALTER TABLE task ADD INDEX idx_task_priority (priority);
-- ❌ 禁止:不写 COMMENT
ALTER TABLE task ADD COLUMN priority TINYINT;
-- ❌ 禁止:不写默认值导致存量数据为 NULL
ALTER TABLE task ADD COLUMN priority TINYINT NOT NULL;
修改表必须:
- 新字段有
COMMENT - 非空字段有
DEFAULT - 考虑对存量数据的影响
- 附带回滚 SQL
检查表
每涉及建表/改表,逐项自检:
- 表名、字段名全小写+下划线
- 有
create_bycreate_timeupdate_byupdate_time - 软删除字段
del_flag(如需要) - 每张表有
COMMENT,每个字段有COMMENT - 金额用
DECIMAL,时间用DATETIME - 主键 + 外键 + WHERE 条件字段有索引
- 非空字段有
NOT NULL DEFAULT - 无物理外键
- 索引命名
idx_表名_字段/uk_表名_字段 - 附带回滚 SQL
- 引擎 InnoDB,字符集 utf8mb4