Files
easygoadmin-wiki/EasyGoAdmin_GoFrame_EleVue/zh/architecture/database-design.md
T
2026-10-20 21:19:44 +08:00

132 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 4.9 数据库设计
:::tip 概述
25 张业务表、统一审计列、13 个唯一索引、9 张租户级表、注释枚举驱动字典——本节给出数据模型全景与 ER 关系。五方言定稿脚本位于 document/{mysql,postgresql,sqlserver,oracle,sqlite}/,MySQL 版为规范基准。
:::
## ER 关系图(逻辑外键,无物理外键约束)
```text
goframe_tenant ──< goframe_user >──┬──< goframe_user_role >── goframe_role
│ │
│ goframe_role_menu
│ │
├──< goframe_dept ▼
├──< goframe_level goframe_menu
├──< goframe_position ▲
│ (user.level_id/position_id/dept_id 引用)
│
goframe_config ──< goframe_config_item
goframe_dict ──< goframe_dict_item
goframe_category(树 parent_id) ──< goframe_article(tenant_id, category_id)
article: cover 单图 / images 多图 / content 富文本
goframe_notice / goframe_link(tenant_id)
goframe_city(树 pid + parent_code,全国行政区划,无租户)
goframe_job ──< goframe_job_log(job_id, job_name 冗余)
goframe_operation_log / goframe_login_log(独立日志表,无租户)
goframe_file_template(全局文件模板,code 唯一)
goframe_param(全局系统参数,code 唯一)
goframe_example(案例演示表,导入导出/状态演示用)
">" 侧为多端;如 user >-- user_role --< role 为多对多。
```
## 全表统一规范
```text
表前缀 goframe_;存储引擎 InnoDB;字符集 utf8mb4。
每张表统一审计列(25 表齐备):
id int NOT NULL AUTO_INCREMENT 主键(数据库自增,禁用雪花)
create_user varchar(50) 创建人(ctx 用户名)
create_time datetime DEFAULT (now()) 创建时间
update_user varchar(50) 更新人
update_time datetime DEFAULT (now()) 更新时间
del_flag int DEFAULT 0 0-正常 1-已删除(软删)
租户级表另有 tenant_id int DEFAULT 0(0=平台级),共 9 张。
删除一律软删(deleteHook 改写);查询一律经 dao.Ctx 过滤 del_flag=0。
```
## 25 张表清单
| 表名 | 中文注释 | 域 | 租户级 | 特征列/说明 |
|------|---------|-----|--------|------------|
| goframe_article | 文章表 | content | 是 | category_id/cover/images(多图)/content(富文本)/status/click/sort |
| goframe_category | 文章分类表 | content | 是 | 树形 parent_id、category_name/code/sort |
| goframe_city | 城市行政区划表 | data | 否 | 树形 pid+parent_code、city_code/area_code/level、lng/lat/pinyin(大数据量表) |
| goframe_config | 系统配置表 | data | 否 | name/code/sort |
| goframe_config_item | 配置项表 | data | 否 | config_id/value/options/type/status/sort |
| goframe_dept | 部门表 | system | 是 | 树形、删除有子级/用户守卫 |
| goframe_dict | 数据字典表 | data | 否 | name/code;缓存 dict:item:{code} |
| goframe_dict_item | 字典项表 | data | 否 | dict_id/name/value/sort |
| goframe_example | 案例演示表 | tool | 否 | 七件套+导入导出+状态演示 |
| goframe_file_template | 文件模板表 | tool | 否 | code 唯一;getTemplateByCode |
| goframe_job | 定时任务表 | monitor | 否 | job_name/cron_expression/execute_policy/is_sync/url/params/status(0未发布/1运行/2暂停) |
| goframe_job_log | 定时任务日志表 | monitor | 否 | job_id/status/耗时/exception_info |
| goframe_level | 职级表 | system | 是 | 导入导出启用;user_count 展示 |
| goframe_link | 友链表 | content | 是 | 无 status 列 |
| goframe_login_log | 登录日志表 | monitor | 否 | log_type(1登录/2退出)/ip/location/os/browser/status |
| goframe_menu | 菜单表 | system | 否 | 树形;type(0菜单/1权限节点)/permission/status/hide/sort |
| goframe_notice | 通知公告表 | data | 是 | status |
| goframe_operation_log | 操作日志表 | monitor | 否 | title/type(log_type枚举)/param/result/ip/location/consume_time/status/error |
| goframe_param | 系统参数表 | data | 否 | code 唯一 |
| goframe_position | 岗位表 | system | 是 | |
| goframe_role | 角色表 | system | 是 | code/data_scope(四档行级数据权限) |
| goframe_role_menu | 角色菜单关联表 | system | 否 | role_id+menu_id(无模块文件,归 role logic) |
| goframe_tenant | 租户表 | system | 否 | code(T+ID)/status/expire_time/max_user_num |
| goframe_user | 用户表 | system | 是 | username/password(bcrypt)/salt/mobile/email/avatar/dept_id/level_id/position_id/status/code |
| goframe_user_role | 用户角色关联表 | system | 否 | user_id+role_id(无模块文件,归 user logic) |
## 唯一索引清单(13 个)
| 表 | 索引名 | 列 | 语义 |
|----|--------|-----|------|
| goframe_category | uk_tenant_name | (tenant_id, category_name, del_flag) | 租户内分类名唯一 |
| goframe_config | uk_code | (code) | 全局配置编码唯一 |
| goframe_dept | uk_tenant_name | (tenant_id, name, del_flag) | 租户内部门名唯一 |
| goframe_dict | uk_code | (code) | 全局字典编码唯一 |
| goframe_file_template | uk_code | (code) | 全局模板编码唯一 |
| goframe_level | uk_tenant_name | (tenant_id, name, del_flag) | 租户内职级名唯一 |
| goframe_param | uk_code | (code) | 全局参数编码唯一 |
| goframe_position | uk_tenant_name | (tenant_id, name, del_flag) | 租户内岗位名唯一 |
| goframe_role | uk_tenant_code | (tenant_id, code, del_flag) | 租户内角色编码唯一 |
| goframe_tenant | uk_code | (code) | 租户编码全局唯一 |
| goframe_user | uk_tenant_username | (tenant_id, username, del_flag) | 租户内用户名唯一 |
| goframe_user | uk_tenant_mobile | (tenant_id, mobile, del_flag) | 租户内手机号唯一 |
| goframe_user | uk_tenant_code | (tenant_id, code, del_flag) | 租户内用户编码唯一 |
要点:索引含 del_flag(软删行不占坑,与 dao.Ctx 恒过滤语义一致);含 tenant_id 的索引,模块唯一预检范围必须等于索引范围。
## 枚举列约定(列注释驱动字典与生成器)
```text
status(账号/租户/字典项等) 1-正常 2-禁用
article.status 0-正常 1-下架
city.level 0-省份 1-城市 2-县区 3-街道 4-社区
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-仅本人
del_flag 0-正常 1-已删除
login_log.log_type 1-登录 2-退出
operation_log.type 见 consts/log_type.go(41 个值,静态映射不走字典)
```
## 大表与性能注意
+ **goframe_city** 全国行政区划大表(AUTO_INCREMENT 已至 78 万+):查询走 parent_code/pid 索引路径(级联懒加载 getCityList),避免全表 List;导入/迁移注意批大小。
+ **日志三表**(operation_log/login_log/job_log)只增不改,依赖 LogClean 任务按 `job.logRetentionDays`(默认 90 天)分批物理清理。
+ **导出接口**统一 ChunkQuery 分批(500/页)防 OOM。
## 建表/变更工作流
```text
1) 以 document/mysql/ 定稿为基准补 ALTER(含列注释枚举、uk_* 唯一索引、uk_/idx_ 命名规范)
2) gf gen dao -c hack/config.yaml 刷新 dao/entity/do(service 手维护)
3) 同步 document/ 其余四方言脚本(人工校对)
4) 租户级表 → 修改 hooks.tenantTables
5) go build ./... 重启;必要时 go run ./cmd/migrator 同步到其他环境库
```