本文档提供了从哪个位置迁移主键的说明 将源数据库表复制到 Spanner。您必须熟悉 此处提供的信息 主键迁移概览。
准备工作
-
如需获取将主键迁移到 Spanner 所需的权限, 请让管理员授予您 实例上的 Cloud Spanner Database Admin (
<ph type="x-smartling-placeholder">roles/spanner.databaseAdmin
) IAM 角色。
迁移自动生成的序列键
如果要从使用顺序单调键的数据库进行迁移,
例如 AUTO_INCREMENT
在 MySQL 中,SERIAL
或者 SQL Server 或 Oracle 中的标准 IDENTITY
类型。
请考虑采用以下总体迁移策略:
- 在 Spanner 中,从 您的源数据库(使用整数主键)。
- 对于 Spanner 中包含顺序值的每一列,
创建一个序列并分配
GET_NEXT_SEQUENCE_VALUE
(GoogleSQL、PostgreSQL) 函数作为列的默认值。 - 使用原始密钥从来源迁移现有数据 数据库导入 Spanner。您可以考虑使用 Spanner 迁移工具或 Dataflow 模板。
- 您还可以选择创建 外键约束 依赖表
- 在插入新数据之前,请调整 Spanner 序列,以跳过现有键值对的范围。
- 插入新数据,使序列能够自动生成唯一键。
迁移工作流示例
以下代码定义了
使用
SEQUENCE
对象,并设置该对象
用作目标表的默认主值:
GoogleSQL
CREATE SEQUENCE singer_id_sequence OPTIONS ( SequenceKind = 'bit_reversed_positive' ); CREATE TABLE Singers ( SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)), Name STRING(1024), Biography STRING(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( AlbumId INT64, SingerId INT64, AlbumName STRING(1024), SongList STRING(MAX), CONSTRAINT FK_singer_album FOREIGN KEY (SingerId) REFERENCES Singers (SingerId) ) PRIMARY KEY (AlbumId);
PostgreSQL
CREATE SEQUENCE SingerIdSequence BIT_REVERSED_POSITIVE; CREATE TABLE Singers ( SingerId BIGINT DEFAULT nextval('SingerIdSequence') PRIMARY KEY, Name VARCHAR(1024) NOT NULL, Biography TEXT ); CREATE TABLE Albums ( AlbumId BIGINT PRIMARY KEY, SingerId BIGINT, AlbumName VARCHAR(1024), SongList TEXT, CONSTRAINT FK_singer_album FOREIGN KEY (SingerId) REFERENCES Singers (SingerId) );
bit_reversed_positive
选项表示
序列的类型为 INT64
、大于零,并且不依序。
将现有行从源数据库迁移到 则主键保持不变。
对于未指定主键的新插入,Spanner
调用该方法来自动检索新值,
GET_NEXT_SEQUENCE_VALUE()
(GoogleSQL
或 PostgreSQL)
函数。
这些值在 [1, 263]
范围内均匀分布,
可能会与现有密钥发生冲突。为防止出现这种情况,您可以
使用 ALTER_SEQUENCE
(GoogleSQL 或 PostgreSQL)配置序列,以跳过
现有键覆盖的值。
假设 singers
表是从 PostgreSQL 迁移而来,该表的主键为
singer_id
的类型为 SERIAL
。以下 PostgreSQL 显示了您的源数据库 DDL:
PostgreSQL
CREATE TABLE Singers ( SingerId SERIAL PRIMARY KEY, Name varchar(1024), Biography varchar );
主键值单调递增。迁移后
您可以在 Spanner 上检索主键 singer_id
的最大值。
在 Spanner 中使用以下代码:
GoogleSQL
SELECT MAX(SingerId) FROM Singers;
PostgreSQL
SELECT MAX(SingerId) FROM Singers;
假设返回值为 20,000。你可以配置 Spanner
序列来跳过 [1, 21000]
范围。额外添加的 1,000 个
缓冲区,以适应初始迁移后对源数据库的写入。
在 Spanner 中生成的新键与
源 PostgreSQL 数据库中生成的主键。
在 Spanner 中使用以下代码:
GoogleSQL
ALTER SEQUENCE SingerIdSequence SET OPTIONS ( skip_range_min = 1, skip_range_max = 21000 );
PostgreSQL
ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 21000;
使用 Spanner 和源数据库
您可以使用跳过范围概念来支持以下场景: 或者,您的源数据库会生成主键,例如,要在 迁移割接期间的灾难恢复方向。
为了支持这一点,两个数据库都会生成主键,数据 会在它们之间同步您可以将每个数据库配置为 键的范围不同。定义来源范围时 您可以配置 Spanner 序列以跳过该数据库, 范围。
例如,在迁移音乐曲目应用后,请复制 将数据从 PostgreSQL 传输到 Spanner, 切换。
在 Spanner 上更新并测试应用后,您可以 停止使用源 PostgreSQL 数据库并使用 Spanner, 使其成为更新和新主键的记录系统。 Spanner 接管后,您可以将流程逆转 将数据整合到 PostgreSQL 实例中。
假设您的源 PostgreSQL 数据库使用 SERIAL
主键,它们是
32 位有符号整数。Spanner 主键为 64 位更大
数字。在 PostgreSQL 中,将主键列更改为 64 位列,
或 bigint
。在源 PostgreSQL 数据库中使用以下代码:
PostgreSQL
ALTER TABLE Singers ALTER COLUMN SingerId TYPE bigint;
您可以为源 PostgreSQL 数据库中的表设置 CHECK
限制条件
,以确保 SingerId
主键的值始终小于或
等于 231-1
。
在源 PostgreSQL 数据库中使用以下代码:
PostgreSQL
ALTER TABLE Singers ADD CHECK (SingerId <= 2147483647);
在 Spanner 中,我们可以更改序列以跳过 [1, 231-1]
范围。
在 Spanner 中使用以下代码:
GoogleSQL
ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 2147483647 -- 231-1
);
PostgreSQL
ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 2147483648;
源 PostgreSQL 数据库始终生成 32 位整数的密钥 空间,而 Spanner 键被限制为 64 位整数 大于所有 32 位整数值。这样可以确保 数据库可以独立生成不冲突的主键。
迁移 UUID 键列
无论 UUIDv4 密钥是在何处生成的,它们实际上都是唯一的。 在其他位置生成的 UUID 密钥与 Spanner。
请考虑以下总体迁移策略 使用 UUID 键导入 Spanner:
- 在 Spanner 中使用包含
默认表达式。使用
GENERATE_UUID()
函数(GoogleSQL、 PostgreSQL)。 - 从源系统导出数据,将 UUID 键序列化为字符串。
- 将主键导入 Spanner。
- 可选:启用外键。
以下是一个迁移工作流示例:
在 Spanner 中,将 UUID 主键列定义为 STRING
,或
TEXT
类型,并将 GENERATE_UUID()
(GoogleSQL 或 PostgreSQL)指定为默认值。将所有
将数据从源数据库传输到 Spanner。迁移后,
将插入新行,Spanner 会调用 GENERATE_UUID()
以
为主键生成新的 UUID 值。例如,主键
在表 FanClubs
中插入新行时,FanClubId
会获取 UUIDv4 值。
在 Spanner 中使用以下代码:
GoogleSQL
CREATE TABLE Fanclubs ( FanClubId STRING(36) DEFAULT (GENERATE_UUID()), ClubName STRING(1024), ) PRIMARY KEY (FanClubId); INSERT INTO FanClubs (ClubName) VALUES ("SwiftFanClub");
PostgreSQL
CREATE TABLE FanClubs ( FanClubId TEXT DEFAULT spanner.generate_uuid() PRIMARY KEY, ClubName VARCHAR(1024) ); INSERT INTO FanClubs (ClubName) VALUES ('SwiftFanClub');
迁移您自己的主键
您的应用程序可能会依靠主键顺序来确定 data 为 或 ,则会对新创建的数据进行排序。要使用外部生成的 顺序键,则可以创建复合键 该方法将均匀分布的值(例如哈希值)组合起来,作为第一个 组件,并将顺序键用作第二个组件。这样, 则可以保留顺序键值,而不会大规模创建热点。 请考虑以下迁移工作流:
假设您需要迁移一个 MySQL 表 students
,该表为
分配给 Spanner 的 AUTO_INCREMENT
主键。
在源 MySQL 数据库中使用以下代码:
MySQL
CREATE TABLE Students ( StudentId INT NOT NULL AUTO_INCREMENT, Info VARCHAR(2048), PRIMARY KEY (StudentId) );
在 Spanner 中,您可以通过创建以下内容的哈希值来添加生成的列 StudentIdHash
StudentId
列。
例如:
StudentIdHash = FARM_FINGERPRINT(CAST(StudentId AS STRING))
您可以在 Spanner 中使用以下代码:
GoogleSQL
CREATE TABLE student ( StudentIdHash INT64 AS (FARM_FINGERPRINT(cast(StudentId as string))) STORED, StudentId INT64 NOT NULL, Info STRING(2048), ) PRIMARY KEY(StudentIdHash, StudentId);
PostgreSQL
CREATE TABLE Student ( StudentIdHash bigint GENERATED ALWAYS AS (FARM_FINGERPRINT(cast(StudentId AS varchar))) STORED, StudentId bigint NOT NULL, Info varchar(2048), PRIMARY KEY (StudentIdHash, StudentId) );