最近做项目需要使用到用户的邀请码,但是自己平时只是使用过,并未亲自设计过,不懂其中的细节问题, 这次趁着项目并未开始之际,写一点东西,理一理设计过程。

需求其实大家都知道,系统本身并不开放注册功能,只有通过用户邀请的方式才能注册进系统,这种方式的 优点有点类似“饥饿营销”,开放少量用户体验,然后通过这种方式吸收大部分可靠的会员。

从需求上面,我们可以简单提炼出邀请码实际是联系人与人之间的关系,存储方面我们主要考虑邀请码和用户的 对应关系。直观上面来说,一个用户应该可以邀请多个亲朋好友加入,那么一个注册用户应该对应多个邀请码,为了 业务发展,所以邀请码应该是没有生成上限的。

通过邀请码,我们需要满足一下需求:

  • 通过邀请码可以追查到生成人
  • 生成人为0的是默认的
  • 通过邀请码,当前会员可以查询到他的邀请人是谁
  • 通过邀请码,可以查到当前会员邀请了那些人

关系ER图

先理一理现有的实体关系: code and user er

现有注册会员和邀请码之间存在一对多的关系,那么邀请码这个表可以外键参考会员一表,这样做的好处的可以通过 会员信息快速找到他所生成的邀请码。

我们首先从邀请码这个实体开始考虑问题,邀请码外键参考会员一表的话,那么通过外键可以快速查到一个会员的所有生成的邀请码,再通过是否使用的flag可以快速确定当前会员生成了多少个邀请码,其中有多少个有效的会员

那么邀请码至少包含以下设计字段:

column type description
id int primary key 自增index
code vchar(16) 邀请码
is_default bool 是否是原始邀请码
is_uesed bool 是否已经注册
customer_ref foreign key 外键参考会员

通过上述表我们可以解决原始生成的邀请码的情况,这种邀请码is_defaulttrue,默认情况下拥有这种邀请码 的会员没有父级邀请码,也就是没法追踪到谁邀请了他,但是这种就是原始开放的邀请码。

然后我们再看看会员数据表的设计字段:

column type description
id int primary key 自增index
customer_id vchar(64) 客户ID
customer_name vcahr(256) 用户名
customer_phone vchar(11) 联系电话
area_id int 用户所属地区信息
register_code vchar(16) 用户注册邀请码

通过该表可以查看到该用户注册候使用的邀请码,可以查到邀请人是谁。

邀请码的设计

邀请码是由数字的字母组成的,可能是大小写混用,所以一共有62(26 * 2 * 10)个选择,我们在生成邀请码的时候,需要注意邀请码不能碰撞,并且邀请码要尽可能短,这样更加便于记忆和传播,为用户注册提供便利。

从邀请码的使用上面来说,看到过很长的,这种邀请码一般多见于论坛,社区,也有比较短的邀请码,像6位,8位的,这种邀请码其实更加友好,用户看了不太会着急,不过一般这种东西,也没得用户会盯着一直看,我们看看如何生成合适的 邀请码。


import time
import random

choice = [i for i in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]

random.seed(int(time.time()))

code = random.sample(choice, 6)

random.shuffle(code)

final = "".join(code)

print final

上面这段代码只是一个简单的示例,并不能满足高并发情况下产生重复的情况,主要的问题是由于高并发情况下, 随机数的种子其实是相同的,那么很难实现每次的种子都不一致,有兴趣的可以继续看一看,但是正常情况下,该实现 是可以满足需求的。

为了保证数据库的唯一性,可以每次生成的时候,都事先向数据库查询一下,当前数据库是不是有这个邀请码,确认没有 后就提交给用户,但是这样的话,效率会降低,所以还是尽量减少重复的情况,极少量的重复是可以接受的。