Objetivos
Este tutorial apresenta as seguintes etapas usando a Cloud Spanner API com a REST:
- Crie uma instância e um banco de dados do Spanner.
- Gravar, ler e executar consultas SQL em dados contidos no banco de dados.
- Atualizar o esquema do banco de dados.
- Adicionar um índice secundário ao banco de dados.
- Usar o índice para ler e executar consultas SQL nos dados.
- Recuperar dados usando uma transação somente leitura.
Se você quer usar bibliotecas de cliente do Spanner em vez de usar a API REST, consulte Tutoriais.
Custos
Neste tutorial, usamos o Spanner, que é um componente faturável do Google Cloud. Para informações sobre o custo do uso do Spanner, consulte Preços.
Antes de começar
- Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Maneiras de fazer chamadas REST
Você pode fazer chamadas REST do Spanner usando:
- O recurso Faça um teste! encontrado na documentação de referência da API Spanner.
- As APIs Explorer do Google, que contém a API Cloud Spanner e outras APIs do Google;
- Outras ferramentas ou bibliotecas compatíveis com chamadas HTTP REST.
Convenções usadas nesta página
Os exemplos usam
<var>PROJECT_ID</var>como o ID do projeto Google Cloud . Substitua o ID do projeto Google Cloud por<var>PROJECT_ID</var>.Os exemplos criam e usam um código de instância de
test-instance. Substitua o ID da instância se você não estiver usandotest-instance.Os exemplos criam e usam um código de banco de dados de
example-db. Substitua o código do seu banco de dados se você não estiver usandoexample-db.Os exemplos usam
<var>SESSION</var>como parte de um nome de sessão. Substitua por<var>SESSION</var>o valor que você receber quando criar uma sessão.Os exemplos usam um código de transação de
<var>TRANSACTION_ID</var>. Substitua<var>TRANSACTION_ID</var>pelo valor que você receber quando criar uma transação.A funcionalidade Faça um teste! permite a adição interativa de campos individuais de solicitação HTTP. A maioria dos exemplos neste documento fornece toda a solicitação em vez de descrever como adicionar interativamente campos individuais.
Instâncias
Ao usar o Spanner pela primeira vez, crie uma instância. Uma instância aloca recursos que os bancos de dados do Spanner usam. Ao criar uma instância, você escolhe onde os dados são armazenados e a capacidade de computação dela.
Listar configurações de instância
Ao criar uma instância, você especifica uma configuração de instância que define a colocação geográfica e a replicação de bancos de dados nesta instância. Escolha uma configuração regional para armazenar dados em uma região ou uma configuração multirregional para distribuir dados em várias regiões. Saiba mais em Instâncias.
Use projects.instanceConfigs.list para determinar quais configurações estão disponíveis para seu Google Cloud projeto.
- Clique em
projects.instanceConfigs.list. Para o pai, digite:
projects/PROJECT_ID
Clique em Executar. A resposta mostra as configurações de instância disponíveis. Veja um exemplo de resposta (seu projeto pode ter diferentes configurações de instância):
{ "instanceConfigs": [ { "name": "projects/<var>PROJECT_ID</var>/instanceConfigs/regional-asia-south1", "displayName": "asia-south1" }, { "name": "projects/<var>PROJECT_ID</var>/instanceConfigs/regional-asia-east1", "displayName": "asia-east1" }, { "name": "projects/<var>PROJECT_ID</var>/instanceConfigs/regional-asia-northeast1", "displayName": "asia-northeast1" }, { "name": "projects/<var>PROJECT_ID</var>/instanceConfigs/regional-europe-west1", "displayName": "europe-west1" }, { "name": "projects/<var>PROJECT_ID</var>/instanceConfigs/regional-us-east4", "displayName": "us-east4" }, { "name": "projects/<var>PROJECT_ID</var>/instanceConfigs/regional-us-central1", "displayName": "us-central1" } ] }
Você usa o valor name de uma das configurações de instância ao criar sua instância.
Criar uma instância
- Clique em
projects.instances.create. Para o pai, digite:
projects/<var>PROJECT_ID</var>Clique em Adicionar parâmetros do corpo da solicitação e selecione
instance.Clique no balão da dica em Instância para ver os campos possíveis. Adicione valores para os seguintes campos:
nodeCount: insira1.config: insira o valornamede uma das configurações de instância regional retornadas quando você listar as configurações de instância.displayName: insiraTest Instance.
Clique no balão da dica depois do colchete de fechamento para Instância e selecione instanceId.
Para
instanceId, digitetest-instance
Sua a página de criação de instância terá Faça um teste! esta aparência:
Clique em Executar. A resposta retorna uma operação de longa duração. Consulte essa operação para verificar o status dela.
Liste instâncias usando
projects.instances.list.
Criar um banco de dados
Crie um banco de dados chamado example-db.
- Clique em
projects.instances.databases.create. Para o pai, digite:
projects/<var>PROJECT_ID</var>/instances/test-instanceClique em Adicionar parâmetros do corpo da solicitação e selecione
createStatement.Para
createStatement, digite:CREATE DATABASE `example-db`
O nome do banco de dados, example-db, contém um hífen, por isso deve estar entre acentos graves (`).
- Clique em Executar. A resposta retorna uma operação de longa duração. Consulte essa operação para verificar o status dela.
Liste seus bancos de dados usando
projects.instances.databases.list.
Criar um esquema
Use a linguagem de definição de dados (DDL) do Spanner para criar, alterar ou remover tabelas e criar ou remover índices.
- Clique em
projects.instances.databases.updateDdl. Para o banco de dados, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-dbPara o Corpo de solicitação, use o seguinte:
{ "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" ] }A matriz
statementscontém as instruções DDL que definem o esquema.Clique em Executar. A resposta retorna uma operação de longa duração. Consulte essa operação para verificar o status dela.
O esquema define duas tabelas, Singers e Albums, para um aplicativo de música básico. Este documento usa essas tabelas. Analise o esquema de exemplo.
Recupere seu esquema usando
projects.instances.databases.getDdl.
Criar uma sessão
Antes de adicionar, atualizar, excluir ou consultar dados, crie uma sessão. Uma sessão representa um canal de comunicação com o serviço de banco de dados do Spanner. (Não utilize uma sessão diretamente se estiver usando uma biblioteca de cliente do Spanner, porque a biblioteca gerencia sessões em seu nome.)
- Clique em
projects.instances.databases.sessions.create. Para o banco de dados, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-dbClique em Executar.
A resposta mostra a sessão que você criou, no formato
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Use esta sessão quando ler ou gravar no banco de dados.
As sessões devem ser de longa duração. O serviço de banco de dados do Spanner exclui uma sessão quando ela fica inativa por mais de uma hora. As tentativas de usar uma sessão excluída resultam em NOT_FOUND. Se você encontrar esse erro, crie e use uma nova sessão. Verifique se uma sessão ainda está ativa usando
projects.instances.databases.sessions.get.
Para informações relacionadas, consulte Manter uma sessão ociosa ativa.
As sessões são um conceito avançado. Para mais detalhes e práticas recomendadas, consulte Sessões.
Em seguida, grave dados no seu banco de dados.
Gravar dados
Os dados são gravados usando o tipo Mutation. Um Mutation é um contêiner para operações de mutação. Uma Mutation
representa uma sequência de inserções, atualizações, exclusões e outras ações que
são aplicadas atomicamente a diferentes linhas e tabelas em um banco de dados do Spanner.
- Clique em
projects.instances.databases.sessions.commit. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "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" ] ] } } ] }Clique em Executar. A resposta mostra o carimbo de data/hora da confirmação.
Este exemplo usou insertOrUpdate. Outras operações para Mutations são insert, update, replace e delete.
Para informações sobre como codificar tipos de dados, consulte TypeCode.
Consultar dados usando SQL
- Clique em
projects.instances.databases.sessions.executeSql. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "sql": "SELECT SingerId, AlbumId, AlbumTitle FROM Albums" }Clique em Executar. A resposta exibe os resultados da consulta.
Ler dados usando a API de leitura
- Clique em
projects.instances.databases.sessions.read. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "table": "Albums", "columns": [ "SingerId", "AlbumId", "AlbumTitle" ], "keySet": { "all": true } }Clique em Executar. A resposta exibe os resultados de leitura.
Atualizar o esquema do banco de dados
Adicione uma nova coluna chamada MarketingBudget à tabela Albums. Isso exige uma atualização no esquema do banco de dados. O Spanner é compatível com atualizações de esquema em um banco de dados enquanto esse banco continua a disponibilizar o tráfego. Para fazer atualizações no esquema, não é necessário desconectar o banco de dados nem bloquear tabelas ou colunas inteiras. É possível continuar gravando dados no banco de dados durante a atualização do esquema.
Adicionar uma coluna
- Clique em
projects.instances.databases.updateDdl. Para o banco de dados, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-dbPara o Corpo de solicitação, use o seguinte código:
{ "statements": [ "ALTER TABLE Albums ADD COLUMN MarketingBudget INT64" ] } ``` The `statements` array contains the DDL statements that define the schema.Clique em Executar. Isso pode levar alguns minutos para ser concluído, mesmo após a resposta ter sido retornada pela chamada REST. A resposta retorna uma operação de longa duração. Consulte essa operação para verificar o status dela.
Gravar dados na coluna nova
Esse código grava dados na nova coluna. Ele define MarketingBudget como 100000 para a linha indexada por Albums(1, 1) e como 500000 para a linha indexada por Albums(2, 2).
- Clique em
projects.instances.databases.sessions.commit. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Você receberá esse valor quando criar uma sessão.
Para o Corpo de solicitação, use o seguinte:
{ "singleUseTransaction": { "readWrite": {} }, "mutations": [ { "update": { "table": "Albums", "columns": [ "SingerId", "AlbumId", "MarketingBudget" ], "values": [ [ "1", "1", "100000" ], [ "2", "2", "500000" ] ] } } ] }Clique em Executar. A resposta mostra o carimbo de data/hora da confirmação.
Execute uma consulta SQL ou uma chamada de leitura para buscar os valores que você acabou de gravar.
- Clique em
projects.instances.databases.sessions.executeSql. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "sql": "SELECT SingerId, AlbumId, MarketingBudget FROM Albums" }Clique em Executar. A resposta mostra duas linhas que contêm os valores
MarketingBudgetatualizados:"rows": [ [ "1", "1", "100000" ], [ "1", "2", null ], [ "2", "1", null ], [ "2", "2", "500000" ], [ "2", "3", null ] ]
Usar um índice secundário
Para buscar todas as linhas de Albums que têm valores de AlbumTitle em um determinado intervalo, leia todos os valores da coluna AlbumTitle usando uma instrução SQL ou uma chamada de leitura e descarte as linhas que não atendem aos critérios. No entanto, essa varredura completa da tabela é cara, especialmente para tabelas com muitas linhas. Para acelerar a recuperação de linhas ao pesquisar por colunas de chaves não primárias, crie um índice secundário na tabela.
Adicionar um índice secundário a uma tabela requer uma atualização de esquema. Assim como outras atualizações de esquema, o Spanner permite adicionar um índice enquanto o banco de dados continua a disponibilizar o tráfego. O Spanner preenche automaticamente o índice com seus dados atuais. Os preenchimentos podem levar alguns minutos para serem concluídos, mas você não precisa ficar off-line ou evitar gravar em determinadas tabelas ou colunas durante esse processo. Para mais informações, consulte preenchimento de índices.
Depois que você adiciona um índice secundário, o Spanner o usa automaticamente para consultas SQL que são executadas mais rapidamente com o índice. Se você usar a interface de leitura, especifique o índice que quer usar.
Adicionar um índice secundário
Adicione um índice usando updateDdl.
- Clique em
projects.instances.databases.updateDdl. Para o banco de dados, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-dbPara o Corpo de solicitação, use o seguinte código:
{ "statements": [ "CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)" ] }Clique em Executar. Isso pode levar alguns minutos para ser concluído, mesmo após a resposta ter sido retornada pela chamada REST. A resposta retorna uma operação de longa duração. Consulte essa operação para verificar o status dela.
Consultar usando o índice
- Clique em
projects.instances.databases.sessions.executeSql. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "sql": "SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums WHERE AlbumTitle >= 'Aardvark' AND AlbumTitle < 'Goo'" }Clique em Executar. A resposta mostra as seguintes linhas:
"rows": [ [ "2", "Go, Go, Go", null ], [ "2", "Forever Hold Your Peace", "500000" ] ]
Ler usando o índice
- Clique em
projects.instances.databases.sessions.read. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "table": "Albums", "columns": [ "AlbumId", "AlbumTitle" ], "keySet": { "all": true }, "index": "AlbumsByAlbumTitle" }Clique em Executar. A resposta mostra as seguintes linhas:
"rows": [ [ "2", "Forever Hold Your Peace" ], [ "2", "Go, Go, Go" ], [ "1", "Green" ], [ "3", "Terrified" ], [ "1", "Total Junk" ] ]
Adicionar um índice com a cláusula STORING
O exemplo de leitura anterior não incluiu a coluna MarketingBudget. Isso ocorre porque a interface de leitura do Spanner não é compatível com a junção de um índice a uma tabela de dados para pesquisar valores que não estão armazenados no índice.
Crie uma definição alternativa de AlbumsByAlbumTitle que armazene uma cópia de MarketingBudget no índice.
Adicione um índice STORING usando updateDdl.
- Clique em
projects.instances.databases.updateDdl. Para o banco de dados, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-dbPara o Corpo de solicitação, use o seguinte código:
{ "statements": [ "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)" ] }Clique em Executar. Isso pode levar alguns minutos para ser concluído, mesmo após a resposta ter sido retornada pela chamada REST. A resposta retorna uma operação de longa duração. Consulte essa operação para verificar o status dela.
Agora, execute uma leitura que busque todas as colunas AlbumId, AlbumTitle e MarketingBudget do índice AlbumsByAlbumTitle2:
- Clique em
projects.instances.databases.sessions.read. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "table": "Albums", "columns": [ "AlbumId", "AlbumTitle", "MarketingBudget" ], "keySet": { "all": true }, "index": "AlbumsByAlbumTitle2" }Clique em Executar. A resposta mostra as seguintes linhas:
"rows": [ [ "2", "Forever Hold Your Peace", "500000" ], [ "2", "Go, Go, Go", null ], [ "1", "Green", null ], [ "3", "Terrified", null ], [ "1", "Total Junk", "100000" ] ]
Recuperar dados usando transações somente leitura
Para executar mais de uma leitura no mesmo carimbo de data/hora, use transações somente leitura. Essas transações seguem um prefixo consistente do histórico de confirmações da transação. Portanto, o aplicativo sempre recebe dados consistentes.
Criar uma transação somente leitura
- Clique em
projects.instances.databases.sessions.beginTransaction. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "options": { "readOnly": {} } }Clique em Executar.
A resposta mostra o código da transação que você criou.
Use a transação somente leitura para recuperar dados em um carimbo de data/hora consistente, mesmo que os dados tenham mudado depois da criação da transação somente leitura.
Executar uma consulta usando a transação somente leitura
- Clique em
projects.instances.databases.sessions.executeSql. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "sql": "SELECT SingerId, AlbumId, AlbumTitle FROM Albums", "transaction": { "id": "<var>TRANSACTION_ID</var>" } }Clique em Executar. A resposta mostra linhas semelhantes a estas:
"rows": [ [ "2", "2", "Forever Hold Your Peace" ], [ "1", "2", "Go, Go, Go" ], [ "2", "1", "Green" ], [ "2", "3", "Terrified" ], [ "1", "1", "Total Junk" ] ]
Fazer leitura usando a transação somente leitura
- Clique em
projects.instances.databases.sessions.read. Para a sessão, digite:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>Para o Corpo de solicitação, use o seguinte:
{ "table": "Albums", "columns": [ "SingerId", "AlbumId", "AlbumTitle" ], "keySet": { "all": true }, "transaction": { "id": "<var>TRANSACTION_ID</var>" } }Clique em Executar. A resposta mostra linhas semelhantes a estas:
"rows": [ [ "1", "1", "Total Junk" ], [ "1", "2", "Go, Go, Go" ], [ "2", "1", "Green" ], [ "2", "2", "Forever Hold Your Peace" ], [ "2", "3", "Terrified" ] ]
O Spanner também é compatível com transações de leitura e gravação, que executam atomicamente um conjunto de leituras e gravações em um único ponto lógico no tempo. Para mais informações, consulte Transações de leitura e gravação. (A funcionalidade Faça um teste! não é adequada para demonstrar uma transação de leitura e gravação.)
Limpeza
Para evitar cobranças extras na sua conta do Google Cloud pelos recursos usados neste tutorial, descarte o banco de dados e exclua a instância criada.
Remover um banco de dados
- Clique em
projects.instances.databases.dropDatabase. Para o nome, insira:
projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-dbClique em Executar.
Excluir uma instância
- Clique em
projects.instances.delete. Para o nome, insira:
projects/<var>PROJECT_ID</var>/instances/test-instanceClique em Executar.
A seguir
- Acesse o Spanner em uma instância de máquina virtual: crie uma instância de máquina virtual com acesso ao seu banco de dados do Spanner.
- Saiba mais sobre os conceitos do Spanner.