mysql全局唯一ID生成方案(二)

MySQL数据表结构中,一般情况下,都会定义一个具有‘AUTO_INCREMENT’扩展属性的‘ID’字段,以确保数据表的每一条记录都可以用这个ID唯一确定;

随着数据的不断扩张,为了提高数据库查询性能,降低查询热点,一般都会把一张表按照一定的规则分成多张数据表,即常说的分表;

分表除了表名的索引不同之外,表结构都是一样的,如果各表的‘ID’字段仍采用‘AUTO_INCREMENT’的方式的话,ID就不能唯确定一条记录了。

这时就需要一种处于各个分表之外的机制来生成ID,我们一般采用一张单独的数据表(不妨假设表名为‘ticket_mutex’)来保存这个ID,无论哪个分表有数据增加时,都是先到ticket_mutex表把ID值加1,然后取得ID值。

这个取ID的操作看似很复杂,所幸的是,MySQL提供了LAST_INSERT_ID机制,让我们能一步完成。

1、新建数据表ticket_mutex

CREATE TABLE ticket_mutex (
    name varchar(32) NOT NULL PRIMARY KEY COMMENT ‘业务名称‘,
    value bigint(20) UNSIGNED NOT NULL COMMENT ‘ID值‘
)Engine=InnoDB DEFAULT CHARSET=UTF8 COMMENT ‘保存分表ID表‘;
字段‘name’用来说明这个ID是哪个业务的,比如‘用户’的ID,我们可以定为‘USER’;
字段‘value’即该业务的ID值。

2、初始化业务和其ID值
INSERT INTO ticket_mutex(name, value) values(‘USER‘, 0),(‘POST‘, 0);
+------+-------+
| name | value |
+------+-------+
| POST |     0 |
| USER |     0 |
+------+-------+
我们初始化了2条记录,即有2个不同的业务,分别代表‘用户信息’和‘主题信息’,它们初始ID值均为‘0’;

3、获取分表唯一ID
这个时候就要利用MySQL提供的LAST_INSERT_ID()机制了。
在往用户表里新增一条数据时,获取‘用户ID’:
UPDATE ticket_mutex SET value=LAST_INSERT_ID(value+1) WHERE name=‘USER‘;SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+
通过这条语句之后,我们得到结果为1,这个值就是我们所需要的值。再来查看数据记录,我们发现记录总数没有改变,但是‘用户’的ID已经为1了;
+------+-------+
| name | value |
+------+-------+
| POST |     0 |
| USER |     1 |
+------+-------+
同样的方法,我们可获取‘主题’的ID:
UPDATE ticket_mutex SET value=LAST_INSERT_ID(value+1) WHERE name=‘POST‘;SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+
查看所有的记录:
+------+-------+
| name | value |
+------+-------+
| POST |     1 |
| USER |     1 |
+------+-------+

从上可以看出,通过MySQL的LAST_INSERT_ID机制,我们可以保证在记录总数不增长的情况下,让业务ID在不断的增加,从而保证了分表ID的唯一性。

4、LAST_INSERT_ID说明
从名字可以看出,LAST_INSERT_ID即为最后插入的ID值,根据MySQL的官方手册说明,它有2种使用方法
一是不带参数:LAST_INSERT_ID(),这种方法和AUTO_INCREMENT属性一起使用,当往带有‘AUTO_INCREMENT’属性字段的表中新增记录时,LAST_INSERT_ID()即返回该字段的值,大家可试下(我已经验证过);
二是带有表达式:如上面介绍的LAST_INSERT_ID(value+1),它返回的是表达式的值,即‘value+1’;
---------------------
作者:Jef冒牌绅士
来源:CSDN
原文:https://blog.csdn.net/longjef/article/details/53117392
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/findumars/p/10421283.html

时间: 2024-09-28 02:47:20

mysql全局唯一ID生成方案(二)的相关文章

【系统设计】分布式唯一ID生成方案总结

目录 分布式系统中唯一ID生成方案 1. 唯一ID简介 2. 全局ID常见生成方案 2.1 UUID生成 2.2 数据库生成 2.3 Redis生成 2.4 利用zookeeper生成 2.5 雪花算法生成 2.6 其他生成方式 分布式系统中唯一ID生成方案 在系统设计中,我们经常需要一个全局唯一的ID来标识一条数据,比如订单表,商品表的主键ID.这个ID往往能影响到数据存储.索引和查询等操作的效率.因此这个全局唯一的ID对系统的可用性和性能至关重要. 1. 唯一ID简介 在系统设计中,我们经常

zookeeper全局唯一id生成

一背景 传统生成id方式可以靠数据库的自增来实现,但是在分布式环境下不太适应.依赖数据库容易造成单点. 为什么不用UUID的,网上看别人介绍的时候,从两个方面去分析: 1 大并发的情况下,UUID会出现重复. 2.UUID是随即的,含义不明.从业务角度去考虑,如果用作订单,用户查询订单在数据分片的情况下很可能分散在多个库,查询困难. 全局唯一id的要求比较高: 不能有单点故障. 性能好,毫秒级返回. 能顺序便于DB存储及划分. 二 使用zookeeper生成全局唯一id. 2.1 利用Zooke

分布式系统全局唯一ID生成

一 什么是分布式系统唯一ID 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识. 如在金融.电商.支付.等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID显然不能满足需求,此时一个能够生成全局唯一ID的系统是非常必要的. 二.分布式系统唯一ID的特点 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求. 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数

分布式全局唯一ID生成策略?

一.背景 分布式系统中我们会对一些数据量大的业务进行分拆,如:用户表,订单表.因为数据量巨大一张表无法承接,就会对其进行分库分表. 但一旦涉及到分库分表,就会引申出分布式系统中唯一主键ID的生成问题. 1.1 唯一ID的特性 整个系统ID唯一; ID是数字类型,而且是趋势递增; ID简短,查询效率快. 1.2 递增与趋势递增 递增 趋势递增 第一次生成的ID为12,下一次生成的ID是13,再下一次生成的ID是14. 什么是?如:在一段时间内,生成的ID是递增的趋势.如:再一段时间内生成的ID在[

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

全局唯一的 ID 几乎是所有系统都会遇到的刚需.这个 id 在搜索, 存储数据, 加快检索速度 等等很多方面都有着重要的意义.工业上有多种策略来获取这个全局唯一的id,针对常见的几种场景,我在这里进行简单的总结和对比. 简单分析一下需求 [1] 所谓全局唯一的 id 其实往往对应是生成唯一记录标识的业务需求. 这个 id 常常是数据库的主键,数据库上会建立聚集索引(cluster index),即在物理存储上以这个字段排序.这个记录标识上的查询,往往又有分页或者排序的业务需求.所以往往要有一个t

分布式系统唯一ID生成方案汇总

系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结.生成ID的方法有很多,适应不同的场景.需求以及性能要求.所以有些比较复杂的系统会有多个ID生成的策略.下面就介绍一些常见的ID生成策略. 1. 数据库自增长序列或字段 最常见的方式.利用数据库,全数据库唯一. 优点: 1)简单,代码方便,性能可以接受. 2)数字ID天然排序,对分页或者需要排序的结果很有帮助. 缺点: 1)不同数据库语法和实现不同,数据库迁移的时候或多数据库版本支持的时候需要处理. 2)在单个数据库或

Twitter全局唯一ID生成算法

测试:private static void TestIdWorker() { HashSet<long> set = new HashSet<long>(); IdWorker idWorker1 = new IdWorker(0, 0); IdWorker idWorker2 = new IdWorker(1, 0); //762884413578018816 //762884520121729024 Stopwatch sw = new Stopwatch(); sw.Sta

【转】MySQL分库分表环境下全局ID生成方案

转载一篇博客,里面有很多的知识和思想值得我们去思考. —————————————————————————————————————————————————————————————————————— 在大型互联网应用中,随着用户数的增加,为了提高应用的性能,我们经常需要对数据库进行分库分表操作.在单表时代,我们可以完全依赖于数据库的自增ID来唯一标识一个用户或数据对象.但是当我们对数据库进行了分库分表后,就不能依赖于每个表的自增ID来全局唯一标识这些数据了.因此,我们需要提供一个全局唯一的ID号生成

高并发分布式系统中生成全局唯一Id汇总

高并发分布式系统中生成全局唯一Id汇总 (转自:http://www.cnblogs.com/baiwa/p/5318432.html) 数据在分片时,典型的是分库分表,就有一个全局ID生成的问题.单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求:   1 不能有单点故障.   2 以时间为序,或者ID里包含时间.这样一是可以少一个索引,二是冷热数据容易分离.   3 可以控制ShardingId.比如某一个用户的文章要放在同一个分片内,这样查询效率高,修改也容易.