Files
zt-closet-backend/.codebuddy/plans/数据库唯一索引全面补齐_0a7c6d59.md
2026-09-11 01:41:52 +08:00

5.8 KiB
Raw Permalink Blame History

name, overview, todos
name overview todos
数据库唯一索引全面补齐 全面盘点代码中依赖数据库唯一索引做幂等/防重、但模型未声明 tag 的表,补全 GORM 模型 tag,并生成一份幂等的建索引 SQL 脚本供用户自行在开发库执行。
id content status
add-model-unique-index-tags 为 vipflowlog、benefit_grant_task、refundflowlog、collect、like、order、quota(UserDailyUsage)、horoscope 八个模型补 uniqueIndex tag completed
id content status dependencies
create-sql-script 新建 sql/unique_indexes.sql:9 条唯一索引 DDL、幂等检查语句、执行说明与重复数据清理提示 completed
add-model-unique-index-tags
id content status dependencies
build-verify 执行 go build、go vet 与 lint 检查,核对脚本索引与模型 tag 一一对应 completed
create-sql-script

产品概述

针对上一轮「配额流水事务一致性修复」遗留的数据库唯一索引落地问题,为开发环境提供一套完整的数据库唯一索引补齐方案。用户处于开发阶段、无历史业务数据,选择由本人后续自行在开发库执行 SQL,本次交付:补全所有依赖唯一索引做幂等/防重的模型声明,并生成可直接执行的幂等 SQL 脚本。

核心功能

  • 补全模型唯一索引声明:为 8 个依赖唯一索引但未声明 gorm tag 的模型补充 uniqueIndex 声明(自文档化,不影响当前运行)。
  • 生成唯一索引 SQL 脚本:新建 sql/unique_indexes.sql,覆盖 9 个表的唯一索引 DDL,每条附用途说明与依赖代码位置。
  • 提供幂等执行与清理指引:脚本头部提供索引存在性检查语句与重复执行说明,尾部提供开发环境重复测试数据的清理提示。
  • 构建验证:确保 tag 改动无编译、静态检查错误。

索引清单

表 唯一索引(建议名) 依赖场景
quota_flow_logs uk_quota_flow_idem (order_no, quota_type, change_type) 配额发放/回收幂等(tag 已补,仅需 SQL)
vip_flow_logs uk_vip_flow_idem (order_no, change_type) VIP 发放/回收幂等
benefit_grant_tasks uk_benefit_task_idem (order_no, benefit_type) 权益发放补偿任务幂等凭证
refund_flow_logs uk_refund_flow_no (refund_no) 退款申请防重
collects uk_collect_user_target (collect_type, target_id, user_id) 收藏/取消收藏 upsert
likes uk_like_user_target (like_type, target_id, user_id) 点赞/取消点赞 upsert
orders uk_order_no (order_no) 商户订单号唯一
user_daily_usages uk_daily_usage_user_date (user_id, stat_date) 每日计数行唯一,防并发重复行
horoscopes uk_horoscope_date_zodiac (stat_date, zodiac) 每日星座运势防重复生成

技术栈

  • 语言:Go
  • ORM:GORM(uniqueIndex tag 声明,priority 控制联合索引列顺序)
  • 数据库:MySQL 8.0(ALTER TABLE ... ADD UNIQUE INDEX)
  • 脚本形式:纯 SQL 文件,人工执行

实现方案

总体策略

项目无迁移机制(无 AutoMigrate、无 .sql 文件、表结构外部管理),用户已明确选择「自己执行 SQL」,因此本次改动仅两处:模型 tag 补全 + 新增 SQL 脚本。不引入 AutoMigrate、不改服务启动行为。tag 声明仅作代码自文档化,为未来可能启用的自动迁移预留基础。

模型 tag 补全(8 个文件)

  1. internal/mysqlmodel/vipflowlog.go:OrderNo + ChangeType 联合索引 uk_vip_flow_idem(priority 1/2)。
  2. internal/mysqlmodel/benefit_grant_task.go:OrderNo + BenefitType 联合索引 uk_benefit_task_idem(priority 1/2)。
  3. internal/mysqlmodel/refundflowlog.go:RefundNo 单列唯一索引 uk_refund_flow_no。
  4. internal/mysqlmodel/collect.go:CollectType + TargetID + UserID 联合索引 uk_collect_user_target(priority 1/2/3)。
  5. internal/mysqlmodel/like.go:LikeType + TargetID + UserID 联合索引 uk_like_user_target(priority 1/2/3)。
  6. internal/mysqlmodel/order.go:OrderNo 单列唯一索引 uk_order_no。
  7. internal/mysqlmodel/quota.go(UserDailyUsage):UserID + StatDate 联合索引 uk_daily_usage_user_date(priority 1/2)。
  8. internal/mysqlmodel/horoscope.go:StatDate + Zodiac 联合索引 uk_horoscope_date_zodiac(priority 1/2)。

tag 格式遵循现有项目约定(如 quotaflowlog.go、quota.go 已声明的 uniqueIndex:名称,priority:N 风格),保持注释说明索引用途。

SQL 脚本设计(新建 sql/unique_indexes.sql)

  • 头部:执行说明(目标库、开发环境定位、执行方式 mysql -u... -p... < sql/unique_indexes.sql);MySQL 8.0 不支持 CREATE INDEX IF NOT EXISTS,提供基于 information_schema.statistics 的索引存在性检查模板查询。
  • 主体:9 条 ALTER TABLE xxx ADD UNIQUE INDEX xxx (...),按上表顺序排列,每条以注释块说明用途、依赖代码位置、重复执行时预期行为(已存在会报 Duplicate key name,可忽略或先删后建)。
  • 尾部:开发阶段如有重复测试数据需先清理的提示,并给出关键表的查重 SQL 示例(如 SELECT order_no, COUNT(*) FROM quota_flow_logs GROUP BY order_no, quota_type, change_type HAVING COUNT(*) > 1; 模板)。
  • 不包含:任何 DROP TABLE、TRUNCATE、删除数据的自动执行语句;清理数据仅以注释形式提示,由用户手动确认执行。

验证

  • go build ./...、go vet ./...、read_lints 检查 tag 改动相关文件,确保无新增错误(tag 为纯字符串注释性元数据,预期零编译影响)。
  • 人工核对脚本中 9 个索引与模型中 tag 声明一一对应,列顺序与 priority 一致。