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主键的实现方法,整型ID作为主键好处有很多,比如节省存储空间、插入和查询排序快、具有一定规律性(时间顺序)等。
生成全局ID的方法很多, 这里记录下一种简单的方案: 利用mysql的自增id生成全局唯一ID. 1. 创建一张只需要两个字段的表: CREATE TABLE `guid` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `stub` char(1...
既然要sharding,那么不可避免的要讨论到sharding key问题,在有些业务系统中,必须保证sharding key全局唯一,比如存放商品的数据库等,那么如何生成全局唯一的ID呢,下文将从DBA的角度介绍几种常见的方案。...
mysql用触发器实现char类型主键自增长
主要介绍了Python3 操作 MySQL 插入一条数据并返回主键 id的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
idgo是一个利用MySQL批量生成ID的ID生成器, 主要有以下特点:每次通过事务批量取ID,性能较高,且不会对MySQL造成压力.当ID生成器服务崩溃后,可以继续生成有效ID,避免了ID回绕的风险.业界已经有利于MySQL生成ID的方案,...
twitter在把存储系统从MySQL迁移到Cassandra的过程中由于Cassandra没有顺序ID生成机制,于是自己开发了一套全局唯一ID生成服务:Snowflake。 1 41位的时间序列(精确到毫秒,41位的长度可以使用69年) 2 10位的机器...
MySQL AUTO_INCREMENT 和主键等解释
这个是用mysql写的存储过程,搭配里面一张数据表使用,达到高并发情况下获得唯一订单号的目的;原理:按照一定规则生成订单号后,把订单号插入数据表后,再返回给用户,由于数据表设置了主键,也就是当数据表中存在...
ft_bigID(生成19位的Long Integer类型的数据),生成唯一的随机码。
用hibernate方式配置生成mysql guid数据,32位的,在eclipse下直接导入,运行即可
链接mysql 生成对应的word文档。亲测可用 字符编码:UTF-8 修改数据库链接就可用直接生成
有关Mybatis雪花ID主键插件前面写了两篇博客作为该项目落地的铺垫。 1、 2、 该插件项目可以直接运用于实际开发中,作为分布式数据库表主键ID使用。 一、项目概述 1、项目背景 在生成表主键ID时,我们可以考虑主键...
mysql修改自增主键初始值,简单易操作,数据库维护小技巧。
配置好数据库连接字符串和输出路径,自动把MySQL数据表生成相应的Java实体类。附上数据库。来源是参考别人的代码,有添加了自动获取表名的功能,不需要手动写表名,非常方便。
Mysql生成三千万条数据,用于测试hive和mysql大数据量处理的速度,详细的jav代码生成
MySQL数据库分表批量主键查询代理-mysql-partitions-proxy
PHP+MySQL生成静态网页实例,不错,推荐学习,哈哈
分布式:可任意横向扩展 高性能:分配 ID 只访问内存(到达上限会请求数据库一次) 易用性:对外提供 HTTP 服务 唯一性:MySQL 自增 ID,永不重复 高可靠:MySQL 持久化