主键迁移概览

本页面介绍了 Spanner 如何使用主键,并针对以下应用场景提供了主键迁移策略:

针对主键的典型方法是使用代理键,例如自动递增的数字。此类主键可让您在当前和未来灵活地优化键,即使业务逻辑发生变化也是如此。在低容量的单实例数据库中,顺序键表现良好。不过在分布式系统中,顺序键的可伸缩性较差。

Spanner 中的顺序主键

在 Spanner 中,每个表都有一个主键,由表的一个或多个列组成。表的主键可唯一标识表中的每一行。Spanner 使用主键在 Spanner 实例中的计算节点之间分布行组(称为“分块”)。这种方式称为范围分片,可让 Spanner 并行执行查询并进行伸缩。

当您拥有主键值非常接近的行(例如单调自动递增键)时,这些行往往会位于同一分块中。这可能会形成热点,其中的分块可以使用所有可用的计算和内存资源。热点可能会导致延迟时间增加,从而可能会导致超时和事务中止。

为了充分利用 Spanner 的可伸缩性并避免热点,Spanner 提供了内置解决方案来替代自动递增主键。

主键建议

Spanner 中主键的默认建议是使用通用唯一标识符版本 4 (UUIDv4) 值。UUID 是使用 122 位随机数据的 128 位标识符。UUIDv4 值具有极大的值范围,无论在何处生成都可有效地保持唯一性。因此,它们非常适合作为 Spanner 中的非热点主键。

您可能需要使用整数主键,因为它们占用的空间更少,并且可以降低您必须进行的应用更改的复杂性。您可以使用正值位反转序列来生成在正 64 位整数空间中均匀分布的唯一主键值。

如需详细了解如何选择主键以避免热点,请参阅架构设计最佳实践

迁移策略

您可以根据应用使用情形和需求部署主键迁移策略。每种迁移策略都需要:

  • 确保迁移的主键的保真度和正确性。
  • 尽量减少下游应用更改,例如更改类型或主键值。
  • 实施 Spanner 最佳实践,以提高性能和可伸缩性。
  • Spanner 只更改生成新数据的方法,不会影响现有数据。

迁移 UUID 键数据库

假设您要从使用 UUID 主键的数据库迁移到 Spanner。在源数据库中将现有 UUID 键配置为字符串,并按原样将其导入到 Spanner 中。UUID 值(尤其是 v4)无论在何处生成都可有效地保持唯一性。

您可以在 Spanner 中使用 GENERATE_UUID() 函数(GoogleSQLPostgreSQL)来迁移 UUID 键数据库。

如需有关迁移 UUID 键数据库的说明,请参阅迁移 UUID 键列

迁移具有顺序键的单实例数据库

假设您要从使用顺序单调键(例如 MySQL 中的 AUTO_INCREMENT、PostgreSQL 中的 SERIAL 或是 SQL Server 或 Oracle 中的标准 IDENTITY 类型)的单实例数据库进行迁移。

配置 Spanner SEQUENCE 对象,以跳过现有键范围内的值并生成新的位反转键。由 Spanner SEQUENCE 对象生成的位反转键始终大于 0,并且在正 64 位整数空间中均匀分布。

如需了解如何迁移具有顺序键的数据库,请参阅迁移自动生成的顺序主键

迁移支持实时割接的顺序键数据库

假设您要从使用顺序单调键的单实例数据库迁移到 Spanner 并支持复制场景,例如,您希望在数据库系统之间进行实时割接。

配置 Spanner SEQUENCE 对象,以跳过源数据库中现有键的整个值范围,并在 Spanner 中生成新的位反转键。由 Spanner SEQUENCE 对象生成的位反转键始终大于 0,但未进行排序。

如需了解如何迁移支持实时割接的数据库,请参阅使用 Spanner 和源数据库

迁移具有应用逻辑依赖项的顺序键数据库

假设您要从使用顺序单调键的数据库进行迁移,并且您的应用逻辑依赖于主键顺序来确定新近度或是对新创建的数据进行排序。

创建一个复合键,将均匀分布的值(例如分片 ID 或哈希)作为第一个组成部分,并将顺序数字作为第二个组成部分来进行组合。这样可保留有序的键值,而不会大规模形成热点。

如需了解如何迁移具有应用逻辑依赖项的顺序键数据库,请参阅迁移您自己的主键

后续步骤

  • 如需查看详细的迁移工作流,请参阅迁移主键