bindbox-game/migrations/20251218_add_draw_logs_unique_index.sql
邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

43 lines
2.1 KiB
SQL
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.

-- 迁移脚本:为 activity_draw_logs 表添加唯一索引,防止重复开奖
-- 创建时间2025-12-18
-- 问题描述:定时抽奖时可能因为竞态条件导致一个订单发放多个奖品
-- 解决方案:
-- 1. 代码层面:先创建开奖日志,成功后再发放奖励(已完成)
-- 2. 数据库层面:添加唯一索引作为最后一道防线
-- 步骤1检查是否存在重复数据
SELECT order_id, COUNT(*) as cnt
FROM activity_draw_logs
GROUP BY order_id, issue_id
HAVING cnt > 1;
-- 步骤2如果有重复数据先清理重复数据保留最早的一条
-- 注意:执行前请先备份数据
-- DELETE a FROM activity_draw_logs a
-- INNER JOIN (
-- SELECT order_id, issue_id, MIN(id) as min_id
-- FROM activity_draw_logs
-- GROUP BY order_id, issue_id
-- HAVING COUNT(*) > 1
-- ) b ON a.order_id = b.order_id AND a.issue_id = b.issue_id AND a.id != b.min_id;
-- 步骤3添加唯一索引order_id + issue_id + reward_id 组合唯一)
-- 注意:对于一番赏,一个订单可能有多个格位,所以不能仅用 order_id 作为唯一键
-- 对于默认玩法一个订单也可能有多次抽奖count > 1
-- 因此这里添加的是复合唯一索引order_id + reward_id + created_at精确到秒
-- 或者使用 order_id + 序号 的方式
-- 方案A对于一番赏每个订单的每个格位只发一次奖
-- 方案B根据业务逻辑可以考虑在代码层添加 slot_index 信息
-- 推荐方案:为确保安全,暂不添加唯一索引,因为:
-- 1. 代码已修复为"先记录日志,再发奖"的模式
-- 2. 不同的玩法(一番赏、默认玩法)有不同的唯一性约束需求
-- 3. 添加索引可能导致历史数据迁移问题
-- 如果确认需要添加索引,可以执行:
-- ALTER TABLE activity_draw_logs ADD INDEX idx_order_issue (order_id, issue_id);
-- 或者添加更严格的唯一索引(需要先清理重复数据):
-- ALTER TABLE activity_draw_logs ADD UNIQUE INDEX uk_order_issue_reward (order_id, issue_id, reward_id);