数据库唯一id生成策略

分布式,高并发下id生成要求

全局唯一
趋势递增
效率高(生成.使用.索引)
控制并发

一 . Uuid(uuid/guid[通用唯一识别码])

Uuid是按照开放软件基金会(osf)制定的标准计算
用到了以太网开地址(MAC),纳米级时间,芯片id码和许多可能的数字

由一下几部分的组成

当前日期和时间
时钟序列
全局唯一的ieee机器识别号(如果有网卡,从网卡获取,没有网卡以其他方式获取) 
生成长度为36的字符串

优缺点:

优点:
	使用简单
	不依赖其他组件
	不影响数据库拓展

缺点:
	数据库索引效率低
	太过于无意义.用户不友好
	长度36的字符串,空间占用大
	应用集群环境,机器多的时候,重复几率大

二 . Mysql整型自增

Mysql 整型自增索引之所以快是因为mysql 采用b+树对整型进行了加速
Mysql使用auto_increment, oracle使用sequence序列
集群环境下,不同的库,设置不同的初始值,每次自增加 100
Mysql下修改起点和步长的方式
     设置起点
     	Set @@auto_increment_offset=1   // 设置起点为1
     设置步长
     	Set@@auto_increment_increment=100  // 设置步长为100
     查看参数
     	show VARIABLES like 'auto_%'  // 查看参数

以上主要用于分表的时候

数据库唯一id生成策略_第1张图片

优缺点:

优点:
    无需编码
    性能也过得去
	索引友好

缺点:
   	大表不能做水平分表,否则插入删除易出现问题(已经存在很大数据的时候再分表,容易出现问题)
   	依赖前期规划,拓展麻烦
   	依赖mysql内部维护自增锁,高并发下插入数据影响性能
   	在业务操作父,子(关联表)插入时,要先父表 后子表

相对于uuid 其实 数据库自增表的效率稍低

特点是 : 互斥 排他 可重入

三 . 雪花算法(twitter 的 snowflake算法)

Snowfake算法是twitter’开源的分布式id生成算法,结果就是long长整型的id

数据库唯一id生成策略_第2张图片

Twitter 的雪花算法 产生的是一个 64位的长整型
	第一位未使用,固定为0
   	接下来41位为毫秒级时间,41位的长度可以使用69年
  	然后是10位节点id,最多支持部署1024个节点,(一般是数据中心编号和机器编号组成)
  	最后12位是毫秒内单位的算法调用计数,(意味着每个节点每毫秒产生4096个id序号)
   	上面4部分加起来是64比特位 = 8 字节 =Long(转换成字符串后长度最多为19)

优缺点:

优点:
	性能较优,速度快
	无需第三方依赖,实现也简单
	可以根据实际情况调整和拓展算法,方便灵活  (开源)
缺点:
	依赖时间机器,如果发生回拨会导致生成id重复,业界使用一般是根据雪花算法进行拓展的(可以把这个服务单独做成一个服务用于生成id,但是会连累生成效率)

四 . Redis

Java 中 基本类型所占的字节
Oracle 产生序列号的方式

思路:

利用增长计数api,业务系统在自增长的基础上,配合其他信息组成一个唯一id
Redis的incr(key) api用于将key的值进行递增,并返回增长数值
如果key不存在,则创建并赋值为0

利用redis的特性: 单线程原子操作,自增计数api,数据有效机制ex

实例:

业务编码+地区+自增数值

key的命名规范:

系统名:+ 模块:+ 功能: + key  例如: 163:study:order:id

优缺点:

优点:
	拓展性强,可以方便的结合业务进行处理
	利用redis操作原子性的特征,可以保证在并发的时候不会重复

缺点:
	引入redis就意味着引入其他三方依赖
	增加一侧网络开销
	需要对reids服务实现高可用

高可用:

自动分片
哨兵模式

注意: 集群并不能做高可用,因为redis集群中没有选举机制,所以需要采用哨兵(选举的机制)的机制配置高可用

各方案对比:

方式 优点 缺点
Uuid 实现简单,不占带宽 无序,占空间,可读性差,索引不友好
数据库自增 无代码调整,递增 db单点故障,扩展性瓶颈
雪花算法 性能优,不占带宽,趋势递增 依赖服务器时间
基于redis自研 无单点故障(高可用后),性能优于db,低于uuid和雪花算法,递增,扩展性强 占用带宽,redis集群维护

遵循 cap base 理论

数据库唯一id生成策略_第3张图片
数据库唯一id生成策略_第4张图片

五 . 总结

Id的无序:

Id已经给你了 ,现在只要找到一种方式打乱,然后打乱后又可以复原,就ok 了

你可能感兴趣的:(数据库)