`
annan211
  • 浏览: 460387 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

mysql 生成唯一全局主键ID

阅读更多

mysql生成全局唯一ID

全局唯一ID生成策略多种多样,这里列举几例以供参考。

1 使用auto_increment_increment和auto_increment_offset
  这两个服务器变量可以让mysql以期望的值和偏移量来增加auto_increment列的值。
  举个例子,两台服务器,可以配置这两台服务器自增步长都是2,其中一台的偏移量设置为1,另一台设置为2,
  这样每台服务器生成的ID就是唯一不重复的。同理,配置3台服务器,初始值为 1、2、3 统一步长为3,则每台服务器生成的
  ID就是唯一不重复的。这种方法相对简单,并且不依赖于某个节点,因此是生成唯一ID的比较普遍的做法。但是其缺点也是名叫明显,
  需要非常仔细的配置服务器,很容易因为配置错误生成重复数字,特别是当增加服务器需要改变其角色或进行灾难恢复时。
  
  缺陷:
1) 在大表做水平分表时,就不能使用自增Id,因为Insert的记录插入到哪个分表依分表规则判定决定,若是自增Id,各个分表中Id就会重复,在做查询、删除时就会有异常。
2) 在对表进行高并发单记录插入时需要加入事物机制,否则会出现Id重复的问题。
3) 在业务上操作父、子表(即关联表)插入时,需要在插入数据库之前获取max(id)用于标识父表和子表关系,若存在并发获取max(id)的情况,max(id)会同时被别的线程获取到。

  此种方式适合小应用,无需分表,没有高并发性能要求。	
2 在全局节点中创建表
  在一个全局数据库节点中创建一个包含auto_increment列的表,应用可以通过这个表来生成唯一数字。
  1)使用MaxId表存储各表的MaxId值
    专门一个数据库,记录各个表的MaxId值,建一个存储过程来取Id,逻辑大致为:开启事物,对于在表中不存在记录,直接返回一个默认值为1的键值,同时插入该条记录到table_key表中。而对于已存在的记录,key值直接在原来的key基础上加1更新到MaxId表中并返回key。
    使用此方案的问题是:每次的查询MaxId是一个性能损耗;不过不会像自增序列表那么容易列暴掉,因为是摆表进行划分的。
  
3 使用memcached
  在memcached的API中有一个incr函数,可以自动增长一个数字并返回。

4 批量分配数字
  应用可以从一个全局节点中请求一批数字,用完后再申请。
  
5 使用多台ID生成器 
 建立两台以上的数据库ID生成服务器,每个服务器都有一张记录各表当前ID的MaxId表,但是MaxId表中Id的增长步长是服务器的数量,起始值依次错开,
 这样相当于把ID的生成散列到每个服务器节点上。例如:如果我们设置两台数据库ID生成服务器,那么就让一台的MaxId表的Id起始值为1(或当前最大Id+1),
 每次增长步长为2,另一台的MaxId表的ID起始值为2(或当前最大Id+2),每次步长也为2。这样就将产生ID的压力均匀分散到两台服务器上,同时配合应用程序控制,当一个服务器失效后,
 系统能自动切换到另一个服务器上获取ID,从而解决的单点问题保证了系统的容错。(Flickr思想)
 但是要注意:1、多服务器就必须面临负载均衡的问题;2、倘若添加新节点,需要对原有数据重新根据步长计算迁移数据。
 结论:适合大型应用,生成Id较短,友好性比较好。(强烈推荐)
 
 6 “COMB”(combined guid/timestamp,意思是:组合GUID/时间截)
   COMB数据类型的基本设计思路是这样的:既然GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么能不能通过组合的方式,保留GUID的10个字节,
   用另6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与GUID组合起来,在保留GUID的唯一性的同时增加了有序性,以此来提高索引效率。
   /// <summary> /// Generate a new <see cref="Guid"/> using the comb algorithm.
/// </summary> 
private Guid GenerateComb()
{
    byte[] guidArray = Guid.NewGuid().ToByteArray();
 
    DateTime baseDate = new DateTime(1900, 1, 1);
    DateTime now = DateTime.Now;
 
    // Get the days and milliseconds which will be used to build   
    //the byte string    
    TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
    TimeSpan msecs = now.TimeOfDay;
 
    // Convert to a byte array        
    // Note that SQL Server is accurate to 1/300th of a   
    // millisecond so we divide by 3.333333    
    byte[] daysArray = BitConverter.GetBytes(days.Days);
    byte[] msecsArray = BitConverter.GetBytes((long)
      (msecs.TotalMilliseconds / 3.333333));
 
    // Reverse the bytes to match SQL Servers ordering   
    Array.Reverse(daysArray);
    Array.Reverse(msecsArray);
 
    // Copy the bytes into the guid    
    Array.Copy(daysArray, daysArray.Length - 2, guidArray,
      guidArray.Length - 6, 2);
    Array.Copy(msecsArray, msecsArray.Length - 4, guidArray,
      guidArray.Length - 4, 4);
 
    return new Guid(guidArray);
}
结论:适合大型应用。即保留GUID的唯一性的同时增加了GUID有序性,提高了索引效率;解决了关联表业务问题;生成的Id不够友好;占据了32位。(强烈推荐)

7 另外互联网上有比较流行的借鉴flicker 和twitter 的做法,可以借鉴。
  
参考   http://blog.csdn.net/houkai6/article/details/17713845
http://my.oschina.net/u/142836/blog/174465
  
  

   请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

分享到:
评论

相关推荐

    mysql雪花算法生成唯一整型ID主键的实现方法

    MySQL 雪花算法生成唯一整型ID主键的实现主要针对大数据环境下,需要大量生成全局唯一ID的需求。雪花算法是一种分布式ID生成策略,由Twitter开源,其设计目标是在分布式系统中生成具有全局唯一性、有序性和高并发性...

    Mysql全局ID生成方法

    MySQL本身也提供了如`UUID()`或`LAST_INSERT_ID()`等函数,可以生成全局唯一的ID。`UUID()`生成128位的UUID,而`LAST_INSERT_ID()`返回最后插入行的ID,通常用于自增列。 在选择全局ID生成方法时,需要考虑并发...

    mysql_guid主键生成方式范例

    MySQL中的GUID(Globally Unique Identifier)主键生成方式是一种确保数据库中每一条记录具有唯一标识的方法,尤其在分布式系统中十分常见。本示例主要介绍如何通过Hibernate框架配置,来实现MySQL数据库中GUID主键...

    Go-GoMySQL实现的ID生成服务

    在现代分布式系统中,生成全局唯一的ID是一项基本且重要的任务。本文将深入探讨如何利用Go语言和MySQL数据库实现一个高性能、高可用的ID生成服务。该服务具备良好的扩展性,保证了ID的唯一性,并且通过HTTP接口提供...

    MySQL数据库生成C#实体类工具

    此命令将会全局安装`FreeSql.Generator`工具,之后您可以在任何.NET Core或.NET项目中使用它来自动生成实体类。需要注意的是,在运行该命令前,请确保您的开发环境已正确配置.NET SDK,并且版本支持`dotnet tool`...

    hibernate中自动生成主键的办法

    UUID(Universally Unique Identifier)是一种生成全局唯一标识符的方式,其长度为128位,通常表示为32个十六进制数字组成的字符串。在Hibernate中,可以通过`&lt;generator class="uuid.hex"/&gt;`来配置一个字段使用UUID...

    Java 数据库主键生成类 IdWorker

    高并发分布式系统中生成全局唯一Id汇总 数据在分片时,典型的是分库分表,就有一个全局ID生成的问题。 单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求: 1 不能有单点故障。 2 以时间为...

    真实项目中关于主键生成方式的剖析(JPA)

    而Hibernate提供了跨数据库的主键生成策略,例如`native`策略,它会根据底层数据库自动选择合适的主键生成方式(如MySQL的自动增长ID或Oracle的序列)。 在JPA中,通过`@GenericGenerator`注解可以定义主键的生成...

    数据库主键生成资料资源

    4. 雪花算法:一种分布式ID生成策略,如Twitter的Snowflake算法,结合时间戳、工作节点ID和序列号,生成具有足够大的取值范围且有序的ID,适用于大规模分布式系统。 5. 用户自定义:允许用户输入特定值,但这需要...

    Hibernate映射文件主键的生成

    生成16进制表示的UUID字符串,适用于需要全局唯一且长度固定的主键。在映射文件中配置`&lt;generator class="uuid.hex"&gt;`。 5. **UUIDString策略**: 生成标准格式的UUID字符串,较UUIDHex更易读。配置为`...

    MybatisPlus主键生成策略方法详解.docx

    - `ID_WORKER`: 全局唯一ID,基于`idWorker`,适用于数值类型数据库字段。 - `UUID`: 生成不含中划线的全局唯一UUID。 - `ID_WORKER_STR`: 基于`idWorker`的字符串表示,适合字符串类型的数据库字段。 3. **局部...

    Go-GolangMysql实现的分布式ID生成服务

    在分布式系统中,生成全局唯一且递增的ID是常见的需求,这有助于追踪和管理大量数据。Go语言作为现代的、高性能的编程语言,被广泛应用于构建分布式系统。本篇文章将详细探讨如何使用Go和MySQL来实现一个分布式ID...

    spring boot整合mybatis利用Mysql实现主键UUID的方法

    `tk.mybatis.mapper.common.IdsMapper`则提供了处理主键ID的基本操作。 在Mapper接口中,你可以像平常一样定义CRUD方法。由于使用了UUID作为主键,插入数据时MyBatis会自动为新记录生成一个UUID。例如: ```java ...

    JPA环境搭建及JPA实例与JPA主键生成策略

    4. **UUID**:生成全局唯一的UUID字符串作为主键。 5. **ASSIGNED**:主键由应用程序分配,JPA不会自动管理。 选择哪种策略取决于你的数据库系统和需求。例如,如果你的数据库不支持序列,但又希望有顺序的主键,...

    MyBatis主键自动生成方法.pdf

    8. 对于SQL Server,可以使用`newId()`函数来生成全局唯一标识符(GUID)。与Oracle类似,可以配置`&lt;selectKey&gt;`元素来获取这个值,然后插入到记录中。 综上所述,MyBatis提供了灵活的方式来处理主键自动生成,无论...

    08_ibatis教程_sql主键生成方式.rar

    在分布式环境下,为了保证全局唯一性,常常使用雪花算法生成主键。这需要在应用程序中实现,而非数据库层面。Ibatis本身不直接支持雪花算法,但可以通过拦截器或在Service层进行处理。 5. **UUID(Universally ...

    hibernate 主键生成策略

    在 Hibernate 中,主键生成策略是一项核心功能,用于确定如何为持久化实体生成唯一的标识符。以下是 Hibernate 支持的主要主键生成策略的详细解析: #### 1. Native - **描述**:此策略根据所使用的数据库类型自动...

    Hibernate的主键生成方式

    - **应用场景**:适用于需要全局唯一ID的场景,例如分布式系统中。 9. **uuid.string** - **定义**:与uuid.hex类似,但生成的UUID以字符串形式存储。 - **应用场景**:适用于某些数据库(如PostgreSQL)不支持...

    MySQL的自增ID(主键) 用完了的解决方法

    - 使用分布式ID生成服务,如Twitter的Snowflake算法,可以生成全局唯一的64位ID,避免在单表内用尽ID。 7. **备份与恢复**: - 在进行任何更改之前,记得先备份数据库,以防止意外情况导致数据丢失。 总之,理解...

    细聊分布式ID生成方法.pdf

    它通过将ID分成多个部分(如时间戳、机器ID、序列号等),从而保证了ID的全局唯一性。此算法广泛应用于高并发场景下的分布式系统中。 - **优点**:支持高并发,性能优越;生成的ID较短且有序,便于排序操作。 - **...

Global site tag (gtag.js) - Google Analytics