Home >Database >Mysql Tutorial >大区中分配玩家唯一ID的办法(续)_MySQL

大区中分配玩家唯一ID的办法(续)_MySQL

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOriginal
2016-06-01 13:38:001143browse

bitsCN.com


大区中分配玩家唯一ID的办法(续)

 

相关链接:

大区中分配玩家唯一ID的办法

http:///database/201212/173832.html

 

之前因为时间匆忙,大区里产生唯一ID只是简单写了一个方法,今天趁着有时间,把里面一些过程写出来,也算是个总结。    

      首先说说需求,现在游戏里数据库为了分散热点,都采用分表方式,以前那种一张表AUTO_INCREMENT的方式显然不行了,那么将唯一ID放到业务进程里可行吗?这个也不好,因为现在后台都是多个部署,每个进程可以保证ID唯一,但是存到数据库的时候就可能重复,所以我们还是得在DB上做文章。

      因此就有了上篇文章的解决方案,单独一张表,这张表的作用就是专门产生唯一ID,而且为多个业务提供唯一ID,多进程情况下也不需要锁表,效率比较高,是不是很像设计模式里的工厂。接着我来分析下这张表。我们再来看看表结构和用法

 

create table SeqTab ( 

   iSeqNo bigint(20) not null default 0,   //表示唯一ID

   iSeqType int(11) not null default 0,   //表示业务ID

   primary key(iSeqNo,iSeqType));

   insert into SeqTab values(0,1);        //初始化,假设一个业务编号为1

   update SeqTab set iSeqNo=last_insert_id(iSeqNo+1) where iSeqType=1;

   select last_insert_id();                   //这两句是获取一个业务的唯一ID,供业务进程使用。

 

   其实说到这张表,关键是说LAST_INSERT_ID()这个方法。它有两种形式LAST_INSERT_ID(),LAST_INSERT_ID(expr)。

   这个东西的特点是,1.属于每个CONNECTION,CONNECTION之间相互不会影响 2.不属于某个具体的表 3.返回最后一次INSERT AUTO_INCREMENT的值 4.假如以此使用INSERT插入    多行数据,只返回第一行数据产生的值 5.如果你UPDATE某个AUTO_INCREMENT的值,不会影响LAST_INSERT_ID()返回值

   LAST_INSERT_ID(expr)与LAST_INSERT_ID()稍有不同,首先它返回expr的值,其次它的返回值会记录在LAST_INSERT_ID()。

 

   我们这里主要使用到了第一和第二个特点,每个进程并发执行update SeqTab set iSeqNo=last_insert_id(iSeqNo+1) where iSeqType=1;,就获取属于进程自己的iSeqNo并且记录在 LAST_INSERT_ID中,通过第二句取出该值。   

    接着我们在比较下其他一些办法。

    第一种是直接一张表,里面有一个ID字段,设置成AUTO_INCREMENT。这个的问题是每个业务ID不是连续的,是离散的。

    第二种是使用GUID或者UUID,但是这个问题我个人觉得是效率上的差异,字符串没有数字的效率好,另外数字ID今后也可以拼接一些区信息,之后跨区的时候可以方便获取对象是哪个区的.

 

bitsCN.com
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn