Primärschlüssel migrieren

Auf dieser Seite wird beschrieben, wie Sie Primärschlüssel aus den Tabellen Ihrer Quelldatenbank in Spanner-Datenbanken mit GoogleSQL- und PostgreSQL-Dialekt migrieren. Lesen Sie sich die Übersicht über die Migration von Primärschlüsseln durch, bevor Sie die auf der Seite beschriebenen Schritte ausführen.

Hinweis

  • Um die Berechtigungen zu erhalten, die Sie zum Migrieren von Primärschlüsseln zu Spanner benötigen, bitten Sie Ihren Administrator, Ihnen die IAM-Rolle Cloud Spanner Database Admin (roles/spanner.databaseAdmin) für die Instanz zu gewähren.

Automatisch generierte sequenzielle Schlüssel migrieren

Wenn Sie von einer Datenbank migrieren, die sequenzielle monotone Schlüssel verwendet, z. B. AUTO_INCREMENT in MySQL, SERIAL in PostgreSQL oder den Standardtyp IDENTITY in SQL Server oder Oracle, sollten Sie die folgende allgemeine Migrationsstrategie in Betracht ziehen:

  1. Replizieren Sie in Spanner die Tabellenstruktur aus Ihrer Quelldatenbank mit einem Ganzzahlprimärschlüssel.
  2. Erstellen Sie für jede Spalte in Spanner, die sequenzielle Werte enthält, eine Sequenz und weisen Sie die Funktion GET_NEXT_SEQUENCE_VALUE ( GoogleSQL, PostgreSQL) als Standardwert für die Spalte zu.
  3. Vorhandene Daten mit Originalschlüsseln aus der Quelldatenbank in Spanner migrieren. Sie können das Spanner-Migrationstool oder eine Dataflow-Vorlage verwenden.
    1. Optional können Sie Fremdschlüsseleinschränkungen für alle abhängigen Tabellen festlegen.
  4. Bevor Sie neue Daten einfügen, passen Sie die Spanner-Sequenz so an, dass der Bereich der vorhandenen Schlüsselwerte übersprungen wird.
  5. Fügen Sie neue Daten ein, damit die Sequenz automatisch eindeutige Schlüssel generieren kann.

Beispiel für einen Migrationsworkflow

Im folgenden Code wird die Tabellenstruktur und die zugehörige Sequenz in Spanner mithilfe eines SEQUENCE-Objekts definiert und das Objekt als Standardprimärwert der Zieltabelle festgelegt:

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)
);

Die Option bit_reversed_positive gibt an, dass die von der Sequenz generierten Werte vom Typ INT64 sind, größer als null und nicht sequenziell sind.

Wenn Sie vorhandene Zeilen aus Ihrer Quelldatenbank zu Spanner migrieren, bleiben die Primärschlüssel unverändert.

Bei neuen Einträgen, für die kein Primärschlüssel angegeben ist, ruft Spanner automatisch die Funktion GET_NEXT_SEQUENCE_VALUE(GoogleSQL oder PostgreSQL) auf, um einen neuen Wert abzurufen.

Diese Werte sind gleichmäßig über den Bereich [1, 263] verteilt und es kann zu Kollisionen mit den vorhandenen Schlüsseln kommen. Um dies zu verhindern, können Sie die Sequenz mit ALTER_SEQUENCE (GoogleSQL oder PostgreSQL) konfigurieren, um den Bereich der Werte zu überspringen, der von den vorhandenen Schlüsseln abgedeckt wird.

Angenommen, die Tabelle singers wurde aus PostgreSQL migriert, wobei der Primärschlüssel singer_id vom Typ SERIAL ist. Die folgende PostgreSQL-DDL zeigt die DDL Ihrer Quelldatenbank:

PostgreSQL

CREATE TABLE Singers (
SingerId SERIAL PRIMARY KEY,
Name varchar(1024),
Biography varchar
);

Die Primärschlüsselwerte steigen monoton an. Nach der Migration können Sie den Höchstwert des Primärschlüssels singer_id in Spanner abrufen. Verwenden Sie in Spanner den folgenden Code:

GoogleSQL

SELECT MAX(SingerId) FROM Singers;

PostgreSQL

SELECT MAX(SingerId) FROM Singers;

Angenommen,der zurückgegebene Wert ist 20.000. Sie können die Spanner-Sequenz so konfigurieren, dass der Bereich [1, 21000] übersprungen wird. Die zusätzlichen 1.000 GB dienen als Puffer,um Schreibvorgänge in die Quelldatenbank nach der ersten Migration zu ermöglichen. In Spanner generierte neue Schlüssel stehen nicht im Konflikt mit dem Bereich der Primärschlüssel, die in der PostgreSQL-Quelldatenbank generiert wurden. Verwenden Sie in Spanner den folgenden Code:

GoogleSQL

ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 21000
);

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 21000;

Spanner und Ihre Quelldatenbank verwenden

Sie können das Konzept des Sprungbereichs verwenden, um Szenarien zu unterstützen, in denen entweder Spanner oder Ihre Quelldatenbank Primärschlüssel generiert, z. B. um die Replikation in beide Richtungen für die Notfallwiederherstellung während einer Migrationsumstellung zu ermöglichen.

Dazu werden in beiden Datenbanken Primärschlüssel generiert und die Daten werden zwischen ihnen synchronisiert. Sie können jede Datenbank so konfigurieren, dass Primärschlüssel in nicht überlappenden Schlüsselbereichen erstellt werden. Wenn Sie einen Bereich für Ihre Quelldatenbank definieren, können Sie die Spanner-Sequenz so konfigurieren, dass dieser Bereich übersprungen wird.

Nach der Migration der Anwendung für Musiktitel können Sie beispielsweise die Daten von PostgreSQL zu Spanner replizieren, um die Umstellungszeit zu verkürzen.

Nachdem Sie die Anwendung in Spanner aktualisiert und getestet haben, können Sie die PostgreSQL-Quelldatenbank nicht mehr verwenden und stattdessen Spanner als Datenbank für Updates und neue Primärschlüssel nutzen. Wenn Spanner übernommen wird, können Sie den Datenfluss zwischen den Datenbanken in die PostgreSQL-Instanz umkehren.

Angenommen, Ihre PostgreSQL-Quelldatenbank verwendet SERIAL-Primärschlüssel, also 32-Bit-ganze Zahlen mit Vorzeichen. Spanner-Primärschlüssel sind größere 64‑Bit-Zahlen. Ändern Sie in PostgreSQL die Primärschlüsselspalte in eine 64-Bit-Spalte oder bigint. Verwenden Sie den folgenden Code in Ihrer Quell-PostgreSQL-Datenbank:

PostgreSQL

ALTER TABLE Singers ALTER COLUMN SingerId TYPE bigint;

Sie können der Tabelle in der PostgreSQL-Quelldatenbank eine CHECK-Einschränkung festlegen, damit die Werte des SingerId-Primärschlüssels immer kleiner oder gleich 231-1 sind.

Verwenden Sie den folgenden Code in Ihrer PostgreSQL-Quelldatenbank:

PostgreSQL

ALTER TABLE Singers ADD CHECK (SingerId <= 2147483647);

In Spanner können wir die Sequenz so ändern, dass der Bereich [1, 231-1] übersprungen wird.

Verwenden Sie in Spanner den folgenden Code:

GoogleSQL

ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 2147483647 -- 231-1
);

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 2147483648;

Ihre PostgreSQL-Quelldatenbank generiert immer Schlüssel im 32-Bit-Integerbereich, während Spanner-Schlüssel auf den 64-Bit-Integerbereich beschränkt sind, der größer ist als alle 32-Bit-Integerwerte. So können beide Datenbanken unabhängig voneinander Primärschlüssel generieren, die nicht in Konflikt stehen.

UUID-Schlüsselspalten migrieren

UUIDv4-Schlüssel sind unabhängig von ihrem Ursprung eindeutig. Anderweitig generierte UUID-Schlüssel können mit neuen UUID-Schlüsseln kombiniert werden, die in Spanner generiert wurden.

Hier ist eine allgemeine Strategie zum Migrieren von UUID-Schlüsseln zu Spanner:

  1. Definieren Sie Ihre UUID-Schlüssel in Spanner mit Stringspalten mit einem Standardausdruck. Verwenden Sie die Funktion GENERATE_UUID() (GoogleSQL, PostgreSQL).
  2. Exportieren Sie die Daten aus dem Quellsystem und serialisieren Sie die UUID-Schlüssel als Strings.
  3. Importieren Sie die Primärschlüssel in Spanner.
  4. Optional: Aktivieren Sie Fremdschlüssel.

Hier ein Beispiel für einen Migrationsablauf:

Definieren Sie in Spanner eine UUID-Primärschlüsselspalte als STRING- oder TEXT-Typ und weisen Sie GENERATE_UUID() (GoogleSQL oder PostgreSQL) als Standardwert zu. Migrieren Sie alle Daten aus Ihrer Quelldatenbank zu Spanner. Nach der Migration ruft Spanner GENERATE_UUID() auf, um neue UUID-Werte für die Primärschlüssel zu generieren, wenn neue Zeilen eingefügt werden. Beispiel: Der Primärschlüssel FanClubId erhält einen UUIDv4-Wert, wenn eine neue Zeile in die Tabelle FanClubs eingefügt wird. Verwenden Sie in Spanner den folgenden Code:

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');

Eigene Primärschlüssel migrieren

Ihre Anwendung kann die Reihenfolge der Primärschlüssel verwenden, um zu bestimmen, wie aktuell die Daten sind, oder um neu erstellte Daten zu sequenzieren. Wenn Sie extern generierte sequenzielle Schlüssel in Spanner verwenden möchten, können Sie einen zusammengesetzten Schlüssel erstellen, der einen gleichmäßig verteilten Wert, z. B. einen Hash, als erste Komponente und Ihren sequenziellen Schlüssel als zweite Komponente kombiniert. So können Sie die sequenziellen Schlüsselwerte beibehalten, ohne Hotspots im großen Maßstab zu schaffen. Betrachten Sie den folgenden Migrationsworkflow:

Angenommen, Sie müssen eine MySQL-Tabelle students mit einem Primärschlüssel AUTO_INCREMENT zu Spanner migrieren. Verwenden Sie den folgenden Code in Ihrer MySQL-Quelldatenbank:

MySQL

CREATE TABLE Students (
StudentId INT NOT NULL AUTO_INCREMENT,
Info VARCHAR(2048),
PRIMARY KEY (StudentId)
);

In Spanner können Sie eine generierte Spalte StudentIdHash hinzufügen, indem Sie einen Hashwert der Spalte StudentId erstellen. Beispiel:

StudentIdHash = FARM_FINGERPRINT(CAST(StudentId AS STRING))

Sie können in Spanner den folgenden Code verwenden:

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)
);

Sequenzielle Schlüsselspalten migrieren

Wenn Ihr Quelldatenbanksystem sequenzielle Werte für eine Schlüsselspalte generiert, können Sie in Ihrem Spanner-Schema eine bitweise umgekehrte positive Sequenz (GoogleSQL, PostgreSQL) verwenden, um Werte zu generieren, die sich gleichmäßig über den positiven 64‑Bit-Ganzzahlbereich verteilen. Um zu verhindern, dass die Spanner-Sequenz einen Wert generiert, der sich mit einem migrierten Wert überschneidet, können Sie einen übersprungenen Bereich dafür definieren.

Wenn Sie wissen, dass die Quelldatenbank nur 32-Bit-Ganzzahlen generiert, können Sie beispielsweise den Bereich von 1 bis 4.294.967.296 (2 hoch 32) für die folgenden beiden Sequenzen überspringen:

GoogleSQL

CREATE SEQUENCE MyFirstSequence OPTIONS (
  sequence_kind = "bit_reversed_positive",
  skip_range_min = 1,
  skip_range_max = 4294967296
);

ALTER SEQUENCE MySecondSequence SET OPTIONS (
  skip_range_min = 1,
  skip_range_max = 4294967296
);

PostgreSQL

CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE
  SKIP RANGE 1 4294967296;

ALTER SEQUENCE MySecondSequence SKIP RANGE 1 4294967296;

Wenn Sie IDENTITY-Spalten verwenden, um automatisch Ganzzahlwerte für Ihre Schlüsselspalten zu generieren, können Sie Auslassungsbereiche festlegen:

GoogleSQL

Verwenden Sie den Befehl GENERATED BY DEFAULT AS IDENTITY, um einen Überspringbereich festzulegen:

ALTER DATABASE db SET OPTIONS (
  default_sequence_kind = 'bit_reversed_positive',
);

CREATE TABLE MyFirstTable (
  Id INT64 GENERATED BY DEFAULT AS IDENTITY (SKIP RANGE 1, 4294967296),
  Name STRING(MAX),
) PRIMARY KEY (Id);

ALTER TABLE MyFirstTable ALTER COLUMN Id ALTER IDENTITY SET SKIP RANGE 1, 4294967296;

PostgreSQL

Verwenden Sie den Befehl GENERATED BY DEFAULT AS IDENTITY, um einen Überspringbereich festzulegen:

ALTER DATABASE db
    SET spanner.default_sequence_kind = 'bit_reversed_positive';

CREATE TABLE MyFirstTable (
  Id bigint GENERATED BY DEFAULT AS IDENTITY (SKIP RANGE 1 4294967296),
  Name text,
  PRIMARY KEY (Id)
);

ALTER TABLE MyFirstTable ALTER COLUMN Id SET SKIP RANGE 1 4294967296;

Bitweise umgekehrte Schlüsselspalten migrieren

Wenn Sie Ihre Schlüsselwerte bereits bitweise umgekehrt haben, um Hotspot-Probleme in Ihrer Quelldatenbank zu vermeiden, können Sie auch eine bitweise umgekehrte positive Spanner-Sequenz (GoogleSQL, PostgreSQL) verwenden, um weiterhin solche Werte zu generieren. Um doppelte Werte zu vermeiden, können Sie die Sequenz so konfigurieren, dass der Zähler mit einer benutzerdefinierten Zahl beginnt.

Wenn Sie beispielsweise die Zahlen von 1 bis 1.000 in umgekehrter Reihenfolge verwenden, um Primärschlüsselwerte zu generieren, kann die Spanner-Sequenz ihren Zähler mit einer beliebigen Zahl beginnen,die größer als 10.000 ist. Optional können Sie eine hohe Zahl auswählen, um einen Puffer für neue Schreibvorgänge zu hinterlassen, die nach der Datenmigration in der Quelldatenbank stattfinden. Im folgenden Beispiel beginnen die Zähler bei 11.000:

GoogleSQL

CREATE SEQUENCE MyFirstSequence OPTIONS (
  sequence_kind = "bit_reversed_positive",
  start_with_counter = 11000
);

ALTER SEQUENCE MySecondSequence SET OPTIONS (
  start_with_counter = 11000
);

PostgreSQL

CREATE SEQUENCE MyFirstSequence BIT_REVERSED_POSITIVE
  START COUNTER 11000;

ALTER SEQUENCE MySecondSequence RESTART COUNTER 11000;

Wenn Sie IDENTITY-Spalten verwenden, um automatisch Ganzzahlwerte für Ihre Schlüsselspalten zu generieren, können Sie einen Startzähler festlegen:

GoogleSQL

Verwenden Sie den Befehl GENERATED BY DEFAULT AS IDENTITY, um einen Startzähler festzulegen:

ALTER DATABASE db SET OPTIONS (
  default_sequence_kind = 'bit_reversed_positive',
);

CREATE TABLE MyFirstTable (
  Id INT64 GENERATED BY DEFAULT AS IDENTITY (START COUNTER WITH 11000),
  Name STRING(MAX),
) PRIMARY KEY (Id);

ALTER TABLE MyFirstTable ALTER COLUMN Id ALTER IDENTITY RESTART COUNTER WITH 11000;

PostgreSQL

Verwenden Sie den Befehl GENERATED BY DEFAULT AS IDENTITY, um einen Startzähler festzulegen:

ALTER DATABASE db
    SET spanner.default_sequence_kind = 'bit_reversed_positive';

CREATE TABLE MyFirstTable (
  Id bigint GENERATED BY DEFAULT AS IDENTITY (START COUNTER WITH 11000),
  Name text,
  PRIMARY KEY (Id)
);

ALTER TABLE MyFirstTable ALTER COLUMN Id RESTART COUNTER WITH 11000;

Nächste Schritte