`
gallop_liu
  • 浏览: 110133 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

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

阅读更多

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

 

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

分享到:
评论

相关推荐

    Mysql全局ID生成方法

    既然要sharding,那么不可避免的要讨论到sharding key问题,在有些业务系统中,必须保证sharding key全局唯一,比如存放商品的数据库等,那么如何生成全局唯一的ID呢,下文将从DBA的角度介绍几种常见的方案。...

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

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

    全局唯一ID生成

    除此之外,还有一种基于分布式数据库的解决方案,如MySQL的UUID函数,它可以生成128位的UUID,保证全局唯一。但UUID的字符串形式较长,可能不适合某些需要节省存储空间的场景。 另一种流行的分布式ID生成器是...

    Go-GoMySQL实现的ID生成服务

    在现代分布式系统中,生成全局唯一的ID是一项基本且重要的任务。本文将深入探讨如何利用Go语言和MySQL数据库实现一个高性能、高可用的ID生成服务。该服务具备良好的扩展性,保证了ID的唯一性,并且通过HTTP接口提供...

    50_一个关键的问题!分库分表之后全局id咋生成?.zip

    然而,随着数据的分散,一个新的挑战也随之而来:如何在分库分表后生成全局唯一ID(Global Unique ID,GID)。这个问题在标题“50_一个关键的问题!分库分表之后全局id咋生成?”中被明确提出。下面将详细探讨这个...

    Go-GolangMysql实现的分布式ID生成服务

    在分布式系统中,生成全局唯一且递增的ID是常见的需求,这有助于追踪和管理大量数据。Go语言作为现代的、高性能的编程语言,被广泛应用于构建分布式系统。本篇文章将详细探讨如何使用Go和MySQL来实现一个分布式ID...

    donkeyid, php扩展,64位自增id生成器.zip

    `donkeyid`扩展的核心功能在于它提供了一种高性能的ID生成机制。在传统的MySQL自增ID方案中,当达到最大值时,ID会回绕,这在分布式系统中可能导致冲突。而`donkeyid`通过算法优化,避免了这个问题,它可以在多台...

    应用级自增ID的生成

    在IT行业中,尤其是在数据库管理和分布式系统设计中,生成全局唯一标识符(ID)是一项至关重要的任务。本话题将深入探讨“应用级自增ID的生成”,这是一个确保每个新记录都有独特标识符的策略,这对于数据的正确性和...

    全局自增ID设计方案

    因此,如何设计一种高效的全局自增ID生成方案成为了一个重要的技术问题。 #### 方案调研与实践 **一、数据库自增ID方案** ##### Flicker方案解析 Flicker提出的解决方案是利用MySQL自身的auto_increment特性来...

    分布式id生成详解.pdf

    - 使用数据库的自动递增功能,如MySQL的`auto_increment`。优点是简单且有序,但并发性差,数据库压力大,一旦数据库故障,ID生成将受影响,还存在数量泄露的风险。 - 优化方案包括数据库水平拆分,设置不同初始值...

    分布式架构系统生成全局唯一序列号的一些思路对比分析.docx

    总结来说,分布式架构系统生成全局唯一序列号的方法多种多样,包括但不限于Flickr方案的优化版、基于AtomicLong的号段管理和Snowflake算法等。选择哪种方案取决于具体业务需求、系统规模以及对性能、扩展性的要求。...

    分布式id公开课.pptx

    分布式ID是现代大规模分布式系统中不可或缺的一个组成部分,它主要用于为分布式环境中的每个实体生成全局唯一且具有特定属性的标识符。以下将详细讲解分布式ID的相关知识点: 1. **UUID(Universally Unique ...

    MySQL分表自增ID问题的解决方法

    在获取锁失败时,可以设置超时并重试,确保在高并发环境下也能安全地生成全局唯一的ID。这种方式避免了MySQL的自增锁问题,提高了并发性能。 这两种方法都旨在解决MySQL分表后生成唯一ID的挑战。使用Redis生成ID...

    php+mysql留言板原码

    PHP是一种广泛使用的开源脚本语言,主要用于Web开发,可以嵌入到HTML中,用于动态生成网页内容。MySQL则是一款关系型数据库管理系统,以其高效、稳定和易用性在Web开发领域占据重要地位。这个"php+mysql留言板原码...

    php+mysql 留言板 (超完整功能齐全)代码详细

    2. **PHP连接MySQL**:使用`mysqli`或`PDO`扩展在PHP中建立与MySQL数据库的连接。 3. **SQL查询**:编写SQL语句进行数据插入(INSERT)、查询(SELECT)、更新(UPDATE)和删除(DELETE)操作。 4. **表单处理**:...

    mysql热备及mysql主从配置

    MySQL双机备份则是在热备基础上的进一步扩展,通常包括两个主数据库和一个或多个从数据库,形成一个更健壮的高可用集群。双主复制允许任何一台服务器都可以接受写操作,当一台服务器出现故障时,另一台可以无缝接管...

    golang(gin)整合mysql,整合redis通用脚手架

    8. **API文档**:生成清晰的API文档,可以使用Swagger等工具。 通过以上步骤,你将能够构建一个完整的、集成了Gin、MySQL和Redis的后端应用。这个通用脚手架将为你提供一个坚实的基础,方便后续功能的扩展和维护。...

Global site tag (gtag.js) - Google Analytics