3.2 数据库建表
概述
建表是模块开发的第一步。本项目对表结构有强约束:统一审计列、int 自增主键、del_flag 软删、uk_* 唯一索引、列注释枚举。这些规范不是建议——它们是全局钩子、字典系统、代码生成器正常工作的前提。
统一规范(25 张表齐备)
sql
-- 审计列(每张表必有)
id int NOT NULL AUTO_INCREMENT COMMENT '主键ID', -- 数据库自增(禁用雪花)
create_user varchar(50) DEFAULT '' COMMENT '创建人',
create_time datetime DEFAULT (now()) COMMENT '创建时间',
update_user varchar(50) DEFAULT '' COMMENT '更新人',
update_time datetime DEFAULT (now()) COMMENT '更新时间',
del_flag int DEFAULT 0 COMMENT '删除标志:0-正常 1-已删除',
-- 租户级表(9 张)另有:
tenant_id int DEFAULT 0 COMMENT '租户ID:0-平台级',
PRIMARY KEY (id)关键决策(与直觉不同的点):
关键约束
- 主键统一 int 数据库自增(2026-10-13 定稿):禁用雪花算法(
utility/id已删除);新增后用result.LastInsertId()回读;hooks 不填 id。 - 删除一律软删:deleteHook 把物理删除改写为
UPDATE del_flag=1,查询由dao.Ctx恒过滤del_flag=0。 - 无物理外键:全部逻辑外键(如 article.category_id),跨表一致性由业务层保证。
唯一索引(uk_*,13 个定稿)
唯一索引是并发唯一性的最终保证(UniqueFields 预检仅为 UX 层,存在 TOCTOU 竞态)。命名规范 uk_ 前缀:
sql
-- 示例:goframe_user 的三个唯一索引(均含 del_flag,软删行不占坑)
UNIQUE KEY uk_tenant_username (tenant_id, username, del_flag)
UNIQUE KEY uk_tenant_mobile (tenant_id, mobile, del_flag)
UNIQUE KEY uk_tenant_code (tenant_id, code, del_flag)
-- 全局唯一(平台级表)
UNIQUE KEY uk_code (code) -- config / dict / param / file_template / tenant
UNIQUE KEY uk_tenant_name (tenant_id, name, del_flag) -- dept / level / position / category索引范围纪律
含 tenant_id 的唯一索引,模块唯一预检(UniqueFields 的 Group:"tenant_id" 或手写检查按行现租户)范围必须等于索引范围,否则漏报 1062 或跨租户误报。
列注释枚举(字典与生成器的数据源)
注释写法 字段名:1-正常 2-禁用(-、—、=、= 均可作分隔符),生成器解析为前端选项并自动建字典(编码规范 {模块驼峰}_{字段驼峰}):
sql
status int DEFAULT 1 COMMENT '状态:1-正常 2-禁用',
-- 常见枚举定稿:
-- article.status 0-正常 1-下架
-- menu.type 0-菜单 1-权限节点
-- job.status 0-未发布 1-运行中 2-暂停
-- job.execute_policy 1-立即执行 2-执行一次 3-放弃执行
-- job.is_sync 1-同步 0-异步
-- role.data_scope 1-全部 2-本部门及以下 3-本部门 4-仅本人
-- login_log.log_type 1-登录 2-退出案例演示表(goframe_example)
sql
CREATE TABLE `goframe_example` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '案例名称',
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '案例图片',
`type` int NOT NULL DEFAULT 0 COMMENT '案例类型',
`status` int NOT NULL DEFAULT 1 COMMENT '状态:1-正常 2-禁用',
`sort` int NOT NULL DEFAULT 0 COMMENT '排序',
`create_user` varchar(50) NOT NULL DEFAULT '' COMMENT '创建人',
`create_time` datetime NULL DEFAULT (now()) COMMENT '创建时间',
`update_user` varchar(50) NOT NULL DEFAULT '' COMMENT '更新人',
`update_time` datetime NULL DEFAULT (now()) COMMENT '更新时间',
`del_flag` int NOT NULL DEFAULT 0 COMMENT '删除标志:0-正常 1-已删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='案例演示表';它演示了最小可用表形态:审计列齐备、status 注释枚举(生成器据此自动创建 example_status 字典)、avatar 图片字段(注释含"图片"触发生成器图片识别)。
建表/变更工作流
text
1) 以 document/mysql/ 定稿为基准补 ALTER
(含列注释枚举、uk_* 唯一索引;索引命名 uk_/idx_ 规范)
2) gf gen dao -c hack/config.yaml 刷新 dao/entity/do(service 手维护)
3) 同步 document/ 其余四方言脚本(人工校对)
4) 租户级表 → 修改 internal/model/hooks 的 tenantTables 清单
(生成器不自动维护此清单!)
5) go build ./... 重启;必要时 go run ./cmd/migrator 同步到其他环境库租户级表判定
新增表是否带 tenant_id 决定它是否需要加入 internal/model/hooks/hooks.go 的 tenantTables 清单:
| 类型 | 现有表 | 行为 |
|---|---|---|
| 租户级(9 张) | user/role/dept/level/position/article/category/notice/link | 自动过滤 tenant_id IN(0,自身)、插入自动盖章 |
| 平台级 | 其余 16 张 | 无租户过滤(超管可见全量) |
漏加清单的后果:租户级表不隔离,所有租户互相可见数据——务必同步。