Obiettivi
Questo tutorial illustra i passaggi seguenti utilizzando l'API Cloud Spanner con REST:
- Creare un'istanza e un database Spanner.
- Scrivi, leggi ed esegui query SQL sui dati nel database.
- Aggiorna lo schema del database.
- Aggiungi un indice secondario al database.
- Utilizza l'indice per leggere ed eseguire query SQL sui dati.
- Recupera i dati utilizzando una transazione di sola lettura.
Se vuoi utilizzare le librerie client di Spanner anziché l'API REST, consulta i tutorial.
Costi
Questo tutorial utilizza Spanner, che è un componente fatturabile di Google Cloud. Per informazioni sul costo dell'utilizzo di Spanner, consulta i prezzi.
Prima di iniziare
- Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
-
Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
Modalità di esecuzione di chiamate REST
Puoi effettuare chiamate REST di Spanner utilizzando:
- La funzionalità Prova! disponibile nella documentazione di riferimento dell'API Spanner. Negli esempi mostrati in questa pagina viene utilizzata la funzionalità Prova!.
- Explorer API di Google, che contiene l'API Cloud Spanner e altre API di Google.
- Altri strumenti o framework che supportano le chiamate REST HTTP.
Convenzioni utilizzate in questa pagina
Gli esempi utilizzano
[PROJECT_ID]
come ID progetto Google Cloud. Sostituisci il tuo ID progetto Google Cloud con[PROJECT_ID]
. Non includere[
e]
nell'ID progetto.Gli esempi creano e utilizzano un ID istanza di
test-instance
. Sostituisci l'ID istanza se non utilizzitest-instance
.Gli esempi creano e utilizzano un ID database di
example-db
. Sostituisci l'ID del database se non utilizziexample-db
.Gli esempi utilizzano
[SESSION]
come parte del nome di una sessione. Sostituisci il valore ricevuto al momento della creazione di una sessione per[SESSION]
. Non includere[
e]
nel nome della sessione.Negli esempi viene utilizzato l'ID transazione
[TRANSACTION_ID]
. Sostituisci il valore ricevuto quando crei una transazione per[TRANSACTION_ID]
. Non includere[
e]
nell'ID transazione.La funzionalità Prova! supporta l'aggiunta interattiva di singoli campi di richiesta HTTP. La maggior parte degli esempi in questo argomento fornisce l'intera richiesta anziché descrivere come aggiungere in modo interattivo i singoli campi alla richiesta.
Istanze
Quando utilizzi Spanner per la prima volta, devi creare un'istanza, ovvero un'allocazione di risorse utilizzate dai database Spanner. Quando crei un'istanza, scegli dove sono archiviati i dati e la capacità di calcolo di cui dispone l'istanza.
Elenca configurazioni istanza
Quando crei un'istanza, specifichi una configurazione dell'istanza che definisce il posizionamento geografico e la replica dei database nell'istanza. Puoi scegliere una configurazione a livello di regione, che archivia i dati in un'unica regione, o una configurazione per più regioni, che distribuisce i dati in più regioni. Scopri di più in Istanze.
Utilizza projects.instanceConfigs.list
per determinare quali configurazioni sono
disponibili per il tuo progetto Google Cloud.
- Fai clic su
projects.instanceConfigs.list
. Per parent, inserisci:
projects/[PROJECT_ID]
Fai clic su Execute (Esegui). Le configurazioni dell'istanza disponibili sono mostrate nella risposta. Ecco un esempio di risposta (il progetto potrebbe avere configurazioni dell'istanza diverse):
{ "instanceConfigs": [ { "name": "projects/[PROJECT_ID]/instanceConfigs/regional-asia-south1", "displayName": "asia-south1" }, { "name": "projects/[PROJECT_ID]/instanceConfigs/regional-asia-east1", "displayName": "asia-east1" }, { "name": "projects/[PROJECT_ID]/instanceConfigs/regional-asia-northeast1", "displayName": "asia-northeast1" }, { "name": "projects/[PROJECT_ID]/instanceConfigs/regional-europe-west1", "displayName": "europe-west1" }, { "name": "projects/[PROJECT_ID]/instanceConfigs/regional-us-east4", "displayName": "us-east4" }, { "name": "projects/[PROJECT_ID]/instanceConfigs/regional-us-central1", "displayName": "us-central1" } ] }
Utilizza il valore name
per una delle configurazioni dell'istanza quando crei l'istanza.
Crea un'istanza
- Fai clic su
projects.instances.create
. Per parent, inserisci:
projects/[PROJECT_ID]
Fai clic su Aggiungi parametri per il corpo della richiesta e seleziona
instance
.Fai clic sul fumetto del suggerimento per instance per visualizzare i campi possibili. Aggiungi valori per i seguenti campi:
nodeCount
: inserisci1
.config
: inserisci il valorename
di una delle configurazioni delle istanze regionali restituite quando elenchi le configurazioni delle istanze.displayName
: inserisciTest Instance
.
Fai clic sul fumetto del suggerimento che segue la parentesi di chiusura per instance e seleziona instanceId.
Per
instanceId
, inseriscitest-instance
.
La pagina di creazione dell'istanza Prova! ora dovrebbe avere il seguente aspetto:Fai clic su Execute (Esegui). La risposta restituisce un'operazione a lunga esecuzione su cui puoi eseguire una query per verificarne lo stato.
Puoi elencare le istanze utilizzando
projects.instances.list
.
Crea un database
Crea un database denominato example-db
.
- Fai clic su
projects.instances.databases.create
. Per parent, inserisci:
projects/[PROJECT_ID]/instances/test-instance
Fai clic su Aggiungi parametri per il corpo della richiesta e seleziona
createStatement
.Per
createStatement
, inserisci:CREATE DATABASE `example-db`
Il nome del database,
example-db
, contiene un trattino, che deve quindi essere racchiuso tra apici inversi (`
).Fai clic su Execute (Esegui). La risposta restituisce un'operazione a lunga esecuzione su cui puoi eseguire una query per verificarne lo stato.
Puoi elencare i tuoi database utilizzando
projects.instances.databases.list
.
Crea uno schema
Utilizza il Data Definition Language (DDL) di Spanner per creare, modificare o eliminare le tabelle e creare o eliminare gli indici.
- Fai clic su
projects.instances.databases.updateDdl
. Per database, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db
Per Corpo della richiesta, utilizza quanto segue:
{ "statements": [ "CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX) ) PRIMARY KEY (SingerId)", "CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX)) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE" ] }
L'array
statements
contiene le istruzioni DDL che definiscono lo schema.Fai clic su Execute (Esegui). La risposta restituisce un'operazione a lunga esecuzione su cui puoi eseguire una query per verificarne lo stato.
Lo schema definisce due tabelle, Singers
e Albums
, per un'applicazione musicale di base. Queste tabelle vengono utilizzate in questa pagina. Se non l'hai ancora fatto, dai un'occhiata allo schema di esempio.
Puoi recuperare lo schema utilizzando
projects.instances.databases.getDdl
.
Crea una sessione
Prima di poter aggiungere, aggiornare, eliminare o eseguire query sui dati, devi creare una sessione, che rappresenta un canale di comunicazione con il servizio di database Spanner. (non utilizzi direttamente una sessione se utilizzi una libreria client di Spanner, perché la libreria client gestisce le sessioni per tuo conto).
- Fai clic su
projects.instances.databases.sessions.create
. Per database, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db
Fai clic su Execute (Esegui).
La risposta mostra la sessione che hai creato, nel modulo
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
Utilizzerai questa sessione per le operazioni di lettura o scrittura nel database.
Le sessioni sono pensate per durare a lungo. Il servizio di database Spanner può eliminare una sessione se questa è inattiva per più di un'ora. I tentativi di utilizzare una sessione eliminata generano un risultato di NOT_FOUND
. Se si verifica questo errore, crea
e utilizza una nuova sessione. Puoi controllare se una sessione è ancora attiva utilizzando
projects.instances.databases.sessions.get
.
Per informazioni correlate, consulta Mantenere attiva una sessione inattiva.
Il passaggio successivo consiste nella scrittura dei dati nel database.
Scrittura di dati
Per scrivere i dati, utilizzi il tipo Mutation
. Un Mutation
è un contenitore per operazioni di mutazione. Un elemento Mutation
rappresenta una sequenza di inserti, aggiornamenti, eliminazioni e altre azioni che possono essere applicate a livello atomico a diverse righe e tabelle in un database Spanner.
- Fai clic su
projects.instances.databases.sessions.commit
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "singleUseTransaction": { "readWrite": {} }, "mutations": [ { "insertOrUpdate": { "table": "Singers", "columns": [ "SingerId", "FirstName", "LastName" ], "values": [ [ "1", "Marc", "Richards" ], [ "2", "Catalina", "Smith" ], [ "3", "Alice", "Trentor" ], [ "4", "Lea", "Martin" ], [ "5", "David", "Lomond" ] ] } }, { "insertOrUpdate": { "table": "Albums", "columns": [ "SingerId", "AlbumId", "AlbumTitle" ], "values": [ [ "1", "1", "Total Junk" ], [ "1", "2", "Go, Go, Go" ], [ "2", "1", "Green" ], [ "2", "2", "Forever Hold Your Peace" ], [ "2", "3", "Terrified" ] ] } } ] }
Fai clic su Execute (Esegui). La risposta mostra il timestamp del commit.
In questo esempio è stato utilizzato insertOrUpdate
. Altre operations
per Mutations
sono insert
, update
, replace
e delete
.
Per informazioni su come codificare i tipi di dati, consulta la pagina TypeCode.
Esegui query sui dati utilizzando SQL
- Fai clic su
projects.instances.databases.sessions.executeSql
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "sql": "SELECT SingerId, AlbumId, AlbumTitle FROM Albums" }
Fai clic su Execute (Esegui). La risposta mostra i risultati della query.
Leggere i dati utilizzando l'API Read
- Fai clic su
projects.instances.databases.sessions.read
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "table": "Albums", "columns": [ "SingerId", "AlbumId", "AlbumTitle" ], "keySet": { "all": true } }
Fai clic su Execute (Esegui). La risposta mostra i risultati della lettura.
Aggiorna lo schema del database
Supponi di dover aggiungere una nuova colonna denominata MarketingBudget
alla tabella Albums
, il che richiede un aggiornamento dello schema del database. Spanner supporta gli aggiornamenti dello schema in un database mentre quest'ultimo continua a gestire il traffico. Gli aggiornamenti dello schema non richiedono di portare il database offline e non bloccano intere tabelle o colonne; puoi continuare a scrivere dati nel database durante l'aggiornamento dello schema.
Aggiungi una colonna
- Fai clic su
projects.instances.databases.updateDdl
. Per database, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db
Per Corpo della richiesta, utilizza quanto segue:
{ "statements": [ "ALTER TABLE Albums ADD COLUMN MarketingBudget INT64" ] }
L'array
statements
contiene le istruzioni DDL che definiscono lo schema.Fai clic su Execute (Esegui). Il completamento dell'operazione potrebbe richiedere alcuni minuti, anche dopo che la chiamata REST ha restituito una risposta. La risposta restituisce un'operazione a lunga esecuzione su cui puoi eseguire una query per verificarne lo stato.
Scrivere i dati nella nuova colonna
Il codice seguente scrive i dati nella nuova colonna. Imposta MarketingBudget
su 100000
per la riga codificata da Albums(1, 1)
e su 500000
per la riga codificata da Albums(2, 2)
.
- Fai clic su
projects.instances.databases.sessions.commit
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "singleUseTransaction": { "readWrite": {} }, "mutations": [ { "update": { "table": "Albums", "columns": [ "SingerId", "AlbumId", "MarketingBudget" ], "values": [ [ "1", "1", "100000" ], [ "2", "2", "500000" ] ] } } ] }
Fai clic su Execute (Esegui). La risposta mostra il timestamp del commit.
Puoi anche eseguire una query SQL o una chiamata di lettura per recuperare i valori che hai appena scritto.
Ecco come eseguire la query:
- Fai clic su
projects.instances.databases.sessions.executeSql
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "sql": "SELECT SingerId, AlbumId, MarketingBudget FROM Albums" }
Fai clic su Execute (Esegui). Nella risposta dovresti vedere due righe che contengono i valori
MarketingBudget
aggiornati:"rows": [ [ "1", "1", "100000" ], [ "1", "2", null ], [ "2", "1", null ], [ "2", "2", "500000" ], [ "2", "3", null ] ]
Utilizza un indice secondario
Supponi di voler recuperare tutte le righe di Albums
con valori di AlbumTitle
in un determinato intervallo. Puoi leggere tutti i valori della colonna AlbumTitle
utilizzando un'istruzione SQL o una chiamata di lettura e quindi ignorare le righe che non soddisfano i criteri, ma eseguire questa scansione completa della tabella è costosa, soprattutto per le tabelle con molte righe. Puoi però velocizzare il recupero delle righe quando esegui ricerche per colonne di chiave non primaria creando un indice secondario nella tabella.
L'aggiunta di un indice secondario a una tabella esistente richiede un aggiornamento dello schema. Come per altri aggiornamenti dello schema, Spanner supporta l'aggiunta di un indice mentre il database continua a gestire il traffico. Spanner esegue automaticamente il backfill dell'indice con i dati esistenti. Il completamento dei backfill potrebbe richiedere alcuni minuti, ma non è necessario mettere offline il database o evitare di scrivere in determinate tabelle o colonne durante questo processo. Per maggiori dettagli, consulta la pagina relativa al backfill degli indici.
Dopo aver aggiunto un indice secondario, Spanner lo utilizza automaticamente per le query SQL che potrebbero essere eseguite più velocemente con l'indice. Se usi l'interfaccia di lettura, devi specificare l'indice che vuoi usare.
Aggiungi un indice secondario
Puoi aggiungere un indice utilizzando updateDdl
.
- Fai clic su
projects.instances.databases.updateDdl
. Per database, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db
Per Corpo della richiesta, utilizza quanto segue:
{ "statements": [ "CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)" ] }
Fai clic su Execute (Esegui). Il completamento dell'operazione potrebbe richiedere alcuni minuti, anche dopo che la chiamata REST ha restituito una risposta. La risposta restituisce un'operazione a lunga esecuzione su cui puoi eseguire una query per verificarne lo stato.
Esegui una query utilizzando l'indice
- Fai clic su
projects.instances.databases.sessions.executeSql
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "sql": "SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums WHERE AlbumTitle >= 'Aardvark' AND AlbumTitle < 'Goo'" }
Fai clic su Execute (Esegui). Come parte della risposta dovresti vedere le seguenti righe:
"rows": [ [ "2", "Go, Go, Go", null ], [ "2", "Forever Hold Your Peace", "500000" ] ]
Lettura utilizzando l'indice
- Fai clic su
projects.instances.databases.sessions.read
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "table": "Albums", "columns": [ "AlbumId", "AlbumTitle" ], "keySet": { "all": true }, "index": "AlbumsByAlbumTitle" }
Fai clic su Execute (Esegui). Come parte della risposta dovresti vedere le seguenti righe:
"rows": [ [ "2", "Forever Hold Your Peace" ], [ "2", "Go, Go, Go" ], [ "1", "Green" ], [ "3", "Terrified" ], [ "1", "Total Junk" ] ]
Aggiungi un indice con la clausola STORING
Potresti aver notato che l'esempio letto sopra non includeva la lettura della colonna MarketingBudget
. Questo perché l'interfaccia di lettura di Spanner non supporta la possibilità di unire un indice a una tabella di dati per cercare valori non archiviati nell'indice.
Crea una definizione alternativa di AlbumsByAlbumTitle
che archivi una copia di MarketingBudget
nell'indice.
Puoi aggiungere un indice STORING utilizzando updateDdl
.
- Fai clic su
projects.instances.databases.updateDdl
. Per database, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db
Per Corpo della richiesta, utilizza quanto segue:
{ "statements": [ "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)" ] }
Fai clic su Execute (Esegui). Il completamento dell'operazione potrebbe richiedere alcuni minuti, anche dopo che la chiamata REST ha restituito una risposta. La risposta restituisce un'operazione a lunga esecuzione su cui puoi eseguire una query per verificarne lo stato.
Ora puoi eseguire una lettura che recupera tutte le colonne AlbumId
, AlbumTitle
e MarketingBudget
dall'indice AlbumsByAlbumTitle2
:
- Fai clic su
projects.instances.databases.sessions.read
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "table": "Albums", "columns": [ "AlbumId", "AlbumTitle", "MarketingBudget" ], "keySet": { "all": true }, "index": "AlbumsByAlbumTitle2" }
Fai clic su Execute (Esegui). Come parte della risposta dovresti vedere le seguenti righe:
"rows": [ [ "2", "Forever Hold Your Peace", "500000" ], [ "2", "Go, Go, Go", null ], [ "1", "Green", null ], [ "3", "Terrified", null ], [ "1", "Total Junk", "100000" ] ]
Recuperare i dati utilizzando transazioni di sola lettura
Supponi di voler eseguire più di una lettura allo stesso timestamp. Le transazioni di sola lettura seguono un prefisso coerente nella cronologia del commit delle transazioni, in modo che l'applicazione riceva sempre dati coerenti.
Creare una transazione di sola lettura
- Fai clic su
projects.instances.databases.sessions.beginTransaction
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
Per il Corpo della richiesta, utilizza il seguente codice:
{ "options": { "readOnly": {} } }
Fai clic su Execute (Esegui).
La risposta mostra l'ID della transazione che hai creato.
Ora puoi utilizzare la transazione di sola lettura per recuperare i dati in un timestamp coerente, anche se i dati sono cambiati dalla creazione della transazione di sola lettura.
Esegui una query utilizzando la transazione di sola lettura
- Fai clic su
projects.instances.databases.sessions.executeSql
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "sql": "SELECT SingerId, AlbumId, AlbumTitle FROM Albums", "transaction": { "id": "[TRANSACTION_ID]" } }
Fai clic su Execute (Esegui). Nella risposta dovresti vedere righe simili alle seguenti:
"rows": [ [ "2", "2", "Forever Hold Your Peace" ], [ "1", "2", "Go, Go, Go" ], [ "2", "1", "Green" ], [ "2", "3", "Terrified" ], [ "1", "1", "Total Junk" ] ]
Lettura utilizzando la transazione di sola lettura
- Fai clic su
projects.instances.databases.sessions.read
. Per sessione, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db/sessions/[SESSION]
(ricevi questo valore quando crei una sessione).
Per Corpo della richiesta, utilizza quanto segue:
{ "table": "Albums", "columns": [ "SingerId", "AlbumId", "AlbumTitle" ], "keySet": { "all": true }, "transaction": { "id": "[TRANSACTION_ID]" } }
Fai clic su Execute (Esegui). Nella risposta dovresti vedere righe simili alle seguenti:
"rows": [ [ "1", "1", "Total Junk" ], [ "1", "2", "Go, Go, Go" ], [ "2", "1", "Green" ], [ "2", "2", "Forever Hold Your Peace" ], [ "2", "3", "Terrified" ] ]
Spanner supporta anche le transazioni di lettura-scrittura, che eseguono un set di letture e scritture a livello atomico in un singolo momento logico. Per ulteriori informazioni, consulta Transazioni di lettura-scrittura. La funzionalità Prova! non è adatta per dimostrare una transazione di lettura/scrittura.
esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi aggiuntivi per le risorse utilizzate in questo tutorial, elimina il database ed elimina l'istanza che hai creato.
Elimina un database
- Fai clic su
projects.instances.databases.dropDatabase
. Per nome, inserisci:
projects/[PROJECT_ID]/instances/test-instance/databases/example-db
Fai clic su Execute (Esegui).
Elimina un'istanza
- Fai clic su
projects.instances.delete
. Per nome, inserisci:
projects/[PROJECT_ID]/instances/test-instance
Fai clic su Execute (Esegui).
Passaggi successivi
- Accesso a Spanner in un'istanza di macchina virtuale: crea un'istanza di macchina virtuale con accesso al tuo database Spanner.
- Scopri di più sui concetti di Spanner.