面试题——分库分表之后,id 主键如何处理?

面试题

分表分库之后,ID主键该如何处理?

面试官心理分析

其实这也是分表分库之后,你必然会面对的一个问题,那就是这个id如何生成?因为要是分成多个表之后,每个表都是从1开始累加,那肯定是不对的,需要一个全局唯一的id来支持。所以这就是生产环境中所必须要考虑的问题。

面试题剖析

基于数据库的实现方案

数据库自增id

这个就是说你的系统里,每次得到一个id,都是通过往数据库里面写入一条没有什么意义的插入操作,得到一个id,拿到这个id之后,再往分表分库的数据库中写入。

这个方案的缺点就是,id由于是单库生成的,无法支撑高并发。

UUID

好处就是UUID是由本地生成的,不需要经过数据库生成,不会拥有高并发瓶颈。坏处就是UUID太长了,占用空间太大,作为主键来说,性能比较差。更重要的是,UUID不会有有序性,会导致B+树在写索引的时候,会有过多的随机写操作(连续的ID可以产生部分顺序写),还有由于在写的时候不能产生顺序的append操作,而需要进行insert操作,将会读取整个B+树节点到内存,在插入这条记录后会将整个节点写回到磁盘,这种操作记录占用空间比较大的情况瞎,性能下降明显。

获取系统当前时间

这个就是以时间戳为主的id生成方式,单问题是,在并发的时候,时间戳可能会一样。这个时候就需要根据业务增加这个id的其他属性,使其可以成为全局唯一的id。

snowflake算法

snowflake是twitter开源的分布式id生成算法,采用scala编写,是把一个64位的long型id,1个bit是不用的,用其中的41bit作为毫秒数,用10bit作为机器id,12bit作为序列号。

  • 1 bit:不用,因为在二进制里面第一bit如果是1,那么都是负数,我们生成的id都是正数,所以第一位就不需要了。
  • 41 bit:表示的是时间戳,单位是毫秒。41 bit可以表示的数字多达2^41 - 1,也就是可以表示2^41-1个毫秒值,换算成年就是69年的时间。
  • 10 bit:记录工作机器id,代表的是这台机器在2^10台机器上放在哪里,也就是1024台机器。但是在10 bit中有5 bit代表了机房id,5个bit代表了机器id。所以意思就是最多有2^5 = 32个机房,每个机房里有2^5 = 32台机器。
  • 12 bit:这个是用来记录同一个毫秒内产生的不同id,12 bit可以代表的最大整数是 2^12 = 4096,也就是说这12bit代表了同一毫秒内,产生的4096个id。

这个大概的意思就是,41 bit相当于当前毫秒的时间戳,然后5 bit就是你传递进来的一个机房 id,另外5 bit就是机器id,剩下的12 bit,就是如果这个id跟上次的id在同一毫秒内产生的,就会顺序累加。

发布了17 篇原创文章 · 获赞 0 · 访问量 319

猜你喜欢

转载自blog.csdn.net/qq_26375325/article/details/105294796