欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于MySql的扩展功能生成全局ID

程序员文章站 2024-02-22 22:08:58
本文利用 mysql的扩展功能 replace into 来生成全局id,replace into和insert的功能一样,但是当使用replace into插入新数据行时...

本文利用 mysql的扩展功能 replace into 来生成全局id,replace into和insert的功能一样,但是当使用replace into插入新数据行时,如果新插入的行的主键或唯一键(unique key)已有的行重复时,已有的行会先被删除,然后再将新数据行插入(replace into 是原始操作)。

建立类似下面的表:

create table `tickets64` ( 
  `id` bigint(20) unsigned not null auto_increment, 
  `stub` char(1) not null default '', 
  primary key (`id`), 
  unique key `stub` (`stub`) 
) engine=myisam; 

当需要获得全局唯一id时,执行下面的sql语句:

replace into `tickets64` (`stub`) values ('a'); 
select last_insert_id(); 

第一次执行这个语句后,ticket64表将包含以下数据:

+--------+------+ 
| id     | stub | 
+--------+------+ 
| 1      |    a | 
+--------+------+  

以后再次执行前面的语句,stub字段值为'a'的行已经存在,所以mysql会先删除这一行,再插入。因此,第二次执行后,ticket64表还是只有一行数据,只是id字段的值为2。这个表将一直只有一行数据。

更棒的方法:

      比如,只需要一张ticket表就可以为所有的业务表提供各自连续的id。下面,来看一下我们的方法。首先来看一下表结构:

create table `sequence` ( 
  `name` varchar(50) not null, 
  `id` bigint(20) unsigned not null default '0', 
  primary key (`name`) 
) engine=innodb; 

 注意区别,id字段不是自增的,也不是主键。在使用前,我们需要先插入一些初始化数据:

insert into `sequence` (`name`) values  
('users'), ('photos'), ('albums'), ('comments'); 

接下来,我们可以通过执行下面的sql语句来获得新的照片id:

update `sequence` set `id` = last_insert_id(`id` + 1) where `name` = 'photos'; 
select last_insert_id(); 

我们执行了一个更新操作,将id字段增加1,并将增加后的值传递到last_insert_id函数,从而指定了last_insert_id的返回值。

实际上,我们不一定需要预先指定序列的名字。如果我们现在需要一种新的序列,我们可以直接执行下面的sql语句:

insert into `sequence` (`name`) values('new_business') on duplicate key update `id` = last_insert_id(`id` + 1); 
select last_insert_id();

     这里,我们采用了insert … on duplicate key update这个mysql扩展,这个扩展的功能也和insert一样插入一行新的记录,但是当新插入的行的主键或唯一键(unique key)和已有的行重复时,会对已有行进行update操作。

当我们第一次执行上面的语句时,因为还没有name为'new_business'的字段,所以正常的执行了插入操作,需要注意的是通过这种方式获取的序列起始值为0,而不是1。因为第一次执行时,没有执行update,所以也没有为last_insert_id传递值,我们也没有自增字段,所以select last_insert_id()将返回0。不过这个应该不是什么大问题。

update: 这个方法更容易解决单点问题,也不局限于两个服务器,只要对不同的服务器设置不同的初始值(但必须是连续的),然后将增量变为服务器数就行了。

以上内容是基于mysql的扩展功能生成全局id的相关资料,希望大家喜欢。