ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分库分表之后,id唯一主键如何生成

2021-12-04 21:03:03  阅读:117  来源: 互联网

标签:10 分库 单库 id bit 主键


一、前言

当单库无法满足业务需求时,分库分表就是一种要做的优化手段了,然而将原本属于一个库中的数据拆分成多份后,如果让每个表的主键依旧从1开始递增,这很明显是不满足全局唯一id的需要。那这个时候我们要使用哪种方式来保证我们的是全局唯一呢,接下来花哥分享几种常见的做法,可以根据具体业务场景进行选择。

二、正文

  • 数据库自增id

此方式思路很简单,每次我们需要拿到id时,我们就向同一个库的某个表插入数据,此时我们会得到一个自增id,取到这个id之后再往对应的分库分表里去写入。同样该方式缺点也很明显,通过单库生成唯一id,不适用高并发的业务场景;

如果想要改进该方式,那么就专门开一个服务出来,这个服务每次就拿到当前id最大值,然后自己递增几个id,一次性返回批量id,然后再把当前最大id值修改成递增几个id之后的一个值;

适用场景:你分库分表就俩原因,要不就是单库并发太高,要不就是单库数据量太大;除非是你并发不高,但是数据量太大导致的分库分表扩容,你可以用这个方案,因为可能每秒最高并发最多就几百,那么就走单独的一个库和表生成自增主键即可。

缺点: 并发很低,几百/s

  • UUID

这是我们常用的手段之一,通过本地生成,不依赖数据库,但是由于uuid太长,作为主键性能太差,不适合用于主键。

适合的场景:如果你是要随机生成文件名,编号之类的

UUID.randomUUID().toString().replace("-", "")
复制代码
  • snowflake算法

此方式是twitter开源的分布式id生成算法,整体思路就是把一个64位的long型的id,先看一下生成的结果:

0 | 0000011 11011101 0011000 10000110 11111001 01 | 10101 | 100000 | 0000 00000000
复制代码

该结果可分为四个部分:

  • 1 bit:在二进制中,第一个bit如果是1,则表示负数,则是正数,因此该算法中第一个bit始终为0
  • 41 bit:表示的是时间戳,单位是毫秒。41 bit可以表示的数字多达2^41 - 1,也就是可以标识2 ^ 41 - 1个毫秒值,换算成年就是表示69年的时间。
  • 10 it:记录工作机器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 - 1 = 4096,也就是说可以用这个12bit代表的数字来区分同一个毫秒内的4096个不同的id

举一个具体例子:

  • 3021-10-22 06:08:07-> 做了一些计算,再换算成一个二进制,41bit来放 -> 0000011 11011101 0011000 10000110 11111001 01
  • 机房编号,21 -> 换算成一个二进制 -> 10101
  • 机器编号,32 -> 换算成一个二进制 -> 100000

标签:10,分库,单库,id,bit,主键
来源: https://blog.csdn.net/m0_64355285/article/details/121718198

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有