面试官:分库分表后如何生成全局ID?

2024年 1月 17日 55.5k 0

分库分表后就不能使用自增 ID 来作为表的主键了,因为数据库自增 ID 只适用于单机环境,但如果是分布式环境,是将数据库进行分库、分表或数据库分片等操作时,那么数据库自增 ID 就会生成重复 ID,从而导致业务查询上的问题。所以此时,可以使用 UUID 或雪花 ID 来作为全局主键 ID。

1、UUID作为全局ID

UUID(Universally Unique Identifier)是一种全局唯一标识符,它保证在空间和时间上的唯一性。通常由 128 位的数字组成,采用 32 位的十六进制数表示,格式为 8-4-4-4-12 这样的 36 个字符(32 个字母数字字符和 4 个短横线),例如 550e8400-e29b-41d4-a716-446655440000。UUID 在 Java 中的实现如下:

import java.util.UUID;

public class UUIDExample {
    public static void main(String[] args) {
        // Generate a random UUID
        UUID uuid = UUID.randomUUID();
        System.out.println("Random UUID: " + uuid);

        // Convert UUID to string
        String uuidString = uuid.toString();
        System.out.println("UUID as string: " + uuidString);

        // Convert string to UUID
        UUID parsedUuid = UUID.fromString(uuidString);
        System.out.println("Parsed UUID: " + parsedUuid);
    }
}

UUID 存在的问题

虽然 UUID 可以保证全局唯一,但并不推荐使用 UUID 来作为分库分表后的主键 ID,因为 UUID 有两个问题:

  • UUID 太长,且生成效率较低。
  • UUID 没有任何业务含义,不连续且没有任何顺序可言。

2、雪花ID作为全局ID

雪花 ID(Snowflake ID)是一个用于分布式系统中生成唯一 ID 的算法,由 Twitter 公司提出。它的设计目标是在分布式环境下高效地生成全局唯一的 ID,具有一定的有序性。雪花 ID 的结构如下所示(共 64 位):

这四部分代表的含义:

  • 符号位:最高位是符号位,始终为 0,1 表示负数,0 表示正数,ID 都是正整数,所以固定为 0。
  • 时间戳部分:由 41 位组成,精确到毫秒级。可以使用该 41 位表示的时间戳来表示的时间可以使用 69 年。
  • 节点 ID 部分:由 10 位组成,用于表示机器节点的唯一标识符。在同一毫秒内,不同的节点生成的 ID 会有所不同。
  • 序列号部分:由 12 位组成,用于标识同一毫秒内生成的不同 ID 序列。在同一毫秒内,可以生成 4096 个不同的 ID。

Java 版雪花算法实现

接下来,我们来实现一个 Java 版的雪花算法:

public class SnowflakeIdGenerator {

// 定义雪花 ID 的各部分位数
private static final long TIMESTAMP_BITS = 41L;
private static final long NODE_ID_BITS = 10L;
private static final long SEQUENCE_BITS = 12L;
// 定义起始时间戳(可根据实际情况调整)
private static final long EPOCH = 1609459200000L;
// 定义最大取值范围
private static final long MAX_NODE_ID = (1L

相关文章

在一台虚拟机上搭建MGR 9.0集群
众所周知的原因安装PMM2
唯一上榜!OceanBase入选 2023“科创中国”先导技术榜!
MySQL 删除数据表
利用 MySQL 克隆插件搭建主从
MySQL索引前缀长度超限怎么办?这种方法帮你搞定

发布评论