随机数算是比较正统的方案,第二个方案看起来有点奇怪。
在低频场景下,很容易出现序列号几乎没有增长,从而导致数据在经过分库分表之后只落到某一张表里的情况。为了解决这种问题,可以考虑这么做,序列号部分不再是从0开始增长,而是从一个随机数开始增长。还有一个策略就是序列号从上一时刻的序列号开始增长,但是如果上一时刻序列号已经很大了,那么就可以退化为从0开始增长,这样比随机数更可控一点,而且性能也更好一点。
一般来说,这个问题只在利用ID进行哈希的分库分表里面有解决的意义。在利用ID进行分库分表的情况下,很显然某一段时间内产生的ID都会落到同一张表里。不过这也是我们的使用范围分库分表预期的行为,不需要解决
大多数时候,我们会面临一个问题,就是分库分表的键和主键并不是同一个。比如在C端的订单分库分表,我们可以采用买家ID来进行分库分表。但是一些业务场景,比如说查看订单详情,可能是根据主键或是订单SN来查找的。
那么可以考虑借鉴雪花算法的设计,将主键生成策略和分库分表键结合在一起,也就是在主键内部嵌入分库分表键。例如,我们可以这样设计订单ID的生成策略,假设分库分表使用的是买家ID的后四位。第一段依旧是采用时间戳,第二段换成了买家后四位,第三段采用随机数。
普遍情况下,我们都是用买家ID来查询对应的订单信息,在别的场景下,比如我们只有一个订单ID,这时候我们可以取出订单ID里嵌入进去的买家ID后四位,来判断数据存储哪个库、哪个表。类似的设计还有答题记录按照答题者ID来分库分表,但是答题记录ID本身可以嵌入这个答题者ID里用于分库分表的部分。
最后要记得升华一下这种设计思想
这一类解决方案,核心就是不拘泥于雪花算法每一段的含义。比如第二段可以使用具备业务含义的ID,第三段可以自增,也可以随机。只要我们能够保证ID生成是全局递增且独一无二的就可以。
为什么要这样升华呢?因为这段话里,我们很明显的埋下了两颗雷,一个是全局递增,一个是独一无二。也就是说这个亮点方案保证不了这两点,可能会被面试官追问这两个点。