Skip to content

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)

关键决策(与直觉不同的点):

关键约束

  1. 主键统一 int 数据库自增(2026-10-13 定稿):禁用雪花算法(utility/id 已删除);新增后用 result.LastInsertId() 回读;hooks 不填 id。
  2. 删除一律软删:deleteHook 把物理删除改写为 UPDATE del_flag=1,查询由 dao.Ctx 恒过滤 del_flag=0。
  3. 无物理外键:全部逻辑外键(如 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 张无租户过滤(超管可见全量)

漏加清单的后果:租户级表不隔离,所有租户互相可见数据——务必同步。

小蚂蚁云团队 · 提供技术支持