mysql全局唯一ID生成方案(一)

一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由。目前几种可行的主键生成策略有:1. UUID:使用UUID作主键是最简单的方案,但是缺点也是非常明显的。由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建
摘要由CSDN通过智能技术生成

一旦数据库被切分到多个物理结点上,我们将不能再依赖数据库自身的主键生成机制。一方面,某个分区数据库自生成的ID无法保证在全局上是唯一的;另一方面,应用程序在插入数据之前需要先获得ID,以便进行SQL路由。


目前几种可行的主键生成策略有:

1. UUID:使用UUID作主键是最简单的方案,但是缺点也是非常明显的。由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建立索引和基于索引进行查询时都存在性能问题。(UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。)

2. 结合数据库维护一个Sequence表:此方案的思路也很简单,在数据库中建立一个Sequence表,表的结构类似于:

     CREATE  TABLE  ` SEQUENCE ` (  
         `tablename`  varchar (30)  NOT  NULL ,  
         `nextid`  bigint (20)  NOT  NULL ,  
         PRIMARY  KEY  (`tablename`)  
     ) ENGINE=InnoDB


每当需要为某个表的新纪录生成ID时就从Sequence表中取出对应表的nextid,并将nextid的值加1后更新到数据库中以备下次使用。此方案也较简单,但缺点同样明显

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 中,可以通过使用第三方库来生成雪花算法的主键ID。比如,可以使用 Twitter 的 Snowflake 算法来生成主键ID。Snowflake 算法生成的主键ID是一个 64 位的整数,其中高位是时间戳,中间位是机器 ID,低位是序列号。这样可以保证生成的主键ID全局唯一,并且有序递增。在 MySQL 中,可以使用类似下面的 SQL 语句来生成 Snowflake ID: ```sql CREATE TABLE `test` ( `id` bigint(20) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; INSERT INTO `test` (`id`, `name`) VALUES((SELECT next_snowflake_id()), 'test'); ``` 其中,`next_snowflake_id()` 是一个自定义的 MySQL 存储过程,用来生成 Snowflake ID。可以将该存储过程定义为如下: ```sql CREATE DEFINER=`root`@`localhost` FUNCTION `next_snowflake_id`() RETURNS bigint(20) DETERMINISTIC BEGIN DECLARE twepoch BIGINT DEFAULT 1288834974657; -- 2006-03-21 20:50:14 DECLARE machine_id BIGINT DEFAULT 0; DECLARE sequence BIGINT DEFAULT 0; DECLARE last_timestamp BIGINT DEFAULT 0; DECLARE current_timestamp BIGINT DEFAULT 0; SET machine_id = (SELECT FLOOR(RAND() * 1024) % 1024); SET last_timestamp = (SELECT UNIX_TIMESTAMP(NOW(3)) * 1000); REPEAT SET current_timestamp = (SELECT UNIX_TIMESTAMP(NOW(3)) * 1000); IF last_timestamp > current_timestamp THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Clock moved backwards'; END IF; IF last_timestamp = current_timestamp THEN SET sequence = (sequence + 1) & 4095; IF sequence = 0 THEN REPEAT SET current_timestamp = (SELECT UNIX_TIMESTAMP(NOW(3)) * 1000); UNTIL current_timestamp > last_timestamp END REPEAT; END IF; ELSE SET sequence = 0; END IF; SET last_timestamp = current_timestamp; UNTIL sequence != 0 END REPEAT; RETURN ((current_timestamp - twepoch) << 22) | (machine_id << 12) | sequence; END ``` 注意,上述存储过程中的 `machine_id` 变量是随机生成的,可以根据需要进行修改。另外,Snowflake 算法生成的主键ID是一个长整型,需要使用 `BIGINT` 类型来保存。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值