Introdução ao Spanner com REST

Objetivos

Este tutorial explica os seguintes passos através da API Cloud Spanner com REST:

  • Crie uma instância e uma base de dados do Spanner.
  • Escrever, ler e executar consultas SQL em dados na base de dados.
  • Atualize o esquema da base de dados.
  • Adicione um índice secundário à base de dados.
  • Use o índice para ler e executar consultas SQL em dados.
  • Obtenha dados através de uma transação só de leitura.

Se quiser usar as bibliotecas de cliente do Spanner em vez da API REST, consulte os tutoriais.

Custos

Este tutorial usa o Spanner, que é um componente faturável do Google Cloud. Para obter informações sobre o custo de utilização do Spanner, consulte a secção Preços.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Formas de fazer chamadas REST

    Pode fazer chamadas REST do Spanner através de:

    Convenções usadas nesta página

    • Os exemplos usam <var>PROJECT_ID</var> como o Google Cloud ID do projeto. Substitua o seu Google Cloud ID do projeto por <var>PROJECT_ID</var>.

    • Os exemplos criam e usam um ID de instância de test-instance. Substitua o ID da instância se não estiver a usar test-instance.

    • Os exemplos criam e usam um ID da base de dados de example-db. Substitua o ID da base de dados se não estiver a usar example-db.

    • Os exemplos usam <var>SESSION</var> como parte de um nome de sessão. Substitua o valor que recebe quando cria uma sessão para <var>SESSION</var>.

    • Os exemplos usam um ID da transação de <var>TRANSACTION_ID</var>. Substitua o valor que recebe quando cria uma transação para <var>TRANSACTION_ID</var>.

    • A funcionalidade Experimentar! suporta a adição interativa de campos de pedidos HTTP individuais. A maioria dos exemplos neste documento fornece o pedido completo em vez de descrever como adicionar interativamente campos individuais ao pedido.

    Instâncias

    Quando usar o Spanner pela primeira vez, crie uma instância. Uma instância atribui recursos que as bases de dados do Spanner usam. Quando cria uma instância, escolhe onde os seus dados são armazenados e a quantidade de capacidade de computação que a instância tem.

    Apresente configurações de instâncias

    Quando cria uma instância, especifica uma configuração da instância, que define o posicionamento geográfico e a replicação das suas bases de dados nessa instância. Escolha uma configuração regional para armazenar dados numa região ou uma configuração multirregional para distribuir dados por várias regiões. Saiba mais em Instâncias.

    Use projects.instanceConfigs.list para determinar que configurações estão disponíveis para o seu projeto Google Cloud .

    1. Clique em projects.instanceConfigs.list.
    2. Para o publicador principal, introduza:

      projects/PROJECT_ID

    3. Clique em Executar. A resposta mostra as configurações de instâncias disponíveis. Segue-se um exemplo de resposta (o seu projeto pode ter configurações de instância diferentes):

      { "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" } ] }
      

    Usa o valor name para uma das configurações de instância quando cria a instância.

    Crie uma instância

    1. Clique em projects.instances.create.
    2. Para o publicador principal, introduza:

      projects/<var>PROJECT_ID</var>
      
    3. Clique em Adicionar parâmetros do corpo do pedido e selecione instance.

    4. Clique no balão de sugestão para instance para ver os campos possíveis. Adicione valores para os seguintes campos:

      • nodeCount: introduza 1.
      • config: introduza o valor de name de uma das configurações da instância regional devolvidas quando listar as configurações da instância.
      • displayName: introduza Test Instance.
    5. Clique no balão de sugestão que segue o parênteses de fecho de instance e selecione instanceId.

    6. Para instanceId, introduza test-instance.
      A página de criação da instância Experimentar! deve agora ter o seguinte aspeto:

      Página de criação de instâncias na funcionalidade Experimente!

    7. Clique em Executar. A resposta devolve uma operação de longa duração. Consulte esta operação para verificar o respetivo estado.

    Apresente instâncias através de projects.instances.list.

    Crie uma base de dados

    Cria uma base de dados com o nome example-db.

    1. Clique em projects.instances.databases.create.
    2. Para o publicador principal, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance
      
    3. Clique em Adicionar parâmetros do corpo do pedido e selecione createStatement.

    4. Para createStatement, introduza:

      CREATE DATABASE `example-db`
      

    O nome da base de dados, example-db, contém um hífen, pelo que deve incluí-lo entre acentos graves (`).

    1. Clique em Executar. A resposta devolve uma operação de longa duração. Consulte esta operação para verificar o respetivo estado.

    Liste as suas bases de dados com o comando projects.instances.databases.list.

    Crie um esquema

    Use a linguagem de definição de dados (DDL) do Spanner para criar, alterar ou eliminar tabelas, bem como para criar ou eliminar índices.

    1. Clique em projects.instances.databases.updateDdl.
    2. Para base de dados, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db
      
    3. Para o corpo do pedido, 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 statements contém as declarações DDL que definem o esquema.

    4. Clique em Executar. A resposta devolve uma operação de longa duração. Consulte esta operação para verificar o respetivo estado.

    O esquema define duas tabelas, Singers e Albums, para uma aplicação de música básica. Este documento usa estas tabelas. Reveja o esquema de exemplo.

    Recupere o seu esquema através de projects.instances.databases.getDdl.

    Crie uma sessão

    Antes de adicionar, atualizar, eliminar ou consultar dados, crie uma sessão. Uma sessão representa um canal de comunicação com o serviço de base de dados do Spanner. (Não usa diretamente uma sessão se estiver a usar uma biblioteca de cliente do Spanner, porque a biblioteca de cliente gere as sessões em seu nome.)

    1. Clique em projects.instances.databases.sessions.create.
    2. Para base de dados, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db
      
    3. Clique em Executar.

    4. A resposta mostra a sessão que criou no formulário

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      

      Use esta sessão quando lê ou escreve na sua base de dados.

    As sessões destinam-se a ser de longa duração. O serviço de base de dados Spanner elimina uma sessão quando esta está inativa durante mais de uma hora. As tentativas de usar um resultado de sessão eliminado resultam em NOT_FOUND. Se encontrar este erro, crie e use uma nova sessão. Verifique se uma sessão ainda está ativa através de projects.instances.databases.sessions.get.

    Para informações relacionadas, consulte o artigo Mantenha uma sessão inativa ativa.

    As sessões são um conceito avançado. Para ver mais detalhes e práticas recomendadas, consulte o artigo Sessões.

    Em seguida, escreva dados na sua base de dados.

    Escrever dados

    Escreve dados usando o tipo Mutation. Um Mutation é um contentor para operações de mutação. Uma Mutation representa uma sequência de inserções, atualizações, eliminações e outras ações que se aplicam atomicamente a diferentes linhas e tabelas numa base de dados do Spanner.

    1. Clique em projects.instances.databases.sessions.commit.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, 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"
                 ]
               ]
             }
           }
         ]
       }
      
    4. Clique em Executar. A resposta mostra a data/hora da confirmação.

    Este exemplo usou insertOrUpdate. Outras operações para Mutations são insert, update, replace e delete.

    Para obter informações sobre como codificar tipos de dados, consulte TypeCode.

    Consultar dados através de SQL

    1. Clique em projects.instances.databases.sessions.executeSql.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "sql": "SELECT SingerId, AlbumId, AlbumTitle FROM Albums"
      }
      
    4. Clique em Executar. A resposta mostra os resultados da consulta.

    Leia dados através da API de leitura

    1. Clique em projects.instances.databases.sessions.read.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "table": "Albums",
        "columns": [
          "SingerId",
          "AlbumId",
          "AlbumTitle"
        ],
        "keySet": {
          "all": true
        }
      }
      
    4. Clique em Executar. A resposta mostra os resultados lidos.

    Atualize o esquema da base de dados

    Adicione uma nova coluna denominada MarketingBudget à tabela Albums. Isto requer uma atualização ao esquema da base de dados. O Spanner suporta atualizações de esquemas a uma base de dados enquanto a base de dados continua a servir tráfego. As atualizações do esquema não requerem a colocação da base de dados offline e não bloqueiam tabelas nem colunas inteiras. Pode continuar a escrever dados na base de dados durante a atualização do esquema.

    Adicione uma coluna

    1. Clique em projects.instances.databases.updateDdl.
    2. Para base de dados, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db
      
    3. Para o corpo do pedido, use o seguinte:

       {
         "statements": [
           "ALTER TABLE Albums ADD COLUMN MarketingBudget INT64"
         ]
       }
       ```
      
      The `statements` array contains the DDL statements that define the schema.
      
    4. Clique em Executar. Este processo pode demorar alguns minutos, mesmo depois de a chamada REST devolver uma resposta. A resposta devolve uma operação de longa duração. Consulte esta operação para verificar o respetivo estado.

    Escreva dados na nova coluna

    Este código escreve dados na nova coluna. Define MarketingBudget como 100000 para a linha identificada por Albums(1, 1) e como 500000 para a linha identificada por Albums(2, 2).

    1. Clique em projects.instances.databases.sessions.commit.
    2. Para sessão, introduza:

           projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      

      (Recebe este valor quando cria uma sessão.)

    3. Para o corpo do pedido, use o seguinte:

       {
         "singleUseTransaction": {
           "readWrite": {}
         },
         "mutations": [
           {
             "update": {
               "table": "Albums",
               "columns": [
                 "SingerId",
                 "AlbumId",
                 "MarketingBudget"
               ],
               "values": [
                 [
                   "1",
                   "1",
                   "100000"
                 ],
                 [
                   "2",
                   "2",
                   "500000"
                 ]
               ]
             }
           }
         ]
       }
      
    4. Clique em Executar. A resposta mostra a data/hora da confirmação.

    Execute uma consulta SQL ou uma chamada de leitura para obter os valores que acabou de escrever.

    1. Clique em projects.instances.databases.sessions.executeSql.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

       {
         "sql": "SELECT SingerId, AlbumId, MarketingBudget FROM Albums"
       }
      
    4. Clique em Executar. A resposta mostra duas linhas que contêm os valores MarketingBudget atualizados:

       "rows": [
         [
           "1",
           "1",
           "100000"
         ],
         [
           "1",
           "2",
           null
         ],
         [
           "2",
           "1",
           null
         ],
         [
           "2",
           "2",
           "500000"
         ],
         [
           "2",
           "3",
           null
         ]
       ]
      

    Use um índice secundário

    Para obter todas as linhas de Albums que tenham valores de AlbumTitle num determinado intervalo, leia todos os valores da coluna AlbumTitle através de uma declaração SQL ou de uma chamada de leitura e, em seguida, rejeite as linhas que não cumprem os critérios. No entanto, esta análise completa da tabela é dispendiosa, especialmente para tabelas com muitas linhas. Para acelerar a obtenção de linhas quando pesquisa por colunas de chaves não primárias, crie um índice secundário na tabela.

    A adição de um índice secundário a uma tabela existente requer uma atualização do esquema. Semelhante a outras atualizações de esquemas, o Spanner suporta a adição de um índice enquanto a base de dados continua a publicar tráfego. O Spanner repreenche automaticamente o índice com os seus dados existentes. Os preenchimentos podem demorar alguns minutos a serem concluídos, mas não precisa de colocar a base de dados offline nem evitar a escrita em determinadas tabelas ou colunas durante este processo. Para mais informações, consulte o artigo sobre o preenchimento do índice.

    Depois de adicionar um índice secundário, o Spanner usa-o automaticamente para consultas SQL que são executadas mais rapidamente com o índice. Se usar a interface read, especifique o índice que quer usar.

    Adicione um índice secundário

    Adicione um índice através de updateDdl.

    1. Clique em projects.instances.databases.updateDdl.
    2. Para base de dados, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db
      
    3. Para o corpo do pedido, use o seguinte:

      {
         "statements": [
           "CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)"
         ]
      }
      
    4. Clique em Executar. Este processo pode demorar alguns minutos, mesmo depois de a chamada REST devolver uma resposta. A resposta devolve uma operação de longa duração. Consulte esta operação para verificar o respetivo estado.

    Consultar através do índice

    1. Clique em projects.instances.databases.sessions.executeSql.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "sql": "SELECT AlbumId, AlbumTitle, MarketingBudget FROM Albums WHERE AlbumTitle >= 'Aardvark' AND AlbumTitle < 'Goo'"
      }
      
    4. Clique em Executar. A resposta mostra as seguintes linhas:

      "rows": [
         [
           "2",
           "Go, Go, Go",
           null
         ],
         [
           "2",
           "Forever Hold Your Peace",
           "500000"
         ]
      ]
      

    Leia através do índice

    1. Clique em projects.instances.databases.sessions.read.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
         "table": "Albums",
         "columns": [
           "AlbumId",
           "AlbumTitle"
         ],
         "keySet": {
           "all": true
         },
         "index": "AlbumsByAlbumTitle"
      }
      
    4. 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"
         ]
      ]
      

    Adicione um índice com a cláusula STORING

    O exemplo de leitura anterior não incluía a coluna MarketingBudget. Isto ocorre porque a interface de leitura do Spanner não suporta a associação de um índice a uma tabela de dados para procurar valores não armazenados no índice.

    Crie uma definição alternativa de AlbumsByAlbumTitle que armazene uma cópia de MarketingBudget no índice.

    Adicione um índice STORING com updateDdl.

    1. Clique em projects.instances.databases.updateDdl.
    2. Para base de dados, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "statements": [
          "CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)"
        ]
      }
      
    4. Clique em Executar. Este processo pode demorar alguns minutos, mesmo depois de a chamada REST devolver uma resposta. A resposta devolve uma operação de longa duração. Consulte esta operação para verificar o respetivo estado.

    Agora, execute uma leitura que obtenha todas as colunas AlbumId, AlbumTitle e MarketingBudget do índice AlbumsByAlbumTitle2:

    1. Clique em projects.instances.databases.sessions.read.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "table": "Albums",
        "columns": [
          "AlbumId",
          "AlbumTitle",
          "MarketingBudget"
        ],
        "keySet": {
          "all": true
        },
        "index": "AlbumsByAlbumTitle2"
      }
      
    4. 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"
         ]
      ]
      

    Obtenha dados através de transações só de leitura

    Para executar mais do que uma leitura na mesma data/hora, use transações só de leitura. Estas transações observam um prefixo consistente do histórico de confirmações de transações, pelo que a sua aplicação recebe sempre dados consistentes.

    Crie uma transação só de leitura

    1. Clique em projects.instances.databases.sessions.beginTransaction.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "options": {
          "readOnly": {}
        }
      }
      
    4. Clique em Executar.

    5. A resposta mostra o ID da transação que criou.

    Use a transação de leitura apenas para obter dados numa data/hora consistente, mesmo que os dados tenham sido alterados depois de criar a transação de leitura apenas.

    Execute uma consulta através da transação só de leitura

    1. Clique em projects.instances.databases.sessions.executeSql.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
        "sql": "SELECT SingerId, AlbumId, AlbumTitle FROM Albums",
        "transaction": {
          "id": "<var>TRANSACTION_ID</var>"
        }
      }
      
    4. Clique em Executar. A resposta mostra linhas semelhantes às seguintes:

      "rows": [
         [
           "2",
           "2",
           "Forever Hold Your Peace"
         ],
         [
           "1",
           "2",
           "Go, Go, Go"
         ],
         [
           "2",
           "1",
           "Green"
         ],
         [
           "2",
           "3",
           "Terrified"
         ],
         [
           "1",
           "1",
           "Total Junk"
         ]
      ]
      

    Leia através da transação só de leitura

    1. Clique em projects.instances.databases.sessions.read.
    2. Para sessão, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db/sessions/<var>SESSION</var>
      
    3. Para o corpo do pedido, use o seguinte:

      {
         "table": "Albums",
         "columns": [
           "SingerId",
           "AlbumId",
           "AlbumTitle"
         ],
         "keySet": {
           "all": true
         },
         "transaction": {
           "id": "<var>TRANSACTION_ID</var>"
         }
      }
      
    4. Clique em Executar. A resposta mostra linhas semelhantes às seguintes:

      "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 suporta transações de leitura/escrita, que executam um conjunto de leituras e escritas de forma atómica num único ponto lógico no tempo. Para mais informações, consulte o artigo Transações de leitura/escrita. (A funcionalidade Experimentar! não é adequada para demonstrar uma transação de leitura/escrita.)

    Limpeza

    Para evitar cobranças adicionais na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine a base de dados e a instância que criou.

    Elimine uma base de dados

    1. Clique em projects.instances.databases.dropDatabase.
    2. Para name, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance/databases/example-db
      
    3. Clique em Executar.

    Elimine uma instância

    1. Clique em projects.instances.delete.
    2. Para name, introduza:

      projects/<var>PROJECT_ID</var>/instances/test-instance
      
    3. Clique em Executar.

O que se segue?