主键生成策略

  系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,下面介绍一些常见的ID生成策略。

  • Sequence ID
  • UUID
  • GUID
  • COMB
  • Snowflake

  最开始的自增ID为了实现分库分别的需求,会在自增的前提下,使用不同步长(例如DB1 生成1,4,7,10,DB2生成2,5,8,11,DB3生成3,6,9,12),但需要做数据库拓展时,极其麻烦。
  相比自增ID,UUID生成唯一主键更加方便(数据量非常大的情况下,存在重复的可能),但由于UUID的无序性,性能不如自增ID,字符串储存,储存空间大,查询效率低。
  COMB相对于UUID,增加了生成ID的有序性,插入与查询效率都有所提高。见Integer GUID和Comb做主键的效率测试(Delphi+access)(三)
  Sonwflake是Twitter主键生成策略,可以看做是COMB的一种改进,用64位的长整型代替128位的字符串。ID构成:第一位0 + 41位的时间前缀 + 10位的节点标识 + 12位的sequence避免并发的数字。见Twitter-Snowflake(64位分布式ID算法)分析与JAVA实现

1. Sequence ID

数据库自增长序列或字段,最常见的方式。由数据库维护,数据库唯一。

优点:

  1. 简单,代码方便,性能可以接受。
  2. 数字ID天然排序,对分页或者需要排序的结果很有帮助。

缺点:

  1. 不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候需要处理。
  2. 在单个数据库或读写分离或一主多从的情况下,只有一个主库可以生成。有单点故障的风险。
  3. 在性能达不到要求的情况下,比较难于扩展。
  4. 如果遇见多个系统需要合并或者涉及到数据迁移会相当痛苦。
  5. 分表分库的时候会有麻烦。

优化方案:

  1. 针对主库单点,如果有多个Master库,则每个Master库设置的起始数字不一样,步长一样,可以是Master的个数。
    比如:Master1 生成的是 1,4,7,10,Master2生成的是2,5,8,11 Master3生成的是 3,6,9,12。这样就可以有效生成集群中的唯一ID,也可以大大降低ID生成数据库操作的负载。

2. UUID

常见的方式,128位。可以利用数据库也可以利用程序生成,一般来说全球唯一。

优点:

  1. 简单,代码方便。
  2. 全球唯一,在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。

缺点:

  1. 没有排序,无法保证趋势递增。
  2. UUID往往是使用字符串存储,查询的效率比较低。
  3. 存储空间比较大,如果是海量数据库,就需要考虑存储量的问题。
  4. 传输数据量大
  5. 不可读。

优化方案:

  1. 为了解决UUID不可读,可以使用UUID to Int64的方法。

3. GUID

GUID:是微软对UUID这个标准的实现。UUID还有其它各种实现,不止GUID一种。优缺点同UUID。

4. COMB

  COMB(combine)型是数据库特有的一种设计思想,可以理解为一种改进的GUID,它通过组合GUID和系统时间,以使其在索引和检索事有更优的性能。
  数据库中没有COMB类型,它是Jimmy Nilsson在他的“The Cost of GUIDs as Primary Keys”一文中设计出来的。
  COMB数据类型的基本设计思路是这样的:既然UniqueIdentifier数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么我们能不能通过组合的方式,保留UniqueIdentifier的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与UniqueIdentifier组合起来,在保留UniqueIdentifier的唯一性的同时增加了有序性,以此来提高索引效率。

优点:

  1. 解决UUID无序的问题,在其主键生成方式中提供了Comb算法(combined guid/timestamp)。保留GUID的10个字节,用另6个字节表示GUID生成的时间(DateTime)。
  2. 性能优于UUID。

5. Twitter的snowflake算法

  snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。snowflake算法可以根据自身项目的需要进行一定的修改。比如估算未来的数据中心个数,每个数据中心的机器数以及统一毫秒可以能的并发数来调整在算法中所需要的bit数。

优点:

  1. 不依赖于数据库,灵活方便,且性能优于数据库。
  2. ID按照时间在单机上是递增的。

缺点:

  1. 在单机上是递增的,但是由于涉及到分布式环境,每台机器上的时钟不可能完全同步,也许有时候也会出现不是全局递增的情况。

参考:

  1. 分布式系统唯一ID生成方案汇总
  2. UUID 、GUID、COMB 的区别与联系
  3. UUID 和 GUID 的区别
  4. The Cost of GUIDs as Primary Keys
  5. Integer GUID和Comb做主键的效率测试(Delphi+access)(三)
  6. Twitter-Snowflake项目地址(Tags:snowflake-2010)
  7. 如何在高并发分布式系统中生成全局唯一Id
  8. Twitter-Snowflake(64位分布式ID算法)分析与JAVA实现

转载注明出处,我就不和你计较。
by Donney Young
http://www.jianshu.com/p/a0a3aa888a49

作者:DonneyYoung
链接:http://www.jianshu.com/p/a0a3aa888a49
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数据库分库分表(一)常见分布式主键ID生成策略的更多相关文章

  1. 分库分表的 9种分布式主键ID 生成方案,挺全乎的

    <sharding-jdbc 分库分表的 4种分片策略> 中我们介绍了 sharding-jdbc 4种分片策略的使用场景,可以满足基础的分片功能开发,这篇我们来看看分库分表后,应该如何为 ...

  2. 常见分布式全局唯一ID生成策略

    全局唯一的 ID 几乎是所有系统都会遇到的刚需.这个 id 在搜索, 存储数据, 加快检索速度 等等很多方面都有着重要的意义.工业上有多种策略来获取这个全局唯一的id,针对常见的几种场景,我在这里进行 ...

  3. mybatis 针对SQL Server 的 主键id生成策略

    SQL Server中命令: select newId()  ,可以得到SQL server数据库原生的UUID值,因此我们可以将这条指令写到 Mybatis的主键生成策略配置selectKey中. ...

  4. 转数据库分库分表(sharding)系列(二) 全局主键生成策略

    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表( ...

  5. 数据库分库分表(sharding)系列(二) 全局主键生成策略

    本文将主要介绍一些常见的全局主键生成策略,然后重点介绍flickr使用的一种非常优秀的全局主键生成方案.关于分库分表(sharding)的拆分策略和实施细则,请参考该系列的前一篇文章:数据库分库分表( ...

  6. 分布式事务-Sharding 数据库分库分表

      Sharding (转)大型互联网站解决海量数据的常见策略 - - ITeye技术网站 阿里巴巴Cobar架构设计与实践 - 机械机电 - 道客巴巴 阿里分布式数据库服务原理与实践:沈询_文档下载 ...

  7. 数据库分库分表(sharding)系列【转】

    原文地址:http://www.uml.org.cn/sjjm/201211212.asp数据库分库分表(sharding)系列 目录; (一) 拆分实施策略和示例演示 (二) 全局主键生成策略 (三 ...

  8. 数据库分库分表(sharding)系列

    数据库分库分表(sharding)系列     目录; (一) 拆分实施策略和示例演示 (二) 全局主键生成策略 (三) 关于使用框架还是自主开发以及sharding实现层面的考量 (四) 多数据源的 ...

  9. 【转】mysql分库分表,数据库分库分表思路

    原文:https://www.cnblogs.com/butterfly100/p/9034281.html 同类参考:[转]数据库的分库分表基本思想 数据库分库分表思路   一. 数据切分 关系型数 ...

随机推荐

  1. Solr查询query效果对比

    q条件 默认分词(org.apache.solr.analysis.TokenizerChain) "parsedquery" IK分词(org.wltea.analyzer.lu ...

  2. 使用 Build Pipeline View 插件图表展示Jenkins job依赖关系

    使用 Build Pipeline View 查看Jenkins的Job的依赖关系图表 安装 Build Pipeline View 插件下载地址 下载后再jenkins的"插件管理&quo ...

  3. docker查看挂载目录命令

    docker inspect -f "{{.Mounts}}"  692691b7416 692691b7416为containerId

  4. 自己从0开始学习Unity的笔记 VII (C#中类继承练习)

    好久都没有写了.今天做了类继承的练习,做了一个小队,进行简单的判定. namespace 兵团建立练习 { class ServantBasics { public string name; //pr ...

  5. leetcode 回文数

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...

  6. C#基础知识入门概要(自我回顾用)

    一,C#是什么? 人与人之间可以用语言进行交流,我们和计算机交流也是通过语言.我们可以通过语言让一个人做一件我们想让他做事情(他愿意的话~),我们能不能让计算机按照我们的意愿来做事情呢?比如我们让计算 ...

  7. C#基础笔记(第十七天)

    1.复习 ref 传地址 用的是同一块内存 一个改变另一个也随着改变 return n1 > n2 ? n1 : n2; 三元表达式 int max=GetMax(1,2,3,4,5,6,); ...

  8. centos7无GUI运行selenium chromedriver 亲测可用!

    1. 安装chrome 首先安装google的epel源 vi /etc/yum.repos.d/google.repo [google] name=Google-x86_64 baseurl=htt ...

  9. 【OCP-12c】2019年CUUG OCP 071考试题库(78题)

    78.View the exhibit and examine the structure of the CUSTOMERStable. Which two tasks would require s ...

  10. Thread.sleep(1000)

    public class Wait { public static void main(String[] args) { System.out.println(System.currentTimeMi ...