Crie uma tabela externa do Bigtable

Esta página descreve como criar uma tabela externa permanente do BigQuery que pode ser usada para consultar dados armazenados no Bigtable. A consulta de dados no Bigtable está disponível em todas as localizações do Bigtable.

Antes de começar

Antes de criar uma tabela externa, reúna algumas informações e certifique-se de que tem autorização para criar a tabela.

Funções necessárias

Para criar uma tabela externa a usar para consultar os seus dados do Bigtable, tem de ser um principal na função de administrador do Bigtable (roles/bigtable.admin) para a instância que contém a tabela de origem.

Também precisa da autorização bigquery.tables.create BigQuery Identity and Access Management (IAM).

Cada uma das seguintes funções de gestão de identidade e acesso predefinidas inclui esta autorização:

  • Editor de dados do BigQuery (roles/bigquery.dataEditor)
  • Proprietário de dados do BigQuery (roles/bigquery.dataOwner)
  • Administrador do BigQuery (roles/bigquery.admin)

Se não for um principal em nenhuma destas funções, peça ao seu administrador para lhe conceder acesso ou criar a tabela externa por si.

Para mais informações sobre as funções e as autorizações de gestão de identidades e acessos no BigQuery, consulte o artigo Funções e autorizações predefinidas. Para ver informações sobre as autorizações do Bigtable, consulte o artigo Controlo de acesso com a gestão de identidades e acessos. Para ver as funções necessárias para consultar a tabela externa, consulte o artigo Consulte dados do Bigtable.

Crie ou identifique um conjunto de dados

Antes de criar uma tabela externa, tem de criar um conjunto de dados para conter a tabela externa. Também pode usar um conjunto de dados existente.

Planeie a utilização de computação

Determine o tipo de computação que quer usar quando consulta os seus dados. Especifica que quer usar o aumento de dados ou que quer encaminhar para um cluster dedicado nas definições do perfil da app.

Aumento de dados

Para evitar afetar o tráfego de publicação da sua aplicação, pode usar a computação sem servidor do Data Boost quando usa uma tabela externa do BigQuery para ler os seus dados do Bigtable. Para usar o aumento de dados, tem de usar um perfil da app de aumento de dados e incluir o ID do perfil da app quando compõe o URI do Bigtable. Para mais informações acerca do Data Boost, consulte a vista geral do Data Boost do Bigtable.

Nós aprovisionados

Se não usar o Data Boost, os nós de cluster são usados para o cálculo.

Se não usar o Data Boost e planear consultar frequentemente os mesmos dados que servem a sua aplicação de produção, recomendamos que designe um cluster na sua instância do Bigtable para ser usado exclusivamente para análise do BigQuery. Isto isola o tráfego do cluster ou dos clusters que usa para as leituras e as escritas da sua aplicação. Para saber mais acerca da replicação e da criação de instâncias com mais do que um cluster, consulte Acerca da replicação.

Identifique ou crie um perfil de app

Antes de criar uma tabela externa, decida que perfil de app do Bigtable o BigQuery deve usar para ler os dados. Recomendamos que use um perfil de app que designe para utilização apenas com o BigQuery. O perfil da app pode ser um perfil da app padrão ou um perfil da app Data Boost, consoante o tipo de computação que quer usar para consultar os seus dados.

Se tiver um cluster na sua instância do Bigtable dedicado ao acesso do BigQuery, configure o perfil da app para usar o encaminhamento de cluster único para esse cluster.

Para usar a computação sem servidor do Data Boost, crie um perfil da app do Data Boost. Para usar nós de cluster para computação, crie um perfil de app padrão. Para saber como funcionam os perfis de apps do Bigtable, consulte o artigo Acerca dos perfis de apps. Para ver como criar um novo perfil de app, consulte o artigo Crie e configure perfis de apps.

Recupere o URI do Bigtable

Para criar uma tabela externa para uma origem de dados do Bigtable, tem de fornecer o URI do Bigtable. Para obter o URI do Bigtable, faça o seguinte:

  1. Abra a página do Bigtable na consola.

    Aceda ao Bigtable

  2. Recupere os seguintes detalhes acerca da sua origem de dados do Bigtable:

    • O ID do seu projeto.
    • O ID da instância do Bigtable.
    • O ID do perfil da app do Bigtable que planeia usar. Pode ser um perfil de app padrão ou um perfil de app Data Boost, consoante o tipo de computação que quer usar. Se não especificar um ID do perfil da app, é usado o perfil da app predefinido.
    • O nome da sua tabela do Bigtable.
  3. Componha o URI do Bigtable com o seguinte formato, em que:

    • PROJECT_ID é o projeto que contém a sua instância do Bigtable
    • INSTANCE_ID é o ID da instância do Bigtable
    • APP_PROFILE (opcional) é o identificador do perfil da app que quer usar
    • TABLE_NAME é o nome da tabela que está a consultar

    https://googleapis.com/bigtable/projects/PROJECT_ID/instances/INSTANCE_ID[/appProfiles/APP_PROFILE]/tables/TABLE_NAME

Crie tabelas externas permanentes

Quando cria uma tabela externa permanente no BigQuery que está associada a uma origem de dados do Bigtable, existem duas opções para especificar o formato da tabela externa:

  • Se estiver a usar a API ou a ferramenta de linha de comandos bq, cria um ficheiro de definição de tabela que define o esquema e os metadados da tabela externa.
  • Se estiver a usar SQL, usa a opção uri da declaração CREATE EXTERNAL TABLE para especificar a tabela do Bigtable a partir da qual extrair dados e a opção bigtable_options para especificar o esquema da tabela.

Os dados da tabela externa não estão armazenados na tabela do BigQuery. Uma vez que a tabela é permanente, pode usar controlos de acesso ao nível do conjunto de dados para partilhar a tabela com outras pessoas que também tenham acesso à origem de dados do Bigtable subjacente.

Para criar uma tabela permanente, escolha um dos seguintes métodos.

SQL

Pode criar uma tabela externa permanente executando a declaração DDL CREATE EXTERNAL TABLE. Tem de especificar o esquema da tabela explicitamente como parte das opções da declaração.

  1. Na Google Cloud consola, aceda à página BigQuery.

    Aceda ao BigQuery

  2. No editor de consultas, introduza a seguinte declaração:

    CREATE EXTERNAL TABLE DATASET.NEW_TABLE
    OPTIONS (
      format = 'CLOUD_BIGTABLE',
      uris = ['URI'],
      bigtable_options = BIGTABLE_OPTIONS );

    Substitua o seguinte:

    • DATASET: o conjunto de dados no qual criar a tabela externa do Bigtable.
    • NEW_TABLE: o nome da tabela externa do Bigtable.
    • URI: o URI da tabela do Bigtable que quer usar como origem de dados. Este URI tem de seguir o formato descrito em Obter o URI do Bigtable.
    • BIGTABLE_OPTIONS: o esquema da tabela do Bigtable no formato JSON. Para ver uma lista das opções de definição da tabela do Bigtable, consulte BigtableOptions na referência da API REST.

  3. Clique em Executar.

Para mais informações sobre como executar consultas, consulte o artigo Execute uma consulta interativa.

Uma declaração para criar uma tabela do Bigtable externa pode ter um aspeto semelhante ao seguinte:

CREATE EXTERNAL TABLE mydataset.BigtableTable
OPTIONS (
  format = 'CLOUD_BIGTABLE',
  uris = ['https://googleapis.com/bigtable/projects/myproject/instances/myBigtableInstance/appProfiles/myAppProfile/tables/table1'],
  bigtable_options =
    """
    {
      columnFamilies: [
        {
          "familyId": "familyId1",
          "type": "INTEGER",
          "encoding": "BINARY"
        }
      ],
      readRowkeyAsString: true
    }
    """
);

bq

Cria uma tabela na ferramenta de linhas de comando bq através do comando bq mk. Quando usa a ferramenta de linha de comandos bq para criar uma tabela associada a uma origem de dados externa, identifica o esquema da tabela através de um ficheiro de definição de tabela.

  1. Use o comando bq mk para criar uma tabela permanente.

    bq mk \
    --external_table_definition=DEFINITION_FILE \
    DATASET.TABLE

    Substitua o seguinte:

    • DEFINITION_FILE: o caminho para o ficheiro de definição da tabela no seu computador local.
    • DATASET: o nome do conjunto de dados que contém a tabela.
    • TABLE: o nome da tabela que está a criar.

API

Use o método da API tables.insert e crie um ExternalDataConfiguration no recurso Table que transmite.

Para a propriedade sourceUris no recurso Table, especifique apenas um URI do Bigtable. Tem de ser um URL HTTPS válido.

Para a propriedade sourceFormat, especifique "BIGTABLE".

Java

Antes de experimentar este exemplo, siga as Javainstruções de configuração no início rápido do BigQuery com bibliotecas cliente. Para mais informações, consulte a API Java BigQuery documentação de referência.

Para se autenticar no BigQuery, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para bibliotecas de cliente.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.BigtableColumn;
import com.google.cloud.bigquery.BigtableColumnFamily;
import com.google.cloud.bigquery.BigtableOptions;
import com.google.cloud.bigquery.ExternalTableDefinition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;
import org.apache.commons.codec.binary.Base64;

// Sample to queries an external bigtable data source using a permanent table
public class QueryExternalBigtablePerm {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String bigtableInstanceId = "MY_INSTANCE_ID";
    String bigtableTableName = "MY_BIGTABLE_NAME";
    String bigqueryDatasetName = "MY_DATASET_NAME";
    String bigqueryTableName = "MY_TABLE_NAME";
    String sourceUri =
        String.format(
            "https://googleapis.com/bigtable/projects/%s/instances/%s/tables/%s",
            projectId, bigtableInstanceId, bigtableTableName);
    String query = String.format("SELECT * FROM %s ", bigqueryTableName);
    queryExternalBigtablePerm(bigqueryDatasetName, bigqueryTableName, sourceUri, query);
  }

  public static void queryExternalBigtablePerm(
      String datasetName, String tableName, String sourceUri, String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      BigtableColumnFamily.Builder statsSummary = BigtableColumnFamily.newBuilder();

      // Configuring Columns
      BigtableColumn connectedCell =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("connected_cell".getBytes()))
              .setFieldName("connected_cell")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();
      BigtableColumn connectedWifi =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("connected_wifi".getBytes()))
              .setFieldName("connected_wifi")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();
      BigtableColumn osBuild =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("os_build".getBytes()))
              .setFieldName("os_build")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();

      // Configuring column family and columns
      statsSummary
          .setColumns(ImmutableList.of(connectedCell, connectedWifi, osBuild))
          .setFamilyID("stats_summary")
          .setOnlyReadLatest(true)
          .setEncoding("TEXT")
          .setType("STRING")
          .build();

      // Configuring BigtableOptions is optional.
      BigtableOptions options =
          BigtableOptions.newBuilder()
              .setIgnoreUnspecifiedColumnFamilies(true)
              .setReadRowkeyAsString(true)
              .setColumnFamilies(ImmutableList.of(statsSummary.build()))
              .build();

      TableId tableId = TableId.of(datasetName, tableName);
      // Create a permanent table linked to the Bigtable table
      ExternalTableDefinition externalTable =
          ExternalTableDefinition.newBuilder(sourceUri, options).build();
      bigquery.create(TableInfo.of(tableId, externalTable));

      // Example query
      TableResult results = bigquery.query(QueryJobConfiguration.of(query));

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));

      System.out.println("Query on external permanent table performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Consultar tabelas externas

Para mais informações, consulte o artigo Consultar dados do Bigtable.

Esquema gerado

Por predefinição, o BigQuery expõe os valores numa família de colunas como uma matriz de colunas e, dentro dessa matriz, uma matriz de valores escritos em diferentes datas/horas. Este esquema preserva a disposição natural dos dados no Bigtable, mas as consultas SQL podem ser difíceis. É possível promover colunas a subcampos na família de colunas principal e ler apenas o valor mais recente de cada célula. Isto representa ambas as matrizes no esquema predefinido como valores escalares.

Exemplo

Está a armazenar perfis de utilizadores para uma rede social fictícia. Um modelo de dados para isto pode ser uma família de colunas profile com colunas individuais para gender, age e email:

rowkey | profile:gender| profile:age| profile:email
-------| --------------| -----------| -------------
alice  | female        | 30         | alice@gmail.com

Usando o esquema predefinido, uma consulta GoogleSQL para contar o número de utilizadores do género masculino com mais de 30 anos é:

SELECT
  COUNT(1)
FROM
  `dataset.table`
OMIT
  RECORD IF NOT SOME(profile.column.name = "gender"
    AND profile.column.cell.value = "male")
  OR NOT SOME(profile.column.name = "age"
    AND INTEGER(profile.column.cell.value) > 30)

A consulta dos dados é menos desafiante se gender e age forem expostos como subcampos. Para os expor como subcampos, liste gender e age como colunas com nome na família de colunas profile ao definir a tabela. Também pode instruir o BigQuery a expor os valores mais recentes desta família de colunas, porque, normalmente, apenas o valor mais recente (e, possivelmente, o único valor) é de interesse.

Depois de expor as colunas como subcampos, a consulta GoogleSQL para contar o número de utilizadores masculinos com mais de 30 anos é:

SELECT
  COUNT(1)
FROM
  `dataset.table`
WHERE
  profile.gender.cell.value="male"
  AND profile.age.cell.value > 30

Repare como gender e age são referenciados diretamente como campos. A configuração JSON para esta configuração é:

  "bigtableOptions": {
    "readRowkeyAsString": "true",
    "columnFamilies": [
      {
          "familyId": "profile",
          "onlyReadLatest": "true",
          "columns": [
              {
                  "qualifierString": "gender",
                  "type": "STRING"
              },
              {
                  "qualifierString": "age",
                  "type": "INTEGER"
              }
          ]
      }
    ]
  }

Codificação de valores

O Bigtable armazena os dados como bytes não processados, independentemente da codificação de dados. No entanto, os valores de bytes são de utilização limitada na análise de consultas SQL. O Bigtable oferece dois tipos básicos de descodificação escalar: texto e HBase-binary.

O formato de texto pressupõe que todos os valores são armazenados como strings de texto alfanuméricas. Por exemplo, um número inteiro 768 é armazenado como a string "768". A codificação binária assume que a classe de métodos Bytes.toBytes do HBase foi usada para codificar os dados e aplica um método de descodificação adequado.

Regiões e zonas compatíveis

A consulta de dados no Bigtable está disponível em todas as zonas do Bigtable suportadas. Pode encontrar a lista de zonas aqui. Para instâncias de vários clusters, o BigQuery encaminha o tráfego com base nas definições do perfil da app do Bigtable.

Limitações

  • Não pode criar tabelas externas sobre objetos baseados em SQL do Bigtable, como vistas e vistas materializadas contínuas.
  • Para mais informações sobre as limitações aplicáveis a tabelas externas, consulte o artigo Limitações das tabelas externas.

Âmbitos para instâncias do Compute Engine

Quando cria uma instância do Compute Engine, pode especificar uma lista de âmbitos para a instância. Os âmbitos controlam o acesso da instância aos Google Cloud produtos, incluindo o Bigtable. As aplicações executadas na VM usam a conta de serviço para chamar as APIs Google Cloud .

Se configurar uma instância do Compute Engine para ser executada como uma conta de serviço, e essa conta de serviço aceder a uma tabela externa associada a uma origem de dados do Bigtable, tem de adicionar o âmbito de acesso aos dados só de leitura (https://www.googleapis.com/auth/bigtable.data.readonly) à instância. Para mais informações, consulte o artigo Criar uma instância do Compute Engine para o Bigtable.

Para ver informações sobre a aplicação de âmbitos a uma instância do Compute Engine, consulte Alterar a conta de serviço e os âmbitos de acesso de uma instância. Para mais informações sobre as contas de serviço do Compute Engine, consulte o artigo Contas de serviço.

O que se segue?