Gestione dei valori predefiniti della chiave primaria

Questa pagina illustra le strategie da utilizzare per generare i valori chiave primaria nella tabella utilizzando le espressioni dei valori predefiniti. Le informazioni riportate in questa pagina si applicano sia ai database con dialetto GoogleSQL sia ai database con dialetto PostgreSQL. Queste strategie presentano i seguenti vantaggi:

  • Evitare gli hotspot
  • Semplificare le migrazioni da altri database
  • Incapsulare la logica delle chiavi nel database in modo da non doverti preoccupare della gestione nell'applicazione
  • Nella maggior parte dei casi, sostituire la necessità di creare e gestire le proprie sequenze

Metodi per generare automaticamente le chiavi primarie

Per generare automaticamente i valori chiave primaria, puoi utilizzare le seguenti strategie in una colonna con espressioni DEFAULT:

  • Una funzione UUID che genera valori UUID versione 4.
  • Colonne IDENTITY che generano automaticamente valori interi per le colonne chiave e non chiave.
  • SERIAL in PostgreSQL e AUTO_INCREMENT in GoogleSQL, che sono alias DDL per le colonne IDENTITY.
  • Un oggetto schema, SEQUENCE, con un'opzione bit_reversed_positive. SEQUENCE è disponibile sia per GoogleSQL sia per PostgreSQL.

Identificatore univoco universale (UUID)

Spanner può generare automaticamente un UUID versione 4 da utilizzare come chiave primaria. Gli UUID sono adatti per le nuove applicazioni e le tabelle con molte righe. Sono distribuiti in modo approssimativo uniforme nello spazio delle chiavi, il che impedisce gli hotspot su larga scala. La generazione di UUID può creare un numero elevato di valori (2122) e ogni valore è effettivamente univoco. Ad esempio, avresti bisogno di 2, 71 × 1018 valori per una probabilità di collisione del 50% o di 1 miliardo al secondo per 86 anni. In questo modo, i valori sono univoci quando li utilizzi in tabelle di grandi dimensioni. Gli UUID sono univoci sia che li generi nel database sia nel client. Ti consigliamo di utilizzare gli UUID, se possibile. Puoi combinare in modo sicuro gli UUID generati dal client e quelli generati da Spanner nella stessa tabella se gli UUID generati dal client sono serializzati in minuscolo, in conformità con RFC 4122.

Per una colonna che richiede valori predefiniti, puoi utilizzare la NEW_UUID funzione GoogleSQL o la gen_random_uuid() funzione PostgreSQL per generarli. L'esempio seguente mostra come creare una tabella in cui la colonna chiave FanId ha un UUID generato nella colonna dei valori come valore predefinito.

GoogleSQL

CREATE TABLE Fans (
  FanId UUID DEFAULT (NEW_UUID()),
  Name STRING(MAX),
) PRIMARY KEY (FanId);

PostgreSQL

CREATE TABLE Fans (
  FanId uuid DEFAULT gen_random_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);

Questa istruzione restituisce un risultato simile al seguente:

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

Per ulteriori informazioni sulle funzioni UUID generate, consulta la GoogleSQL o PostgreSQL.

Colonne IDENTITY

Con le colonne IDENTITY, puoi generare automaticamente valori interi per le colonne chiave e non chiave. Le colonne IDENTITY non richiedono agli utenti di gestire manualmente una sequenza sottostante o di gestire la relazione tra la colonna e la sequenza sottostante. Quando una colonna identity generata automaticamente viene eliminata, viene eliminata automaticamente anche la sequenza sottostante.

Puoi utilizzare le colonne IDENTITY fornendo un valore intero iniziale durante la generazione della sequenza o lasciando che Spanner generi la sequenza di numeri interi per te. Per fornire un valore intero iniziale, devi utilizzare l'opzione START COUNTER WITH e un valore iniziale INT64 positivo. Spanner utilizza questo valore per impostare il valore successivo per il contatore della sequenza interna generata automaticamente e inverte i bit del valore prima di inserirlo in questa colonna.

In Spanner, le colonne IDENTITY sono supportate sia in GoogleSQL sia in PostgreSQL.

GoogleSQL

L'esempio seguente mostra come utilizzare le colonne IDENTITY per creare una colonna chiave primaria intera generata automaticamente per SingerId quando crei una nuova tabella utilizzando il comando CREATE TABLE:

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

Puoi anche specificare l'inizio del contatore per la colonna utilizzando l'opzione START_WITH_COUNTER. Nell'esempio seguente, viene creata una colonna intera generata automaticamente per SingerId con valori positivi invertiti e un contatore interno che inizia da 1000.

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

L'esempio seguente mostra come utilizzare le colonne IDENTITY per creare una colonna intera generata automaticamente per SingerId quando crei una nuova tabella utilizzando il comando CREATE TABLE:

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

Puoi anche specificare l'inizio del contatore per la colonna utilizzando l'opzione START COUNTER WITH. Nell'esempio seguente, viene creata una colonna intera generata automaticamente per SingerId che genera valori positivi invertiti e il contatore interno, prima dell'inversione dei bit, inizia da 1000.

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

SERIAL e AUTO_INCREMENT

Spanner supporta SERIAL in PostgreSQL e AUTO_INCREMENT in GoogleSQL, che sono alias DDL per le colonne IDENTITY e vengono utilizzati per creare colonne intere univoche. Prima di utilizzare SERIAL o AUTO_INCREMENT, devi impostare l'opzione default_sequence_kind del database. Puoi utilizzare la seguente istruzione SQL per impostare l'opzione default_squence_kind del database:

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

Tieni presente che, poiché SERIAL e AUTO_INCREMENT eseguono il mapping alle colonne IDENTITY, non le vedrai quando serializzi lo schema. Per questo schema, l'output di GetDatabaseDDL sarà:

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

Sequenza con inversione dei bit

Una sequenza con inversione dei bit è un oggetto schema che produce una sequenza di numeri interi e ne inverte i bit. Questo oggetto utilizza l'inversione dei bit su un contatore Spanner interno privato per garantire l'unicità. I valori con inversione dei bit risultanti aiutano a evitare gli hotspot su larga scala quando vengono utilizzati in una chiave primaria.

In Spanner, utilizzi le istruzioni DDL SEQUENCE insieme all' bit_reversed_positive per creare, modificare o eliminare una sequenza che produce valori positivi con inversione dei bit (GoogleSQL o PostgreSQL).

Ogni sequenza gestisce un insieme di contatori interni e li utilizza per generare un valore. Il contatore della sequenza fornisce l'input all'algoritmo di inversione dei bit.

Quando definisci una colonna con un'espressione DEFAULT che utilizza la funzione GoogleSQL GET_NEXT_SEQUENCE_VALUE o la funzione PostgreSQL nextval come valore predefinito, Spanner chiama automaticamente la funzione e inserisce i valori di output con inversione dei bit nella colonna. Le sequenze con inversione dei bit sono particolarmente utili per le chiavi primarie, perché i valori con inversione dei bit sono distribuiti uniformemente nello spazio delle chiavi in modo da non causare hotspot.

L'esempio seguente mostra come creare una sequenza con inversione dei bit e una tabella in cui la colonna chiave utilizza la sequenza come valore predefinito:

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

Puoi quindi utilizzare la seguente istruzione SQL per inserire e restituire il valore della chiave primaria:

GoogleSQL

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

PostgreSQL

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

Questa istruzione restituisce un risultato simile al seguente:

SingerId
3458764513820540928

Scenari per l'utilizzo di UUID e sequenze come valori predefiniti per le chiavi primarie

Gli scenari per UUID e sequenze includono i seguenti:

  • Nuove applicazioni
  • Migrazioni

Le sezioni seguenti descrivono ogni scenario.

Nuove applicazioni

Per le nuove applicazioni, Spanner consiglia di utilizzare l'identificatore univoco universale (UUID) per le chiavi primarie. Per ulteriori informazioni, vedi Utilizzare un identificatore univoco universale (UUID).

Se l'applicazione esistente richiede INT64 chiavi in GoogleSQL o bigint chiavi in PostgreSQL, Spanner offre l' oggetto schema della sequenza positiva con inversione dei bit (PostgreSQL o GoogleSQL).

Migrazioni

Per le migrazioni di tabelle a Spanner, hai le seguenti opzioni:

Passaggi successivi