⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/Crazy_shark/article/details/142054196 「每天瞎忙的农民工」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

MySQL 的自增 ID(Auto Increment ID)是数据库表中最常用的主键类型之一。然而,在一些特定的场景下,例如当表中的数据量非常大或者应用场景特殊时,自增 ID 可能会达到其最大值。默认情况下,MySQL 的自增 ID 是一个 BIGINT 类型,这种类型的最大值是 2^63 - 1,即 9223372036854775807,远远超过实际应用中可能达到的数量级。但是,在一些情况下,例如使用了 INT 类型或是数据表长期运行且 ID 的使用不当时,可能会遇到 ID 用尽的问题。

解决方案

1. 更改 ID 列的类型

如果表中的自增 ID 已经接近上限,可以通过更改列的类型来扩展 ID 的范围。

从 INT 扩展到 BIGINT:

ALTER TABLE table_name MODIFY id BIGINT UNSIGNED AUTO_INCREMENT;

BIGINT 类型提供了更大的数值范围,比 INT 类型可以支持更大的 ID 数量。

2. 使用 UUID 替代自增 ID

UUID(通用唯一标识符)是一种具有很高唯一性的标识符,UUID 的长度为 128 位,几乎可以保证全局唯一性。使用 UUID 替代自增 ID 可以避免 ID 用尽的问题,但 UUID 相较于自增 ID 更长,会对存储和性能产生影响。

生成 UUID 的示例:

CREATE TABLE table_name (
id CHAR(36) NOT NULL PRIMARY KEY DEFAULT (UUID()),
name VARCHAR(255)
);

在插入数据时,UUID 会自动生成。

INSERT INTO table_name (name) VALUES ('example_name');

可以使用 MySQL 提供的 UUID() 函数来生成 UUID。

3. 分段 ID 生成策略

这种策略将 ID 生成分成多个段,每个段由不同的生成策略或不同的表来管理。通过这种方式,可以避免单一表的 ID 上限问题。

使用不同的表来生成 ID:

维护多个 ID 生成表,每个表管理一个 ID 段。例如:

CREATE TABLE id_generator_1 (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
INDEX (id)
);

CREATE TABLE id_generator_2 (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
INDEX (id)
);

在插入新数据时,根据需要选择合适的表来生成 ID。

4. 使用合成主键

合成主键(Composite Key)是由多个列组合而成的主键。这种方案可以在需要时使用额外的列来生成唯一标识符,从而避免单一列的 ID 限制。

示例:

CREATE TABLE table_name (
id INT UNSIGNED AUTO_INCREMENT,
other_column VARCHAR(255),
PRIMARY KEY (id, other_column)
);

5. 调整自增步长和偏移量

调整自增列的步长和偏移量,虽然这不能直接解决 ID 用尽问题,但可以优化 ID 的分配和使用效率。

设置步长和偏移量:

ALTER TABLE table_name AUTO_INCREMENT = 1000000;

这将 ID 从一个新的起始值开始。

6. 数据库分片

数据库分片(Sharding)是将数据分布到多个数据库实例上,从而避免单个数据库的自增 ID 达到上限的问题。

示例:

将数据分布到多个数据库实例,每个实例有独立的 ID 生成策略。例如:

CREATE TABLE db1.table_name (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255)
);

CREATE TABLE db2.table_name (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255)
);

在应用层选择合适的数据库实例来插入数据。

总结

  • 更改 ID 列的类型: 将 INT 更改为 BIGINT,以提供更大的 ID 范围。
  • 使用 UUID: 替代自增 ID 以避免 ID 用尽问题,但需要考虑 UUID 的存储和性能影响。
  • 分段 ID 生成策略: 通过维护多个 ID 生成表或段来管理 ID。
  • 使用合成主键: 使用多个列组合成主键,以绕过单一列的限制。
  • 调整自增步长和偏移量: 优化自增列的使用。
  • 数据库分片: 将数据分布到多个数据库实例上,避免单个数据库的 ID 限制。

根据实际情况选择合适的方案,以确保系统的可扩展性和数据的唯一性。

文章目录
  1. 1. 解决方案
    1. 1.1. 1. 更改 ID 列的类型
    2. 1.2. 2. 使用 UUID 替代自增 ID
    3. 1.3. 3. 分段 ID 生成策略
    4. 1.4. 4. 使用合成主键
    5. 1.5. 5. 调整自增步长和偏移量
    6. 1.6. 6. 数据库分片
  2. 2. 总结