flickr 的全局主键生成方案

来源:互联网 发布:mac幼圆字体下载 编辑:程序博客网 时间:2024/06/06 17:27

flickr 的全局主键生成方案

类似于京东的数据库设计,我们的用户分库有 Shop_1/2/3/4 … 那么uid怎样生成?

现在的做法是在用一张索引表 Shop_share.user_index 取其自增主键,insert_id 便是uid。但缺点是,有单点负载的风险。

flickr提供了一个扩展的更好的方案: 他们把 user_index 抽出一个专门用作生成 uid 的表,例如取名叫 uid_sequence,并拆成若干的字表,自增步长设置为2(机器数目),这两张表可以放在不同的物理机器上。 其中一个表负责生成奇数uid,另一个负责生成偶数uid

uid_sequence 表的设计

比如创建64位的自增id:

CREATE TABLE `uid_sequence` (    `id` bigint(20) unsigned NOT NULL auto_increment,    `stub` char(1) NOT NULL default '',    PRIMARY KEY  (`id`),    UNIQUE KEY `stub` (`stub`)  ) ENGINE=MyISAM;

SELECT * from uid_sequence 输出:

+-------------------+------+  | id                | stub |  +-------------------+------+  | 72157623227190423 |    a |  

如果我需要一个全局的唯一的64位uid,则执行:

REPLACE INTO uid_sequence (stub) VALUES ('a');  SELECT LAST_INSERT_ID();  
  • 用 REPLACE INTO 代替 INSERT INTO 的好处是避免表行数太大,还要另外定期清理。
  • stub 字段要设为唯一索引,这个 sequence 表只有一条纪录,但也可以同时为多张表生成全局主键,例如 user_ship_id。除非你需要表的主键是连续的,那么就另建一个 user_ship_id_sequence 表。
  • 经过实际对比测试,使用 MyISAM 比 Innodb 有更高的性能。

这里flickr使用两台数据库作为自增序列生成,通过这两台机器做主备和负载均衡。

TicketServer1: auto-increment-increment = 2  auto-increment-offset = 1    TicketServer2:auto-increment-increment = 2  auto-increment-offset = 2  


MySQL 中 last_insert_id() 的并发问题

因为是两条SQL语句,所以这两条语句之间会不会有并发问题?

答案是不会,因为 last_insert_id() 是 Connection 级别的,是单个连接客户端里执行的insert语句最近一条,客户端之间是不会影响,没必要锁定和事务处理。

原创粉丝点击