• 用MySQL的扩展功能生成全局ID


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

    建立类似下面的表:

    Java代码  收藏代码
    1. CREATE TABLE `tickets64` (  
    2.     `id` bigint(20) unsigned NOT NULL auto_increment,  
    3.     `stub` char(1) NOT NULL default '',  
    4.     PRIMARY KEY  (`id`),  
    5.     UNIQUE KEY `stub` (`stub`)  
    6. ) ENGINE=MyISAM;  

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

    Java代码  收藏代码
    1. REPLACE INTO `tickets64` (`stub`) VALUES ('a');  
    2. SELECT LAST_INSERT_ID();  

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

    Java代码  收藏代码
    1. +--------+------+  
    2. | id     | stub |  
    3. +--------+------+  
    4. 1      |    a |  
    5. +--------+------+  

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

    更棒的方法:

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

    Java代码  收藏代码
    1. CREATE TABLE `sequence` (  
    2.     `name` varchar(50) NOT NULL,  
    3.     `id` bigint(20) unsigned NOT NULL DEFAULT '0',  
    4.     PRIMARY KEY (`name`)  
    5. ) ENGINE=InnoDB;  

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

    Java代码  收藏代码
    1. INSERT INTO `sequence` (`name`) VALUES   
    2. ('users'), ('photos'), ('albums'), ('comments');  

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

    Java代码  收藏代码
    1. UPDATE `sequence` SET `id` = LAST_INSERT_ID(`id` + 1) WHERE `name` = 'photos';  
    2. SELECT LAST_INSERT_ID();  

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

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

    Java代码  收藏代码
    1. INSERT INTO `sequence` (`name`) VALUES('new_business') ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id` + 1);  
    2. 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: 这个方法更容易解决单点问题,也不局限于两个服务器,只要对不同的服务器设置不同的初始值(但必须是连续的),然后将增量变为服务器数就行了。 


    注:此文章来源于网络:http://www.zolazhou.com/posts/primary-key-selection-in-database-partition-design/

  • 相关阅读:
    [如何构建自己的轮式移动机器人系统·从入门到放弃]机器人底层篇
    Readme.txt
    [MATLAB&SIMULINK] 如何提取并处理Simscape Power System 中powergui的谐波分析数据
    记录2016年12月11日
    [深度强化学习] blog翻译使用Keras与Gym仿真环境进行深度Q学习(DQL)
    使用PARL与Gym仿真环境进行深度Q学习(DQL)
    Telerik控件使用Expression_DarkTheme后引发Combobx下拉问题
    [Win系统][临时方案]系统任务管理器不能使用临时性解决方案
    [Visual Studio]重置开发环境
    WPF中使用DataGrid后,里面的Button的Command不响应的问题
  • 原文地址:https://www.cnblogs.com/douzilovetiger/p/7614769.html
Copyright © 2020-2023  润新知