Questa pagina illustra le strategie da utilizzare per generare valori di chiave primaria nella tabella utilizzando le espressioni di valore predefinito. Le informazioni in questa pagina si applicano sia ai database con dialetto GoogleSQL sia a quelli con dialetto PostgreSQL. Queste strategie offrono i seguenti vantaggi:
- Evitare gli hotspot
- Semplificare le migrazioni da altri database
- Incapsula la logica chiave nel database in modo da non doverti preoccupare di gestirla nella tua applicazione
- Nella maggior parte dei casi, sostituisce la necessità di creare e gestire le tue sequenze
Metodi per generare automaticamente le chiavi primarie
Per generare automaticamente i valori della chiave primaria, puoi utilizzare le seguenti strategie in una colonna con espressioni DEFAULT:
- Una funzione UUID che genera valori UUID versione 4.
- Colonne
IDENTITYche generano automaticamente valori interi per le colonne chiave e non chiave. SERIALin PostgreSQL eAUTO_INCREMENTin GoogleSQL, che sono alias DDL per le colonneIDENTITY.- Un oggetto di schema,
SEQUENCE, che ha un'opzionebit_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 a nuove applicazioni e tabelle con molte righe. Sono distribuiti in modo approssimativo uniforme nello spazio delle chiavi, il che impedisce 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 lo utilizzi in tabelle di grandi dimensioni. Gli UUID sono univoci indipendentemente dal fatto che li generi nel database o nel client. Ti consigliamo di utilizzare gli UUID quando possibile. Puoi combinare in modo sicuro UUID generati dal client e da Spanner nella stessa tabella se gli UUID generati dal client vengono serializzati in minuscolo, in conformità con RFC 4122.
Per una colonna che richiede valori predefiniti, puoi utilizzare la funzione
NEW_UUID
GoogleSQL o la funzione
gen_random_uuid()
PostgreSQL
per generare i valori. 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 saperne di più sulle funzioni UUID generate, consulta la pagina di riferimento di GoogleSQL o PostgreSQL.
IDENTITY colonne
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 viene eliminata una colonna Identity generata automaticamente, 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 di sequenza interno generato automaticamente e inverte i bit del valore prima di inserirlo in questa colonna.
In Spanner, le colonne IDENTITY sono supportate sia in GoogleSQL che in PostgreSQL.
GoogleSQL
L'esempio seguente mostra come utilizzare le colonne IDENTITY per creare una colonna della 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 di numeri interi generata automaticamente per SingerId con valori positivi invertiti bit per bit 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 di numeri interi 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 di numeri interi generata automaticamente per SingerId che genera valori positivi invertiti a livello di bit e il contatore interno, prima dell'inversione a livello di 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 di numeri interi univoci. 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 vengono mappati alle colonne IDENTITY, non
li vedrai quando serializzi lo schema. Per questo schema, l'output di
GetDatabaseDDL sarebbe:
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 di 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 privato e interno per garantire l'unicità. I valori invertiti a livello di bit risultanti aiutano a evitare hotspot su larga scala quando vengono utilizzati in una chiave primaria.
In Spanner, utilizzi le istruzioni DDL SEQUENCE insieme all'attributo bit_reversed_positive per creare, modificare o eliminare una sequenza che produce valori positivi invertiti a livello di bit (GoogleSQL o PostgreSQL).
Ogni sequenza mantiene un insieme di contatori interni e li utilizza per generare un valore. Il contatore di sequenza fornisce l'input all'algoritmo di inversione dei bit.
Quando definisci una colonna con un'espressione DEFAULT che utilizza la funzione
GET-NEXT-SEQUENCE-VALUE GoogleSQL o nextval PostgreSQL come valore predefinito, Spanner
chiama automaticamente la funzione e inserisce i valori di output invertiti bit per 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 di 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:
- 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 maggiori informazioni, vedi Utilizzare un UUID (Universally Unique Identifier).
Se la tua applicazione esistente richiede chiavi INT64 in GoogleSQL o chiavi bigint in PostgreSQL, Spanner offre l'oggetto schema di sequenza positiva invertita bit (PostgreSQL o GoogleSQL).
Migrazioni
Per le migrazioni di tabelle a Spanner, hai le seguenti opzioni:
- Se utilizzi UUID nel database di origine, in Spanner puoi utilizzare una colonna di tipo UUID e la funzione UUID generata (GoogleSQL o PostgreSQL) come valore predefinito.
- Se utilizzi una chiave primaria intera e la tua applicazione richiede solo che la chiave sia univoca, puoi utilizzare una colonna chiave in
INT64e una sequenza positiva invertita bit per bit per il valore predefinito della chiave primaria. Consulta Migrazione delle colonne delle chiavi con inversione dei bit. - Spanner non supporta un modo per generare valori monotoni.
Se utilizzi una chiave monotona, ad esempio il tipo
SERIALdi PostgreSQL o l'attributoAUTO_INCREMENTdi MySQL, e hai bisogno di nuove chiavi monotone su Spanner, puoi utilizzare una chiave composita. Per saperne di più, consulta Inverti l'ordine delle chiavi e Calcola l'hash della chiave univoca e distribuisci le scritture tra gli shard logici. - Se la tua applicazione esegue manualmente l'inversione dei bit della chiave
INT64in GoogleSQL o della chiavebigintin PostgreSQL, puoi utilizzare una sequenza positiva con inversione dei bit (GoogleSQL o PostgreSQL) e generare nuovi valori delle chiavi. Per maggiori informazioni, consulta Migrazione di colonne chiave con inversione di bit.
Passaggi successivi
- Scopri di più sull'utilizzo delle sequenze con il controllo dell'accesso granulare.
- Scopri di più sulle istruzioni DDL
SEQUENCEper GoogleSQL o PostgreSQL. - Scopri di più sulle funzioni di sequenza in GoogleSQL o PostgreSQL.
- Scopri di più sulle sequenze in INFORMATION_SCHEMA in GoogleSQL o PostgreSQL.
- Scopri di più sulle opzioni di sequenza in INFORMATION_SCHEMA per GoogleSQL.