Skip to content

数据库规范 ​

基本约定 ​

  • 不使用 AutoMigrate:表结构变更一律通过 sql/ 下的版本目录脚本交付,人工执行;
  • 所有表和字段必须有中文注释;
  • 字符集统一 utf8mb4,排序规则统一 utf8mb4_general_ci;
  • 数值枚举从 1 开始,0 仅表示「未设置/不过滤」,并在 internal/common/enums 与前端 src/enums 集中定义;
  • 软删除使用 deleted_at(GORM gorm.DeletedAt),查询默认排除已删除记录;
  • 表名:核心表 sys_* 前缀;插件业务表 plg_{插件ID}_* 前缀。

SQL 目录 ​

text
sql/
├── v0.0.1/   # 全量初始化脚本
├── v0.0.2/   # 插件基础设施、操作日志清理
├── v0.0.3/   # 会员用户表与菜单
└── plugins/  # 插件安装器归档的插件迁移

新版本脚本放在对应版本目录,脚本应可重复执行(CREATE TABLE IF NOT EXISTS、菜单按业务键判断等),并在对应版本的更新说明中描述执行方式。

索引与一致性 ​

  • 主键、唯一约束、查询条件与排序字段按访问方式建立索引;
  • 业务唯一性必须由唯一索引兜底,不能只依赖应用层先查后写;
  • 可空唯一字段(如会员登录账号)使用 NULL 表示未设置——MySQL 唯一索引允许多个 NULL;
  • 并发写入使用事务、条件更新或锁,禁止「先查再无条件写」;保存类接口优先 clause.OnConflict upsert;
  • 外键约束是否使用与现有项目保持一致,但关联 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_storage_config / sys_upload_file存储渠道与上传记录
sys_sms_config / sys_sms_signature / sys_sms_template / sys_sms_send_log短信配置与发送记录
sys_wechat_config / sys_payment_config / sys_platform_config渠道与平台配置
sys_plugin / sys_plugin_migration / sys_plugin_menu / sys_plugin_install_log插件基础设施