• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

mysql 生成独一全局主键ID_mysql

mysql 搞代码 7年前 (2018-06-07) 176次浏览 已收录 0个评论

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       

欢迎大家阅读《mysql 生成独一全局主键ID_mysql》,跪求各位点评,by 搞代码


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:mysql 生成独一全局主键ID_mysql
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址