Crea una tabella esterna Bigtable

Questa pagina descrive come creare una tabella esterna permanente BigQuery da utilizzare per eseguire query sui dati archiviati in Bigtable. L'esecuzione di query sui dati in Bigtable è disponibile in tutte le località di Bigtable.

Prima di iniziare

Prima di creare una tabella esterna, raccogli alcune informazioni e assicurati di avere l'autorizzazione per crearla.

Ruoli obbligatori

Per creare una tabella esterna da utilizzare per eseguire query sui dati Bigtable, devi essere un'entità nel ruolo Amministratore Bigtable (roles/bigtable.admin) per l'istanza che contiene la tabella di origine.

È necessaria anche l'autorizzazione bigquery.tables.create BigQuery Identity and Access Management (IAM).

Ciascuno dei seguenti ruoli predefiniti di Identity and Access Management include questa autorizzazione:

  • Editor dati BigQuery (roles/bigquery.dataEditor)
  • Proprietario dati BigQuery (roles/bigquery.dataOwner)
  • Amministratore BigQuery (roles/bigquery.admin)

Se non sei un'entità in uno di questi ruoli, chiedi all'amministratore di concederti l'accesso o di creare la tabella esterna per te.

Per ulteriori informazioni sui ruoli e sulle autorizzazioni di Identity and Access Management in BigQuery, consulta Ruoli e autorizzazioni predefiniti. Per visualizzare le informazioni sulle autorizzazioni di Bigtable, vedi Controllo dell'accesso con Identity and Access Management.

Creare o identificare un set di dati

Prima di creare una tabella esterna, devi creare un set di dati che contenga la tabella esterna. Puoi anche usare un set di dati esistente.

(Facoltativo) Specifica o crea un cluster

Se prevedi di eseguire query frequenti sugli stessi dati che gestiscono la tua applicazione di produzione, ti consigliamo di indicare un cluster nell'istanza Bigtable in modo che venga utilizzato esclusivamente per l'analisi di BigQuery. Questo isola il traffico dal cluster o dai cluster che utilizzi per le letture e le scritture dell'applicazione. Per saperne di più sulla replica e sulla creazione di istanze che hanno più di un cluster, consulta Informazioni sulla replica.

Identifica o crea un profilo di app

Prima di creare una tabella esterna, decidi quale profilo app Bigtable deve essere utilizzato da BigQuery per leggere i dati. Ti consigliamo di utilizzare un profilo applicazione designato per l'utilizzo solo con BigQuery.

Se nell'istanza Bigtable è presente un cluster dedicato all'accesso a BigQuery, configura il profilo dell'app in modo da utilizzare il routing a cluster singolo verso quel cluster.

Per sapere come funzionano i profili di app Bigtable, consulta Informazioni sui profili di app. Per scoprire come creare un nuovo profilo di app, consulta Creare e configurare profili di app.

Recupera l'URI Bigtable

Per creare una tabella esterna per un'origine dati Bigtable, devi fornire l'URI Bigtable. Per recuperare l'URI di Bigtable:

  1. Apri la pagina Bigtable nella console.

    Vai a Bigtable

  2. Recupera i seguenti dettagli sull'origine dati Bigtable:

    • Il tuo ID progetto
    • ID istanza Bigtable
    • L'ID del profilo dell'app Bigtable che prevedi di utilizzare
    • Il nome della tabella Bigtable
  3. Scrivi l'URI Bigtable utilizzando il seguente formato, dove:

    • project_id è il progetto contenente l'istanza Bigtable
    • instance_id è l'ID istanza Bigtable
    • (Facoltativo) app_profile è l'ID profilo dell'app che vuoi utilizzare
    • table_name è il nome della tabella su cui stai eseguendo la query

    https://googleapis.com/bigtable/projects/project_id/instances/instance_id[/appProfiles/app_profile]/tables/table_name

Crea tabelle esterne permanenti

Quando crei una tabella esterna permanente in BigQuery collegata a un'origine dati Bigtable, esistono due opzioni per specificare il formato della tabella esterna:

  • Se utilizzi l'API o lo strumento a riga di comando bq, crea un file di definizione della tabella che definisce lo schema e i metadati per la tabella esterna.
  • Se utilizzi SQL, utilizza l'opzione uri dell'istruzione CREATE EXTERNAL TABLE per specificare la tabella Bigtable da cui estrarre i dati e l'opzione bigtable_options per specificare lo schema della tabella.

I dati della tabella esterna non vengono archiviati nella tabella BigQuery. Poiché la tabella è permanente, puoi utilizzare i controlli dell'accesso a livello di set di dati per condividere la tabella con altri utenti che hanno anche accesso all'origine dati Bigtable sottostante.

Per creare una tabella permanente, scegli uno dei seguenti metodi.

SQL

Puoi creare una tabella esterna permanente eseguendo l'istruzione DDL CREATE EXTERNAL TABLE. Devi specificare esplicitamente lo schema della tabella all'interno delle opzioni di istruzione.

  1. Nella console Google Cloud, vai alla pagina BigQuery.

    Vai a BigQuery

  2. Nell'Editor query, inserisci la seguente istruzione:

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

    Sostituisci quanto segue:

    • DATASET: il set di dati in cui creare la tabella esterna Bigtable.
    • NEW_TABLE: il nome della tabella esterna di Bigtable.
    • URI: l'URI della tabella Bigtable che vuoi utilizzare come origine dati. Questo URI deve seguire il formato descritto in Recupero dell'URI Bigtable.
    • BIGTABLE_OPTIONS: lo schema per la tabella Bigtable in formato JSON. Per un elenco delle opzioni di definizione delle tabelle Bigtable, vedi BigtableOptions nel riferimento dell'API REST.

  3. Fai clic su Esegui.

Per ulteriori informazioni su come eseguire le query, consulta Eseguire una query interattiva.

Un'istruzione per creare una tabella Bigtable esterna potrebbe essere simile alla seguente:

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

bq

Puoi creare una tabella nello strumento a riga di comando bq utilizzando il comando bq mk. Quando utilizzi lo strumento a riga di comando bq per creare una tabella collegata a un'origine dati esterna, identifichi lo schema della tabella tramite un file di definizione della tabella.

  1. Usa il comando bq mk per creare una tabella permanente.

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

    Sostituisci quanto segue:

    • DEFINITION_FILE: il percorso del file di definizione della tabella sulla macchina locale.
    • DATASET: il nome del set di dati che contiene la tabella.
    • TABLE: il nome della tabella che stai creando.

API

Utilizza il metodo API tables.insert e crea un ExternalDataConfiguration nella risorsa Table che passi.

Per la proprietà sourceUris nella risorsa Table, specifica un solo URI Bigtable. Deve essere un URL HTTPS valido.

Per la proprietà sourceFormat, specifica "BIGTABLE".

Java

Prima di provare questo esempio, segui le istruzioni di configurazione di Java disponibili nella guida rapida di BigQuery sull'utilizzo delle librerie client. Per saperne di più, consulta la documentazione di riferimento dell'API BigQuery Java.

Per eseguire l'autenticazione in BigQuery, configura Credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per le librerie client.

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());
    }
  }
}

Esegui query su tabelle esterne

Per maggiori informazioni, consulta Eseguire query sui dati di Bigtable.

Schema generato

Per impostazione predefinita, BigQuery espone i valori in una famiglia di colonne sotto forma di array di colonne e al suo interno un array di valori scritti con timestamp diversi. Questo schema conserva il layout naturale dei dati in Bigtable, ma le query SQL possono essere impegnative. È possibile promuovere le colonne in campi secondari all'interno della famiglia di colonne padre e leggere solo il valore più recente di ogni cella. Rappresenta entrambi gli array nello schema predefinito come valori scalari.

Esempio

Stai memorizzando i profili utente per un social network fittizio. Un modello dei dati per questo potrebbe essere una famiglia di colonne profile con singole colonne per gender, age e email:

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

Utilizzando lo schema predefinito, una query GoogleSQL per conteggiare il numero di utenti di sesso maschile oltre i 30 anni è:

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)

L'esecuzione di query sui dati è meno impegnativa se gender e age sono esposti come sottocampi. Per esporle come campi secondari, elenca gender e age come colonne denominate nella famiglia di colonne profile quando definisci la tabella. Puoi anche indicare a BigQuery di esporre i valori più recenti di questa famiglia di colonne perché in genere è interessato solo il valore più recente (e probabilmente l'unico).

Dopo aver esposto le colonne come sottocampi, la query GoogleSQL per conteggiare il numero di utenti di sesso maschile oltre i 30 anni è:

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

Osserva come si fa riferimento direttamente a gender e age come campi. La configurazione JSON per questa impostazione è:

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

Codifica dei valori

Bigtable archivia i dati come byte non elaborati, indipendentemente dalla codifica dei dati. Tuttavia, i valori in byte sono di uso limitato nell'analisi delle query SQL. Bigtable offre due tipi di base di decodifica scalare: testo e binaria HBase.

Il formato di testo presuppone che tutti i valori siano memorizzati come stringhe di testo alfanumeriche. Ad esempio, un numero intero 768 verrà memorizzato come stringa "768". La codifica binaria presuppone che i metodi della classe Bytes.toBytes di HBase siano stati utilizzati per codificare i dati e applica un metodo di decodifica appropriato.

Regioni e zone supportate

L'esecuzione di query sui dati in Bigtable è disponibile in tutte le zone di Bigtable. Puoi trovare l'elenco delle zone qui. Per le istanze multi-cluster, BigQuery instrada il traffico in base alle impostazioni del profilo di app di Bigtable.

Limitazioni

Per informazioni sulle limitazioni che si applicano alle tabelle esterne, consulta Limitazioni delle tabelle esterne.

Ambiti per le istanze di Compute Engine

Quando crei un'istanza di Compute Engine, puoi specificare un elenco di ambiti per l'istanza. Gli ambiti controllano l'accesso dell'istanza ai prodotti Google Cloud, tra cui Bigtable. Le applicazioni in esecuzione sulla VM utilizzano l'account di servizio per le chiamate alle API Google Cloud.

Se configuri un'istanza Compute Engine per l'esecuzione come account di servizio e l'account di servizio accede a una tabella esterna collegata a un'origine dati Bigtable, devi aggiungere l'ambito di accesso ai dati di sola lettura di Bigtable (https://www.googleapis.com/auth/bigtable.data.readonly) all'istanza. Per ulteriori informazioni, consulta Creazione di un'istanza di Compute Engine per Bigtable.

Per informazioni sull'applicazione degli ambiti a un'istanza di Compute Engine, consulta Modifica dell'account di servizio e degli ambiti di accesso per un'istanza. Per ulteriori informazioni sugli account di servizio Compute Engine, consulta Account di servizio.

Passaggi successivi