由于改用 PostgreSQL 数据库,本章内容仅作知识扩展。项目使用的相关知识请阅读《前置知识:使用 XID 作为分布式ID》。

为什么需要分布式ID

由于我们的商城系统是分布式的,同时,数据库也将是集群。这就要求对数据库中每条记录的主键提出了要求:如果还是使用简单的、数据库自带的自增值作为主键,那将造成集群内的ID重复(当然,可以通过设置集群内每个 MySQL 的自增起始值和步长规避)。

有哪些分布式ID的实现

常用的有:

  • UUID

  • Redis 分配

  • xid

  • 以及其它

为什么选用雪花算法

我们的商城专题将选用雪花算法,主要是由 MySQL 特性决定的。其实一开始选定的是 xid:

  • 专题构想之初,计划使用的 PostgreSQL 数据库,它已经提供了 xid 数据类型。即使不使用 xid 数据类型而使用 CHAR 类型,PostgreSQL 也不存在 MySQL 的问题

    • 整数类型的索引效率远高于字符串
    • 具有排序的、递增数据的索引最为高效
  • UUID:它是无序的字符串。对于 MySQL 来说,索引效率非常低下

  • xid:它是有序的且递增的,但很遗憾,它也是字符串。对于 MySQL 来说,索引效率中等

  • 雪花算法:它是有序递增的长整型,对 MySQL 索引最友好

rust 的雪花算法

使用 rs-snowflake 即可方便地在 rust 使用雪花算法来生成分布式ID,它的依赖如下:

[dependencies]
rs-snowflake="0.6"

使用起来也非常方便,只需要传入机器ID和节点ID即可:

use snowflake::SnowflakeIdGenerator;
fn main() {
   let mut id_generator_generator = SnowflakeIdGenerator::new(1, 1);
   let id = id_generator_generator.real_time_generate();
}

或者

use snowflake::SnowflakeIdBucket;
fn main() {
   let mut id_generator_bucket = SnowflakeIdBucket::new(1, 1);
   let id = id_generator_bucket.get_id();
}