数据库规范
基本约定
- 不使用
AutoMigrate:表结构变更一律通过sql/下的版本目录脚本交付,通过校验后的安装或升级命令执行; - 所有表和字段必须有中文注释;
- 字符集统一
utf8mb4,排序规则统一utf8mb4_general_ci; - 数值枚举从
1开始,0仅表示「未设置/不过滤」,并在internal/common/enums与前端src/enums集中定义; - 软删除使用
deleted_at(GORMgorm.DeletedAt),查询默认排除已删除记录; - 表名:核心表
sys_*前缀;插件业务表plg_{插件ID}_*前缀。
SQL 目录
text
sql/
├── 0.0.1/
│ ├── full.sql # 空库安装
│ ├── incremental.sql # 相对上一版本的变化;首次基线为说明文件
│ └── release.json # 版本链与摘要
└── plugins/{plugin_id}/{version}/
├── full.sql
└── incremental.sql新版本必须同时提供全量和增量文件。全量只用于空库,不能重复导入已有系统;增量按版本记录执行,DDL 失败时先核对结构再恢复,不得盲目重跑。
索引与一致性
- 主键、唯一约束、查询条件与排序字段按访问方式建立索引;
- 业务唯一性必须由唯一索引兜底,不能只依赖应用层先查后写;
- 可空唯一字段(如会员登录账号)使用 NULL 表示未设置——MySQL 唯一索引允许多个 NULL;
- 并发写入使用事务、条件更新或锁,禁止「先查再无条件写」;保存类接口优先
clause.OnConflictupsert; - 短信渠道通过
is_default、生成列default_slot和唯一索引保证未删除配置至多一个默认渠道,管理端切换默认值时使用事务和行锁; - 外键约束是否使用与现有项目保持一致,但关联 ID 必须有索引。
字段类型
- 金额类字段使用
decimal(如sys_member.balance为decimal(12,2)),Go 模型与 Resp 用字符串承载,禁止 float/double; - 时间字段
datetime(3),对外输出格式化到秒(不展示毫秒); - 文件字段只保存相对路径,访问地址按当前存储配置动态补全;
- 密钥类字段(私钥、Secret)响应结构一律不返回。
表关系
- Model 只映射当前表字段,不定义关联对象;表关联关系在 Resp 中定义,优先使用 GORM
Preload批量加载,避免 N+1 查询; - 树形结构(菜单、部门、角色)由
pkg/tree.BuildTree生成{data, children}。
核心数据表
| 表 | 作用 |
|---|---|
sys_user | 管理员账号 |
sys_member | 会员(C 端用户)账号 |
sys_user_login | 登录流水 |
sys_role / sys_user_role / sys_role_menu | 角色与授权关系 |
sys_menu | 菜单、页面与按钮权限 |
sys_dept | 部门 |
sys_operation_log | 管理端操作日志 |
sys_scheduled_task / sys_scheduled_task_log | 定时任务配置与执行日志 |
sys_storage_config / sys_upload_file | 存储渠道与上传记录 |
sys_sms_config / sys_sms_signature / sys_sms_template / sys_sms_send_log | 短信配置与发送记录 |
sys_message / sys_message_template / sys_message_push_record / sys_message_subscription | 消息中心:站内消息、消息模板、小程序推送记录与订阅授权记录 |
sys_wechat_config / sys_payment_config / sys_platform_config | 渠道与平台配置 |
sys_payment_order / sys_payment_attempt / sys_payment_notify_log | 统一支付单、支付尝试和第三方回调日志 |
sys_plugin / sys_plugin_migration / sys_plugin_menu / sys_plugin_install_log | 插件基础设施 |
当前发布规则
当前统一基线为 0.0.1,每次发布必须同时提供全量、增量 SQL 和摘要;完整目录、安装升级与校验规则见数据库版本管理。早期功能脚本已归并进当前全量结构。