注册时用户名不可重复设计方案
很多系统要求在注册的时候可以自己输入用户名,但是要求注册的时候的用户名是不可以重复的,要想实现这样的一个需求,其实是没有银弹的,是要根据你们系统的用户量来决定的。
1.如果对于政府项目这类数据量很小的系统来说
对于这类数据量很小的系统来说,一张表完全可以存放下所有的用户数据,而且直接去查询db也不会很慢,对于这种系统来说,那就可以直接查db了。
2.对于用户量稍微大一点的系统来说
对于这类系统来说,应该是符合大部分企业的情况的,数据量没有那么小,但是又没有大厂那么大,对于这类系统来说,其实可以将数据放在redis中或者是使用一下布隆过滤器,注册的时候就可以判断这个数据是否存在了,而且数据量不太大的情况下定期重构布隆过滤器的时间开销其实也是可以接受的。对于使用布隆过滤器这种场景,有概率会发生误判,所以布隆过滤器的使用也是需要配合db来进行兜底的。
3.对于大厂这种数据量非常大的系统来说
对于大厂这种数据量很大的系统来说,比如数据表里面已经有了1亿条用户数据了,这种级别的数据量肯定是需要进行水平分库、水平分表的。然后对于这类场景的设计来说,可以使用ES分片的策略存储用户名来进行。
在一个系统中,用户名的长度肯定是固定的,比如最大长度不能超过16个字符,最小长度不能少于1个字符,所以最多会有16^16个用户名,这个数据量是非常大的,完全能够满足使用。 每个用户名肯定有一个唯一的ASCII码值,所以我们可以针对ASCII的大小进行范围分片构造ES分片。然后我们在每个ES分片中存储已经注册的用户名,当我们用户在进行注册的时候,先根据ASCII值的大小就能够确定ES的分片,然后去ES中查询是否存在这个用户名,如果没有的话,说明没有被重复注册,如果有的话,说明已经被注册过了,则无法进行注册。而且ES中删除一个用户名是很快的,查询也是很快的。 另外针对并发注册同一个用户名的并发问题,推荐使用分布式锁来实现,因为说实话对于注册或者改名这个接口来说QPS其实是没有那么大的,使用分布式锁我认为是可以接受的。