zoukankan      html  css  js  c++  java
  • mysql 获取全局唯一值

      在涉及数据库存储数据的时候,经常会遇到唯一值问题,有的是主键带来的限制,有的则是业务上的需要。

      下面介绍几种唯一值的获取或者生产方法:

      先建一个测试用的表tbl_user,有三个字段:Id、Name、Age,其中Id为主键。
       1:  drop table if exists `tbl_user`;
       2:  create table 
       3:  `tbl_user` (
       4:      `Id` int(10),
       5:      `Name` varchar(20),
       6:      `Age` int(10),
       7:      PRIMARY KEY  (`Id`)
       8:  )DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     

      插入几条数据

       1:  insert into tbl_user values (1000,"小猫",22);
       2:  insert into tbl_user values (1001,"小狗",22);
       3:  insert into tbl_user values (1002,"小刺猬",22);
       4:   
       5:  select * from tbl_user;
      查询结果:
      image
     
      1.由应用程序根据一定算法生成唯一值:一般采用”MD5(时间戳+随机数)“或者其他的UUID算法,基本也比较好实现。如果遇到多机器上分布的程序访问统一数据库的表,可以把Ip、网卡号等信息考进来就可以解决了(当然可以不是简单的拼接,你可以根据需要去合适的位数经过一定的算法去获取)。
     

      2.先查询表中最大的值select max(id),再加1后作为新的值。很笨的方法。

       1:  select max(Id) from tbl_user;
       2:  查询到的最大Id为 1002
       3:   
       4:  之后插入 1003
       5:   
       6:  insert into tbl_user values (1003,"小熊",22);
       7:   

      此时表中数据为

      image

      3.如果是表级别的唯一,即在同一个表中某个字段唯一,可以把该字段设置为“自增(AUTO_INCREMENT)”的。这样你不必费心思去生成这个不能重复的唯一值了。但是一般应用程序是需要这个唯一值的,这个时候你就得在查询一次去获取刚才数据库自增生成的Id。比如在用户登录的时候,你要生成一个登录会话Id或者Token,这些程序一般是需要得到这个值而不是仅仅存在数据库中。生成的值,1.可以一般的select条件查询,根据条件查询刚才插入的数据。2.直接调用select @@IDENTITY 就可以得到上一次插入记录时自动产生的ID(注意是在数据库同一个连接(会话)中),用在插入后立select @@IDENTITY

      看例子,先将表中的Id字段设置为自增,再插入一条数据(不要插入Id值,让数据库自增得到值),select @@IDENTITY查询,最后验证看看。

    1.#将Id改为自增(auto_increment)
    ALTER TABLE tbl_user CHANGE Id Id int not null auto_increment;
    
    #或者 先删除Id字段再添加一个Id字段
    alter table tbl_user auto_increment=1000;
    alter table tbl_user drop column Id;
    alter table tbl_user add Id int not null auto_increment primary key first;
    
    2.插入一条记录
    insert tbl_user set Name='小猴',Age=23;
    
    3.查询刚才的自增Id值
    select @@IDENTITY;
    值是1004,


      验证下:select * from tbl_user;得到的当前表记录为

      image

      过刚插入的数据“小猴”id为1004,和select @@IDENTITY;结果一样。

      4.使用mysql的 UUID()函数。前面的自增字段(auto_increment)只能生成”表内”的唯一值,且需要搭配使其为”唯一的主键或唯一索引”,它的值是逐步增长的。这里的UUID产生的是字符串类型值,固定长度为:36个字符。UUID生成的是在时间、空间上都独一无二的值,是“随机+规则”组合而成。

    select uuid();
    select uuid();
    
    执行两次,结果:
    69ad8b74-6d47-11e3-ba6e-7446a08ee8ec
    69b03c16-6d47-11e3-ba6e-7446a08ee8ec

      可以看到,多次调用UUID()函数得到的值不相同,它由五部分组成,并且有连字符(-)隔开,一共36个字符。其中:

      前3组值是时间戳换算过来的,解决“时间上唯一”;

      第4组值是暂时性保持时间戳的唯一性,重启mysql才会变动;

      第5组是mac值转过来的,有助于解决“空间上的唯一”,同一个机器多实例的一般相同。如果mac值获取不到,则是一个随机值。

      这些已经可以保证得到的值在时间和空间上的唯一。当然你也可以去掉连字符: select replace(uuid(),'-','')。

      在MySQL 5.1.*及更高版本有一个变种的UUID()函数,UUID_SHORT(),可以生成一个17-64位无符号的整数,注意是生成的一个整数,而前面UUID()生成的是字符串。MySQL启动后第一次执行的值是通过时间戳等初始化这个值,在本次运行中再次调用的时候都加1。这个值一般比较大,可以调用right(UUID_SHORT(),9)取后面的若干位。或者,你还可以写成自定义函数,来按需生成这个值。举个例子:

    #1.调用uuid_short()函数
    SELECT UUID_SHORT();
    SELECT UUID_SHORT();
    
    #执行两次得到的值递增的:
    23285634974089216
    23285634974089217
    
    
    #2.创建一个自定义函数,按需获取唯一值:
    CREATE DEFINER=`root`@`%` FUNCTION `GetUuidTest`(SysId     int) RETURNS int(10)
    begin
        declare tmpID  int;            
        set tmpID = 0;          
        #SELECT UUID_SHORT() into  tmpID;  #直接取值
         SELECT concat(SysId,right(UUID_SHORT(),8)) into  tmpID;#SysId和UUID_SHORT()后8位数拼接得到
         return  tmpID;
    end
    
    #3.调用自定义的函数GetUuidTest(int)函数:
    select GetUuidTest(1);
    select GetUuidTest(1);
    select GetUuidTest(2);
    select GetUuidTest(2);
    #得到结果:
    174089233 #1+uuid_short()后8位(74089233)组成
    174089234 #1+uuid_short()后8位(74089234)组成
    274089235 #2+uuid_short()后8位(74089235)组成
    274089236 #3+uuid_short()后8位(74089236)组成
    #uuid_short()值递增,前面在加一个Id,不同的服务器IdSysId不同。
    
    #4.在例子中调用自定义函数GetUuidTest(int)  来插入记录:这时候不需要把Id设置为自增了。
    insert tbl_user set Id=GetUuidTest(1),Name='小熊猫',Age=22;
    insert tbl_user set Id=GetUuidTest(2),Name='小鸭子',Age=21;

      例子中,select * from tbl_user;得到的所有记录为

      image

      欢迎转载,方便的话,请注明出处,谢谢

      作者:子韦一

  • 相关阅读:
    Aptana 由于没有关闭编辑器而导致的启动不起来了。
    postgresql备份导入数据库小记
    [转] js 事件冒泡 阻止
    ruby 取得ip
    [ 转 ] 网页聊天室的原理
    ryby 数组笔记
    第一个rails应用
    vue-router-5-命名路由
    vue-router-4-编程式导航
    vue-router-3-嵌套路由
  • 原文地址:https://www.cnblogs.com/alylee/p/Mysql_UUID.html
Copyright © 2011-2022 走看看