mysql如何实现注册邀请码功能_mysql项目设计示例

3次阅读

邀请码表须用char(16)存随机码,含code(唯一索引)、inviter_id、used_at、expires_at(默认7天)、created_at;校验注册需原子UPDATE,生成用6位base36去重防混淆,关系链应预计算存辅助表。

mysql如何实现注册邀请码功能_mysql项目设计示例

邀请码表设计必须带有效期和使用状态

直接用 CHAR(16) 存邀请码,别用自增ID当邀请码——容易被枚举。字段至少包含:code(唯一索引)、inviter_id(发码用户ID)、used_atNULL表示未用)、expires_at(DATETIME,建议默认 7 天后)、created_at。避免把邀请关系硬编码进用户表,否则后期查谁邀请了谁、统计邀请数会非常慢。

注册时校验邀请码要原子性更新

不能先 selectUPDATE,否则并发注册可能让同一码被多人成功使用。必须用单条语句完成校验+标记已用:

UPDATE invite_codes  SET used_at = NOW(), user_id = ?  WHERE code = ? AND used_at IS NULL AND expires_at > NOW();

执行后检查 ROW_COUNT() 是否为 1。返回 0 表示码无效(过期/已用/不存在),不是程序错误,而是业务规则拦截。

生成邀请码别用 UUID 或时间戳拼接

UUID 太长且可读性差;时间戳易预测。推荐用「随机字符串 + 校验位」组合:

  • RAND() 配合 CONV(FLOOR(RAND()*POW(36,6)),10,36) 生成 6 位 base36 字符串(约 20 亿种组合)
  • 插入前加 UNIQUE KEY(code) 约束,冲突则重试(一般 1–2 次就成功)
  • 避免字母 O 和数字 0I1 混淆,生成时过滤掉

邀请关系链不要靠递归查询实现

mysql 8.0 虽支持 CTE 递归,但深度稍大(比如邀请 5 层以上)就会慢甚至超时。实际项目中,如果需要统计“某用户带来的全部下线”,应该在注册时就写死一级关系,并用定时任务或触发器维护一个 user_ancestors 辅助表,存 user_id 和其所有上级 inviter_id 及层级。否则每次查都要 WITH RECURSIVE,线上扛不住。

text=ZqhQzanResources