Verwaltung der Standardwerte für Primärschlüssel

Auf dieser Seite werden Strategien beschrieben, mit denen Sie Primärschlüsselwerte in Ihrer Tabelle mithilfe von Standardwertausdrücken generieren können. Die Informationen auf dieser Seite gelten sowohl für Datenbanken im GoogleSQL-Dialekt als auch für Datenbanken im PostgreSQL-Dialekt. Diese Strategien bieten folgende Vorteile:

  • Hotspots vermeiden
  • Migrationen von anderen Datenbanken vereinfachen
  • Kapseln Sie die Schlüssellogik in der Datenbank ein, damit Sie sich nicht um die Verwaltung in Ihrer Anwendung kümmern müssen.
  • In den meisten Fällen müssen Sie keine eigenen Sequenzen mehr erstellen und verwalten.

Methoden zum automatischen Generieren von Primärschlüsseln

Wenn Sie Primärschlüsselwerte automatisch generieren möchten, können Sie in einer Spalte mit DEFAULT-Ausdrücken die folgenden Strategien verwenden:

  • Eine UUID-Funktion, die UUID-Werte der Version 4 generiert.
  • Ein Schemaobjekt, SEQUENCE, mit einer bit_reversed_positive-Option. SEQUENCE ist sowohl für GoogleSQL als auch für PostgreSQL verfügbar.

Methoden zum automatischen Generieren von Primärschlüsseln

In diesem Abschnitt wird beschrieben, wie Sie automatisch UUIDs und bitweise umgekehrte Sequenzen generieren, die als Primärschlüsselwerte verwendet werden.

Universally Unique Identifier (UUID)

Spanner kann automatisch einen UUID-Version-4-String generieren, der als Primärschlüssel verwendet wird. UUIDs eignen sich gut für neue Anwendungen und Tabellen mit vielen Zeilen. Sie sind ungefähr gleichmäßig über den Schlüsselbereich verteilt, was Hotspots in großem Umfang verhindert. Bei der UUID-Generierung kann eine große Anzahl von Werten (2122) erstellt werden und jeder Wert ist eindeutig. Für eine Kollisionswahrscheinlichkeit von 50% wären beispielsweise 2, 71 × 1018 Werte erforderlich, was einer Milliarde pro Sekunde über 86 Jahre entspricht. So werden eindeutige Werte sichergestellt, wenn Sie sie in großen Tabellen verwenden. UUIDs sind eindeutig, unabhängig davon, ob Sie sie in der Datenbank oder im Client generieren. Wir empfehlen, nach Möglichkeit UUIDs zu verwenden. Sie können client- und Spanner-generierte UUIDs in derselben Tabelle gefahrlos mischen, wenn die clientgenerierten UUIDs gemäß RFC 4122 in Kleinbuchstaben serialisiert werden.

Wenn für eine Spalte Standardwerte erforderlich sind, können Sie diese mit der Funktion GENERATE_UUID generieren. Im folgenden Beispiel wird eine Tabelle erstellt, in der die Schlüsselspalte FanId den Standardwert GENERATE_UUID in der Wertespalte hat. Im Beispiel werden 36 Zeichen für die GoogleSQL-STRING- und PostgreSQL-varchar-Attribute verwendet, da UUIDs 36 Zeichen haben. Wenn Sie die Anweisung INSERT with THEN RETURN verwenden, um Daten in die Tabelle Fans einzufügen, generiert und gibt GENERATE_UUID einen UUID-Wert für FanId zurück.

GoogleSQL

CREATE TABLE Fans (
  FanId STRING(36) DEFAULT (GENERATE_UUID()),
  Name STRING(MAX),
) PRIMARY KEY (FanId);

PostgreSQL

CREATE TABLE Fans (
  FanId varchar(36) DEFAULT spanner.generate_uuid(),
  Name text,
  PRIMARY KEY (FanId)
);

GoogleSQL

INSERT INTO Fans (Name) VALUES ('Melissa Garcia')
THEN RETURN FanId;

PostgreSQL

INSERT INTO fans (name) VALUES ('Melissa Garcia')
RETURNING (fanid);

Diese Anweisung gibt ein Ergebnis zurück, das in etwa so aussieht:

FanId
6af91072-f009-4c15-8c42-ebe38ae83751

Weitere Informationen zur Funktion GENERATE_UUID() finden Sie in der GoogleSQL- oder PostgreSQL-Referenz.

IDENTITY Spalten

Mit IDENTITY-Spalten können Sie automatisch Ganzzahlwerte für Schlüssel- und Nicht-Schlüsselspalten generieren. Bei IDENTITY-Spalten müssen Nutzer keine zugrunde liegende Sequenz manuell verwalten oder die Beziehung zwischen der Spalte und der zugrunde liegenden Sequenz verwalten. Wenn eine automatisch generierte Identitätsspalte gelöscht wird, wird auch die zugrunde liegende Sequenz automatisch gelöscht.

Sie können IDENTITY-Spalten verwenden, indem Sie entweder beim Generieren der Sequenz einen Startwert für Ganzzahlen angeben oder Spanner die Ganzzahlsequenz für Sie generieren lassen. Wenn Sie einen Ganzzahlwert für den Anfang angeben möchten, müssen Sie die Option START COUNTER WITH und einen positiven INT64-Startwert verwenden. Spanner verwendet diesen Wert, um den nächsten Wert für seinen automatisch generierten internen Sequenzzähler festzulegen, und kehrt den Wert in Bitfolge um, bevor er in diese Spalte eingefügt wird.

In Spanner werden IDENTITY-Spalten sowohl in GoogleSQL als auch in PostgreSQL unterstützt.

GoogleSQL

Im folgenden Beispiel wird gezeigt, wie Sie mit IDENTITY-Spalten eine automatisch generierte Primärschlüsselspalte vom Typ „Integer“ für SingerId erstellen, wenn Sie mit dem Befehl CREATE TABLE eine neue Tabelle erstellen:

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

Sie können den Start des Zählers für die Spalte auch mit der Option START_WITH_COUNTER angeben. Im folgenden Beispiel wird eine automatisch generierte Ganzzahlspalte für SingerId mit bitweise umgekehrten positiven Werten und einem internen Zähler erstellt, der bei 1.000 beginnt.

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

PostgreSQL

Im folgenden Beispiel wird gezeigt, wie Sie mit IDENTITY-Spalten eine automatisch generierte Ganzzahlspalte für SingerId erstellen, wenn Sie mit dem Befehl CREATE TABLE eine neue Tabelle erstellen:

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name text,
  PRIMARY KEY (SingerId)
);

Sie können den Start des Zählers für die Spalte auch mit der Option START COUNTER WITH angeben. Im folgenden Beispiel wird für SingerId eine automatisch generierte Ganzzahlspalte erstellt, die bitinvertierte positive Werte generiert. Der interne Zähler beginnt vor der Bitumkehrung bei 1.000.

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name text,
  PRIMARY KEY (SingerId)
);

SERIAL und AUTO_INCREMENT

Spanner unterstützt SERIAL in PostgreSQL und AUTO_INCREMENT in GoogleSQL. Dies sind DDL-Aliasse für IDENTITY-Spalten, die zum Erstellen eindeutiger Ganzzahlspalten verwendet werden. Sie müssen zuerst die Datenbankoption default_sequence_kind festlegen, bevor Sie SERIAL oder AUTO_INCREMENT verwenden können. Mit der folgenden SQL-Anweisung können Sie die default_squence_kind-Option der Datenbank festlegen:

GoogleSQL

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

CREATE TABLE Singers (
  id INT64 AUTO_INCREMENT PRIMARY KEY,
  name STRING(MAX),
)

PostgreSQL

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

CREATE TABLE Singers (
  id serial PRIMARY KEY,
  name text
);

Da SERIAL und AUTO_INCREMENT IDENTITY-Spalten zugeordnet sind, werden sie bei der Serialisierung des Schemas nicht angezeigt. Für dieses Schema würde GetDatabaseDDL Folgendes ausgeben:

GoogleSQL

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

CREATE TABLE Singers (
  id INT64 GENERATED BY DEFAULT AS IDENTITY,
  name STRING(MAX),
) PRIMARY KEY (id);

PostgreSQL

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

CREATE TABLE Singers (
  id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  name character varying,
  PRIMARY KEY(id)
);

Bit-Reversed-Sequenz

Eine Bit-Reverse-Sequenz ist ein Schemaobjekt, das eine Sequenz von Ganzzahlen generiert und diese Bit-Reverse-codiert. Dieses Objekt verwendet die Bitumkehrung auf einem privaten, internen Spanner-Zähler, um für Eindeutigkeit zu sorgen. Die daraus resultierenden bitweise umgekehrten Werte tragen dazu bei, Hotspots in großem Umfang zu vermeiden, wenn sie in einem Primärschlüssel verwendet werden.

In Spanner verwenden Sie SEQUENCE-DDL-Anweisungen zusammen mit dem bit_reversed_positive-Attribut, um eine Sequenz zu erstellen, zu ändern oder zu löschen, die bitweise umgekehrte positive Werte erzeugt (GoogleSQL oder PostgreSQL).

Jede Sequenz verwaltet eine Reihe interner Zähler und verwendet diese, um einen Wert zu generieren. Der Sequenzzähler liefert die Eingabe für den Bitumkehralgorithmus.

Wenn Sie eine Spalte mit einem DEFAULT-Ausdruck definieren, der die GoogleSQL-Funktion GET-NEXT-SEQUENCE-VALUE oder die PostgreSQL-Funktion nextval als Standardwert verwendet, ruft Spanner die Funktion automatisch auf und fügt die bitreversierten Ausgabewerte in die Spalte ein. Bit-inverse Sequenzen sind besonders nützlich für Primärschlüssel, da sie gleichmäßig über den Schlüsselbereich verteilt sind und daher keine Hotspots verursachen.

Im folgenden Beispiel wird gezeigt, wie Sie eine bitreversierte Sequenz und eine Tabelle erstellen, in deren Schlüsselspalte die Sequenz als Standardwert verwendet wird:

GoogleSQL

CREATE SEQUENCE SingerIdSequence OPTIONS (
  sequence_kind="bit_reversed_positive"
);

CREATE TABLE Singers (
  SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
  Name STRING(MAX),
  Rank INT64,
) PRIMARY KEY (SingerId);

PostgreSQL

CREATE SEQUENCE SingerIdSequence bit_reversed_positive;

CREATE TABLE Singers (
  SingerId bigint DEFAULT nextval('SingerIdSequence'),
  Name text,
  PRIMARY KEY (SingerId)
);

Mit der folgenden SQL-Anweisung können Sie den Primärschlüsselwert einfügen und zurückgeben:

GoogleSQL

INSERT INTO Singers (Name) VALUES ('Melissa Garcia')
THEN RETURN SingerId;

PostgreSQL

INSERT INTO Singers (name) VALUES ('Melissa Garcia')
RETURNING (SingerId);

Diese Anweisung gibt ein Ergebnis wie das folgende zurück:

SingerId
3458764513820540928

Szenarien für die Verwendung von UUIDs und Sequenzen als Standardwerte für Primärschlüssel

Zu den Szenarien für UUIDs und Sequenzen gehören:

  • Neue Anwendungen
  • Migrationen

In den folgenden Abschnitten werden die einzelnen Szenarien beschrieben.

Neue Anwendungen

Wenn Ihre vorhandene Anwendung INT64-Schlüssel in GoogleSQL oder bigint-Schlüssel in PostgreSQL erfordert, bietet Spanner das Schemaobjekt „Bit-reversed positive sequence“ (bitweise umgekehrte positive Sequenz) (PostgreSQL oder GoogleSQL). Andernfalls empfehlen wir für neue Anwendungen die Verwendung einer Universally Unique Identifier (UUID). Weitere Informationen finden Sie unter Universally Unique Identifier verwenden.

Migrationen

Für die Migration von Tabellen zu Spanner haben Sie mehrere Möglichkeiten:

  • Wenn Sie UUIDs in Ihrer Quelldatenbank verwenden, können Sie in Spanner eine Schlüsselspalte vom Typ STRING und die Funktion GENERATE_UUID() (GoogleSQL oder PostgreSQL) als Standardwert verwenden.
  • Wenn Sie einen Primärschlüssel vom Typ „Integer“ verwenden und der Schlüssel in Ihrer Anwendung nur eindeutig sein muss, können Sie in INT64 eine Schlüsselspalte und als Standardwert für den Primärschlüssel eine bitweise umgekehrte positive Sequenz verwenden. Weitere Informationen finden Sie unter Bitweise umgekehrte Schlüsselspalten migrieren.
  • In Spanner gibt es keine Möglichkeit, monotone Werte zu generieren.

    Wenn Sie einen monotonen Schlüssel wie den PostgreSQL-Typ SERIAL oder das MySQL-Attribut AUTO_INCREMENT verwenden und neue monotone Schlüssel in Spanner benötigen, können Sie einen zusammengesetzten Schlüssel verwenden. Weitere Informationen finden Sie unter Reihenfolge der Schlüssel tauschen und Eindeutigen Schlüssel hashen und Schreibvorgänge auf logische Shards aufteilen.

  • Wenn in Ihrer Anwendung der INT64-Schlüssel in GoogleSQL oder der bigint-Schlüssel in PostgreSQL manuell bitweise umgekehrt wird, können Sie eine bitweise umgekehrte positive Sequenz (GoogleSQL oder PostgreSQL) verwenden und neue Schlüsselwerte generieren lassen. Weitere Informationen finden Sie unter Bitweise umgekehrte Schlüsselspalten migrieren.

Nächste Schritte