本页介绍了 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()
函数(GoogleSQL、PostgreSQL)来迁移 UUID 键数据库。
如需了解如何迁移 UUID 键数据库,请参阅迁移 UUID 键列。
迁移具有顺序键的单实例数据库
假设您要从使用顺序单调键(例如 MySQL 中的
AUTO_INCREMENT
、PostgreSQL 中的 SERIAL
或 SQL Server 或 Oracle 中的标准 IDENTITY
类型)的单实例数据库进行迁移。
配置 Spanner SEQUENCE
对象以跳过现有键范围内的值,并生成新的位反转键。Spanner SEQUENCE
对象生成的按位反转键始终大于零,并且均匀分布在正 64 位整数空间中。
如需了解如何迁移具有序列键的数据库,请参阅迁移自动生成的序列主键。
迁移支持实时切换的顺序键数据库
假设您要从使用顺序单调键的单实例数据库迁移到 Spanner 并支持复制场景,例如,您希望在数据库系统之间进行实时切换。
配置 Spanner SEQUENCE
对象,以跳过源数据库中现有键的整个值范围,并在 Spanner 上生成新的位反转键。Spanner SEQUENCE
对象生成的按位反转键始终大于零,但没有排序。
如需了解如何迁移支持实时切换的数据库,请参阅 使用 Spanner 和源数据库。
迁移具有应用逻辑依赖项的顺序键数据库
假设您要从使用顺序单调键的数据库进行迁移,并且您的应用逻辑依赖于主键顺序来确定新近性或对新创建的数据进行排序。
创建一个复合键,将均匀分布的值(例如分片 ID 或哈希)作为第一个组件,将序列号作为第二个组件。这样可以保留有序键值,而不会造成大规模热点。
如需了解如何迁移具有应用逻辑依赖项的顺序键数据库,请参阅迁移您自己的主键。
后续步骤
- 如需查看详细的迁移工作流程,请参阅迁移主键。