签入版本

This commit is contained in:
小蚂蚁云
2026-10-20 21:53:26 +08:00
parent 5cc3da657c
commit b33799aa63
427 changed files with 32547 additions and 1 deletions
@@ -0,0 +1,107 @@
# 3.2 数据库建表
:::tip 概述
建表是模块开发的第一步。本项目对表结构有强约束:统一审计列、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)
```
关键决策(与直觉不同的点):
::: warning 关键约束
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
```
::: tip 索引范围纪律
含 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 张 | 无租户过滤(超管可见全量) |
漏加清单的后果:租户级表不隔离,所有租户互相可见数据——务必同步。