Crea y usa tablas agrupadas

En este documento, se describe el proceso para crear y usar tablas agrupadas en BigQuery. Para obtener una descripción general de la compatibilidad con tablas agrupadas en BigQuery, consulta Introducción a las tablas agrupadas.

Limitaciones

Las tablas agrupadas en BigQuery están sujetas a las limitaciones siguientes:

  • El agrupamiento en clústeres solo es compatible con tablas particionadas.
  • Solo se admite SQL estándar para consultar las tablas agrupadas y escribir los resultados de consultas en tablas agrupadas.
  • Solo puedes especificar columnas de agrupamiento en clústeres cuando se crea una tabla.
  • Después de crear una tabla agrupada, no puedes modificar las columnas de agrupamiento en clústeres.
  • Las columnas de agrupamiento en clústeres deben ser de nivel superior, no se deben repetir y deben ser de uno de los tipos siguientes:

    • DATE
    • BOOL
    • GEOGRAPHY
    • INT64
    • NUMERIC
    • STRING
    • TIMESTAMP

    Para obtener más información sobre los tipos de datos, consulta Tipos de datos de SQL estándar.

  • Puedes especificar hasta cuatro columnas de agrupamiento en clústeres.

  • Cuando se usan columnas de tipo STRING para el agrupamiento en clústeres, BigQuery usa solo los primeros 1,024 caracteres a fin de agrupar los datos. Los valores de las columnas pueden tener más de 1,024 caracteres.

Crea tablas agrupadas

Por ahora, solo puedes agrupar en clústeres una tabla particionada. Esto incluye a las tablas particionadas por tiempo de transferencia y a las tablas particionadas por una columna TIMESTAMP o DATE.

Puedes crear una tabla particionada en BigQuery de las siguientes maneras:

Nombres de las tablas

Cuando creas una tabla en BigQuery, el nombre de la tabla debe ser único en cada conjunto de datos. El nombre de la tabla tiene las siguientes características:

  • Contiene hasta 1,024 caracteres
  • Contener letras (mayúsculas o minúsculas), números y guiones bajos

Permisos necesarios

Como mínimo, para crear una tabla, debes tener los siguientes permisos:

  • Permisos bigquery.tables.create para crear la tabla
  • bigquery.tables.updateData para escribir datos en la tabla mediante un trabajo de carga, de consulta o de copia
  • bigquery.jobs.create para ejecutar un trabajo de consulta, de carga o de copia que escriba datos en la tabla

Es posible que se necesiten permisos adicionales, como bigquery.tables.getData, para acceder a los datos que escribes en la tabla.

Las siguientes funciones predefinidas de Cloud IAM incluyen los permisos bigquery.tables.create y bigquery.tables.updateData:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

Las siguientes funciones predefinidas de Cloud IAM incluyen los permisos bigquery.jobs.create:

  • bigquery.user
  • bigquery.jobUser
  • bigquery.admin

Además, si un usuario tiene permisos bigquery.datasets.create, se le otorga el acceso bigquery.dataOwner cuando crea un conjunto de datos. Con el acceso bigquery.dataOwner, el usuario puede crear y actualizar tablas en el conjunto de datos.

Para obtener más información sobre las funciones de Cloud IAM y los permisos en BigQuery, consulta Funciones y permisos predefinidos.

Crea una tabla agrupada vacía con una definición de esquema

Cuando creas una tabla en BigQuery, especificas las columnas de agrupamiento en clústeres. Después de crear la tabla, puedes modificar las columnas de clústeres. Consulta Modifica la especificación de agrupamiento en clústeres para obtener más información. Solo puedes especificar columnas de agrupamiento en clústeres para una tabla particionada.

Las columnas de agrupamiento en clústeres deben ser de nivel superior, no se deben repetir y deben ser de uno de los tipos de datos simples siguientes:

  • DATE
  • BOOLEAN
  • GEOGRAPHY
  • INTEGER
  • NUMERIC
  • STRING
  • TIMESTAMP

Puedes especificar hasta cuatro columnas de agrupamiento en clústeres. Cuando especificas varias columnas, el orden de las columnas determina el orden de los datos. Por ejemplo, si la tabla está agrupada en las columnas a, b y c, los datos se ordenan en el mismo orden: primero por la columna a, luego por la b y, por último, por la columna c. Como práctica recomendada, coloca en primer lugar a la columna que se filtra o se agrega con mayor frecuencia.

El orden de las columnas de agrupamiento en clústeres también afecta el rendimiento y el precio de la consulta. Si deseas obtener más información sobre las prácticas recomendadas de consulta para tablas agrupadas, ve a la sección Consulta tablas agrupadas.

Para crear una tabla agrupada vacía con una definición de esquema, sigue estos pasos:

Console

  1. En Google Cloud Console, ve a la IU web de BigQuery.

    Ir a la IU web de BigQuery

  2. En el panel de navegación, en la sección Recursos, expande tu proyecto y selecciona un conjunto de datos.

  3. En el lado derecho de la ventana, en el panel de detalles, haz clic en Create table (Crear tabla).

    Botón Crear tabla.

  4. En la página Create table (Crear tabla), debajo de Source (Fuente), selecciona la opción Empty table (Tabla vacía) en Create table from (Crear tabla desde).

    Opción Crear tabla desde.

  5. En Destination (Destino), haz lo siguiente:

    • Para Nombre del conjunto de datos, selecciona el conjunto de datos apropiado y, en el campo Nombre de la tabla, escribe el nombre de la tabla que crearás.
    • Verifica que Tipo de tabla esté establecido en Tabla nativa.
  6. En Esquema, ingresa la definición del esquema.

    • Ingresa la información del esquema de forma manual de la siguiente manera:

      • Habilita Editar como texto (Edit as text) y, luego, ingresa el esquema de la tabla como un arreglo JSON.

      • Usa Agregar campo (Add field) para ingresar el esquema de forma manual.

  7. En Configuración de partición y agrupamiento en clústeres, selecciona Partición por campo y elige la columna DATE o TIMESTAMP. Esta opción no está disponible si el esquema no contiene una columna DATE o TIMESTAMP.

    Para crear una tabla particionada por tiempo de transferencia, selecciona Partición por tiempo de transferencia.

  8. De forma opcional, en Filtro de partición (Partitioning filter), haz clic en la casilla de verificación Exigir filtro de partición (Require partition filter) a fin de solicitar a los usuarios que incluyan una cláusula WHERE que especifique las particiones que deben consultarse. Exigir un filtro de partición puede reducir los costos y mejorar el rendimiento. Para obtener más información, lee la sección Consulta tablas particionadas.

  9. De forma opcional, en Orden de agrupamiento en clústeres, ingresa entre uno y cuatro nombres de columna separados por comas.

  10. De manera opcional, si deseas usar una clave de Cloud Key Management Service, haz clic en Opciones avanzadas y selecciona Clave administrada por el cliente en Encriptación. Si dejas establecida la configuración Clave administrada por Google, BigQuery encripta los datos en reposo.

  11. Haz clic en Crear tabla.

IU clásica

  1. Ve a la IU web clásica de BigQuery.

    Ir a la IU web clásica de BigQuery

  2. En el panel de navegación, haz clic en el ícono de flecha hacia abajo Ícono de flecha hacia abajo. junto al nombre de tu conjunto de datos y haz clic en Crear tabla nueva.

  3. En la página Crear tabla, en la sección Datos de origen, haz clic en Crear tabla vacía.

  4. En la página Crear tabla, en la sección Tabla de destino, realiza lo siguiente:

    • Para el Nombre de la tabla, elige el conjunto de datos apropiado y, en el campo correspondiente, ingresa el nombre de la tabla que creas en ese momento.
    • Verifica que Tipo de tabla (Table type) esté establecido en Tabla nativa (Native table).
  5. En la sección Schema (Esquema), ingresa la definición de esquema de forma manual.

    • Para ingresar la información del esquema de forma manual, haz lo siguiente:

      • Haz clic en Edit as Text (Editar como texto) y, luego, ingresa el esquema de la tabla como un arreglo JSON.

      • Usa Add Field (Agregar campo) para ingresar el esquema.

  6. En Options (Opciones), elige lo siguiente:

    • Para Partitioning Type (Tipo de partición), haz clic en None (Ninguna) y elige Day (Día).
    • Para Campo de partición, elige uno de los siguientes:
      • Elige timestamp para crear una tabla particionada por una columna DATE o TIMESTAMP.
      • Elige _PARTITIONTIME para crear una tabla particionada por tiempo de transferencia.
    • En Clustering Fields (Campos de agrupamiento en clústeres), ingresa entre uno y cuatro nombres de campo.
    • En Encriptación de destino (Destination Encryption), ingresa la opción Default. Esta propiedad es para claves de encriptación administradas por clientes. De manera predeterminada, BigQuery encripta contenido del cliente almacenado en reposo.

      Detalles de la tabla particionada.

  7. Haz clic en Create Table (Crear tabla).

Después de crear la tabla, puedes actualizar el vencimiento de tabla, la descripción y las etiquetas de la tabla agrupada en clústeres. No puedes agregar un vencimiento de partición con la IU web de BigQuery luego de crear la tabla.

bq

Usa el comando mk con las siguientes marcas:

  • --table (o la abreviación -t)
  • --schema. Puedes proporcionar la definición del esquema de la tabla de forma intercalada o usar un archivo de esquema JSON
  • --time_partitioning_type (para tablas particionadas por tiempo de transferencia) o --time_partitioning_field (para tablas particionadas) Por ahora, DAY es el único valor admitido para --time_partitioning_type.
  • --clustering_fields. Puedes especificar hasta cuatro columnas de agrupamiento en clústeres

Los parámetros opcionales incluyen --expiration, --description, --time_partitioning_expiration, --destination_kms_key y --label.

Si creas una tabla en otro proyecto que no sea el predeterminado, agrega el ID del proyecto al conjunto de datos en el formato siguiente: project_id:dataset.

--destination_kms_key no se muestra aquí. Para obtener más información sobre el uso de --destination_kms_key, consulta las claves de encriptación administradas por el cliente.

Ingresa el comando siguiente para crear una tabla agrupada vacía con una definición de esquema:

bq mk \
--table \
--expiration INTEGER1 \
--schema SCHEMA \
--time_partitioning_type=DAY \
--time_partitioning_field PARTITION_COLUMN \
--clustering_fields CLUSTER_COLUMNS \
--time_partitioning_expiration INTEGER2 \
--description "DESCRIPTION" \
--label KEY:VALUE,KEY:VALUE \
PROJECT_ID:DATASET.TABLE

Reemplaza lo siguiente:

  • INTEGER1: La duración predeterminada, en segundos, de la tabla. El valor mínimo es 3,600 segundos (una hora). La fecha de caducidad se evalúa según la hora UTC actual más el valor del número entero. Si configuras el tiempo de vencimiento de la tabla cuando creas una tabla particionada por el tiempo, se ignora la configuración de vencimiento de la tabla predeterminada del conjunto de datos. Si configuras este valor, la tabla y todas las particiones se borran después del lapso especificado.
  • SCHEMA: Una definición de esquema intercalado en el formato COLUMN:DATA_TYPE,COLUMN:DATA_TYPE o la ruta de acceso al archivo de esquema JSON en tu máquina local.
  • PARTITION_COLUMN: El nombre de la columna TIMESTAMP o DATE que se usa para crear una tabla particionada. Si creas una tabla particionada, no necesitas especificar la marca --time_partitioning_type=DAY.
  • CLUSTER_COLUMNS: Una lista separada por comas de hasta cuatro columnas de agrupamiento en clústeres.
  • INTEGER2: La duración predeterminada, en segundos, de las particiones de la tabla. No hay valor mínimo. El tiempo de vencimiento se evalúa según la fecha de la partición más el valor de número entero. El vencimiento de la partición es independiente del vencimiento de la tabla, pero no lo anula. Si configuras un vencimiento de partición que expire después del vencimiento de la tabla, prevalece el vencimiento de la tabla.
  • DESCRIPTION: Una descripción de la tabla, entre comillas.
  • KEY:VALUE: El par clave-valor que representa una etiqueta. Puedes ingresar varias etiquetas mediante una lista separada por comas.
  • PROJECT_ID: El ID de tu proyecto.
  • DATASET: Un conjunto de datos en tu proyecto.
  • TABLE: El nombre de la tabla particionada que creas.

Cuando especificas el esquema en la línea de comandos, no puedes incluir un tipo de RECORD (STRUCT) ni una descripción de columna. Tampoco puedes especificar el modo de la columna. Todos los modos predeterminados están establecidos en NULLABLE. Para incluir descripciones, modos y tipos RECORD, proporciona un archivo de esquema JSON en su lugar.

Ejemplos:

Ingresa el siguiente comando para crear una tabla particionada llamada myclusteredtable en mydataset en tu proyecto predeterminado. La tabla es una tabla particionada (particionada por una columna TIMESTAMP). El vencimiento de la partición se establece en 86,400 segundos (1 día), el vencimiento de la tabla se establece en 2,592,000 (1 mes de 30 días), la descripción se establece en This is my clustered table y la etiqueta en organization:development. El comando usa la combinación de teclas -t, en lugar de --table.

El esquema está especificado de forma intercalada como: timestamp:timestamp,customer_id:string,transaction_amount:float. El campo de agrupamiento en clústeres especificado customer_id se usa para agrupar las particiones.

bq mk -t \
--expiration 2592000 \
--schema 'timestamp:timestamp,customer_id:string,transaction_amount:float' \
--time_partitioning_field timestamp \
--clustering_fields customer_id \
--time_partitioning_expiration 86400  \
--description "This is my clustered table" \
--label org:dev \
mydataset.myclusteredtable

Ingresa el siguiente comando para crear una tabla agrupada llamada myclusteredtable en myotherproject, no en tu proyecto predeterminado. La tabla es una tabla particionada en tiempo de transferencia. El vencimiento de la partición se establece en 259,200 segundos (3 días), la descripción se establece en This is my partitioned table y la etiqueta en organization:development. El comando usa la combinación de teclas -t, en lugar de --table. El comando no especifica un vencimiento de tabla. Si el conjunto de datos tiene un vencimiento de tabla predeterminado, se aplica. Si el conjunto de datos no tiene un vencimiento predeterminado, la tabla no se vencerá nunca, pero las particiones se vencerán en 3 días.

El esquema se especifica en un archivo JSON local: /tmp/myschema.json. El campo customer_id se usa para agrupar en clústeres las particiones.

bq mk -t \
--expiration 2592000 \
--schema /tmp/myschema.json \
--time_partitioning_type=DAY \
--clustering_fields=customer_id \
--time_partitioning_expiration 86400  \
--description "This is my partitioned table" \
--label org:dev \
myotherproject:mydataset.myclusteredtable

Una vez creada la tabla, puedes actualizar el vencimiento de la tabla, el vencimiento de las particiones, la descripción y las etiquetas de la tabla particionada.

API

Llama al método tables.insert con un recurso de tabla definido que especifique las propiedades timePartitioning, clustering.fields y schema.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go que se encuentran en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Si deseas obtener más información, consulta la documentación de referencia de la API de Go de BigQuery.

import (
	"context"
	"fmt"
	"time"

	"cloud.google.com/go/bigquery"
)

// createTableClustered demonstrates creating a BigQuery table with advanced properties like
// partitioning and clustering features.
func createTableClustered(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydatasetid"
	// tableID := "mytableid"
	ctx := context.Background()

	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	sampleSchema := bigquery.Schema{
		{Name: "timestamp", Type: bigquery.TimestampFieldType},
		{Name: "origin", Type: bigquery.StringFieldType},
		{Name: "destination", Type: bigquery.StringFieldType},
		{Name: "amount", Type: bigquery.NumericFieldType},
	}
	metaData := &bigquery.TableMetadata{
		Schema: sampleSchema,
		TimePartitioning: &bigquery.TimePartitioning{
			Field:      "timestamp",
			Expiration: 90 * 24 * time.Hour,
		},
		Clustering: &bigquery.Clustering{
			Fields: []string{"origin", "destination"},
		},
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, metaData); err != nil {
		return err
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java que se encuentran en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Clustering;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.StandardTableDefinition;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
import com.google.cloud.bigquery.TimePartitioning;
import com.google.common.collect.ImmutableList;

public class CreateClusteredTable {
  public static void runCreateClusteredTable() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    createClusteredTable(datasetName, tableName);
  }

  public static void createClusteredTable(String datasetName, String tableName) {
    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();

      TableId tableId = TableId.of(datasetName, tableName);

      TimePartitioning partitioning = TimePartitioning.of(TimePartitioning.Type.DAY);

      Schema schema =
          Schema.of(
              Field.of("name", StandardSQLTypeName.STRING),
              Field.of("post_abbr", StandardSQLTypeName.STRING),
              Field.of("date", StandardSQLTypeName.DATE));

      Clustering clustering =
          Clustering.newBuilder().setFields(ImmutableList.of("name", "post_abbr")).build();

      StandardTableDefinition tableDefinition =
          StandardTableDefinition.newBuilder()
              .setSchema(schema)
              .setTimePartitioning(partitioning)
              .setClustering(clustering)
              .build();
      TableInfo tableInfo = TableInfo.newBuilder(tableId, tableDefinition).build();

      bigquery.create(tableInfo);
      System.out.println("Clustered table created successfully");
    } catch (BigQueryException e) {
      System.out.println("Clustered table was not created. \n" + e.toString());
    }
  }
}

Crea una tabla agrupada a partir del resultado de una consulta

Existen dos maneras de crear una tabla agrupada a partir del resultado de una consulta:

Puedes crear una tabla agrupada si realizas consultas en una tabla particionada o en una tabla sin particiones. No puedes cambiar una tabla existente a una tabla agrupada con los resultados de una consulta.

Cuando creas una tabla agrupada a partir del resultado de una consulta, debes usar SQL estándar. Por el momento, SQL heredado no es compatible con la consulta en tablas agrupadas o la escritura de resultados de consultas en tablas agrupadas.

Console

No puedes especificar opciones de agrupamiento en clústeres para una tabla de destino cuando realizas consultas de datos mediante la IU web de BigQuery de Console, a menos que uses una declaración DDL. Para obtener más información, consulta Usa declaraciones de lenguaje de definición de datos.

IU clásica

No puedes especificar opciones de agrupamiento en clústeres para una tabla de destino cuando realizas consultas de datos mediante la IU web clásica de BigQuery, a menos que uses una declaración DDL. Para obtener más información, consulta Usa declaraciones de lenguaje de definición de datos.

bq

Ingresa el comando siguiente para crear una tabla de destino agrupada nueva a partir del resultado de una consulta:

bq --location=LOCATION query \
--use_legacy_sql=false 'QUERY'

Reemplaza lo siguiente:

  • LOCATION: El nombre de tu ubicación. La marca --location es opcional. Por ejemplo, si usas BigQuery en la región de Tokio, puedes establecer el valor de la marca en asia-northeast1. Puedes configurar un valor predeterminado para la ubicación con el archivo .bigqueryrc.
  • QUERY: Una consulta en la sintaxis de SQL estándar. Por el momento, no puedes usar SQL heredado para realizar consultas en las tablas agrupadas o escribir resultados de consultas en tablas agrupadas. La consulta puede contener una declaración DDL CREATE TABLE que especifica las opciones para crear tu tabla agrupada. Puedes usar DDL en vez de especificar las marcas de línea de comandos individuales.

Ejemplos:

Ingresa el siguiente comando para escribir los resultados de la consulta en una tabla de destino agrupada llamada myclusteredtable en mydataset. mydataset está en tu proyecto predeterminado. La consulta recupera datos de una tabla sin particiones: mytable. La columna customer_id de la tabla se usa para agrupar en clústeres la tabla. La columna timestamp de la tabla se usa para crear una tabla particionada.

bq query --use_legacy_sql=false \
'CREATE TABLE
   mydataset.myclusteredtable
 PARTITION BY
   DATE(timestamp)
 CLUSTER BY
   customer_id AS
 SELECT
   *
 FROM
   `mydataset.mytable`'

API

Para guardar los resultados de la consulta en una tabla agrupada, llama al método jobs.insert, configura un trabajo query y, además, incluye una declaración DDL CREATE TABLE que crea la tabla agrupada.

Especifica tu ubicación en la propiedad location en la sección jobReference del recurso de trabajo.

Crea una tabla agrupada cuando cargas datos

Puedes crear una tabla agrupada si especificas columnas de agrupamiento en clústeres cuando cargas datos en una tabla nueva. No es necesario crear una tabla vacía antes de cargarle datos. Puedes crear una tabla agrupada y cargar tus datos al mismo tiempo.

Para obtener más información sobre la carga de datos, consulta Introducción a la carga de datos en BigQuery.

Para definir el agrupamiento en clústeres cuando defines un trabajo de carga, haz lo siguiente:

API

Para definir la configuración del agrupamiento en clústeres cuando creas una tabla a través de un trabajo de carga, puedes propagar las propiedades Clustering de la tabla.

Go

Antes de probar este ejemplo, sigue las instrucciones de configuración para Go que se encuentran en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Si deseas obtener más información, consulta la documentación de referencia de la API de Go de BigQuery.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// importClusteredTable demonstrates creating a table from a load job and defining partitioning and clustering
// properties.
func importClusteredTable(projectID, destDatasetID, destTableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/sample-transactions/transactions.csv")
	gcsRef.SkipLeadingRows = 1
	gcsRef.Schema = bigquery.Schema{
		{Name: "timestamp", Type: bigquery.TimestampFieldType},
		{Name: "origin", Type: bigquery.StringFieldType},
		{Name: "destination", Type: bigquery.StringFieldType},
		{Name: "amount", Type: bigquery.NumericFieldType},
	}
	loader := client.Dataset(destDatasetID).Table(destTableID).LoaderFrom(gcsRef)
	loader.TimePartitioning = &bigquery.TimePartitioning{
		Field: "timestamp",
	}
	loader.Clustering = &bigquery.Clustering{
		Fields: []string{"origin", "destination"},
	}
	loader.WriteDisposition = bigquery.WriteEmpty

	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}

	if status.Err() != nil {
		return fmt.Errorf("job completed with error: %v", status.Err())
	}
	return nil
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración para Java que se encuentran en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Clustering;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.Schema;
import com.google.cloud.bigquery.StandardSQLTypeName;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TimePartitioning;
import com.google.common.collect.ImmutableList;

public class LoadTableClustered {

  public static void runLoadTableClustered() throws Exception {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "/path/to/file.csv";
    loadTableClustered(datasetName, tableName, sourceUri);
  }

  public static void loadTableClustered(String datasetName, String tableName, String sourceUri)
      throws Exception {
    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();

      TableId tableId = TableId.of(datasetName, tableName);

      Schema schema =
          Schema.of(
              Field.of("name", StandardSQLTypeName.STRING),
              Field.of("post_abbr", StandardSQLTypeName.STRING),
              Field.of("date", StandardSQLTypeName.DATE));

      TimePartitioning partitioning = TimePartitioning.of(TimePartitioning.Type.DAY);

      Clustering clustering =
          Clustering.newBuilder().setFields(ImmutableList.of("name", "post_abbr")).build();

      LoadJobConfiguration loadJobConfig =
          LoadJobConfiguration.builder(tableId, sourceUri)
              .setFormatOptions(FormatOptions.csv())
              .setSchema(schema)
              .setTimePartitioning(partitioning)
              .setClustering(clustering)
              .build();

      Job loadJob = bigquery.create(JobInfo.newBuilder(loadJobConfig).build());

      // Load data from a GCS parquet file into the table
      // Blocks until this load table job completes its execution, either failing or succeeding.
      Job completedJob = loadJob.waitFor();

      // Check for errors
      if (completedJob == null) {
        throw new Exception("Job not executed since it no longer exists.");
      } else if (completedJob.getStatus().getError() != null) {
        // You can also look at queryJob.getStatus().getExecutionErrors() for all
        // errors, not just the latest one.
        throw new Exception(
            "BigQuery was unable to load into the table due to an error: \n"
                + loadJob.getStatus().getError());
      }
      System.out.println("Data successfully loaded into clustered table during load job");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Data not loaded into clustered table during load job \n" + e.toString());
    }
  }
}

Controla el acceso a las tablas agrupadas

Para configurar el acceso a las tablas y vistas, puedes otorgar una función de Cloud IAM a una entidad en los siguientes niveles, ordenados según el rango de recursos permitidos (de mayor a menor):

El acceso con cualquier recurso protegido por Cloud IAM es aditivo. Por ejemplo, si una entidad no tiene acceso en un nivel alto, como un proyecto, podrías otorgar acceso a la entidad a nivel del conjunto de datos. Luego, la entidad tendrá acceso a las tablas y vistas del conjunto de datos. Del mismo modo, si la entidad no tiene acceso en el nivel alto o en el de conjunto de datos, puedes otorgar acceso a la entidad a nivel de tabla o de vista.

Cuando se otorgan funciones de Cloud IAM en un nivel superior en la jerarquía de recursos de Google Cloud, como el nivel de proyecto, organización o carpeta, se le otorga a la entidad acceso a un amplio conjunto de recursos. Por ejemplo, cuando se otorga una función a una entidad en el nivel de proyecto, se le brindan permisos que se aplican a todos los conjuntos de datos del proyecto.

Si se otorga una función a nivel de conjunto de datos, se especifican las operaciones que una entidad puede realizar en las tablas y vistas de ese conjunto de datos específico, incluso si la entidad no tiene acceso a un nivel superior. Para obtener información sobre la configuración de los controles de acceso a nivel de conjunto de datos, consulta Controla el acceso a los conjuntos de datos.

Cuando se otorga una función a nivel de tabla o vista, se especifican las operaciones que una entidad puede realizar en las tablas y vistas específicas, incluso si la entidad no tiene acceso a un nivel superior. Para obtener información sobre la configuración de los controles de acceso a nivel de tabla, consulta Controla el acceso a las tablas y vistas.

También puedes crear funciones personalizadas de Cloud IAM. Si creas una función personalizada, los permisos que otorgues dependerán de las operaciones específicas que desees que la entidad pueda realizar.

No puedes establecer un permiso “deny” en ningún recurso protegido por Cloud IAM.

Para obtener más información sobre las funciones y los permisos, consulta las siguientes páginas:

Usa tablas agrupadas en clústeres

Obtén información sobre las tablas agrupadas

Tienes las siguientes opciones para obtener información sobre las tablas:

  • Mediante Cloud Console o la IU web clásica de BigQuery
  • Mediante el comando bq show de la interfaz de línea de comandos
  • Con una llamada al método tables.get de la API
  • Consultar las vistas INFORMATION_SCHEMA

Permisos necesarios

Como mínimo, para obtener información sobre las tablas, debes tener permisos de bigquery.tables.get. Las siguientes funciones predefinidas de Cloud  IAM incluyen los permisos bigquery.tables.get:

  • bigquery.metadataViewer
  • bigquery.dataViewer
  • bigquery.dataOwner
  • bigquery.dataEditor
  • bigquery.admin

Además, si un usuario tiene permisos bigquery.datasets.create, se le otorga el acceso bigquery.dataOwner cuando crea un conjunto de datos. El acceso bigquery.dataOwner brinda al usuario la capacidad de obtener información sobre las tablas en un conjunto de datos.

Para obtener más información sobre las funciones de Cloud IAM y los permisos en BigQuery, consulta Funciones y permisos predefinidos.

Obtén información sobre tablas agrupadas

Para ver información sobre una tabla agrupada, haz lo siguiente:

Console

  1. En Google Cloud Console, ve al panel Resources (Recursos). Haz clic en el nombre de tu conjunto de datos para expandirlo y, luego, haz clic en el nombre de la tabla que deseas ver.

  2. Haz clic en Detalles. En esta página, se muestran los detalles de la tabla que incluyen las columnas de agrupamiento en clústeres.

    Detalles de la tabla.

IU clásica

  1. En el panel de navegación, haz clic en el ícono de flecha hacia abajo Ícono de flecha hacia abajo. a la izquierda de tu conjunto de datos para expandirlo, o haz doble clic en el nombre del conjunto. Con esta acción, se muestran las tablas y vistas del conjunto de datos.

  2. Haz clic en el nombre de la tabla.

  3. Haz clic en Detalles. En la página Detalles de la tabla, se muestran los detalles de la tabla que incluyen las columnas de agrupamiento en clústeres.

    Detalles de tablas agrupadas.

bq

Emite el comando bq show para mostrar toda la información de la tabla. Usa la marca --schema para mostrar solo la información del esquema de la tabla. La marca --format se puede usar para controlar el resultado.

Si obtienes información sobre una tabla en un proyecto que no sea tu proyecto predeterminado, agrega el ID del proyecto al conjunto de datos en el formato siguiente: project_id:dataset.

bq show \
--schema \
--format=prettyjson \
PROJECT_ID:DATASET.TABLE

Reemplaza lo siguiente:

  • PROJECT_ID: El ID de tu proyecto.
  • DATASET: El nombre del conjunto de datos.
  • TABLE: El nombre de la tabla.

Ejemplos:

Ingresa el comando siguiente para mostrar toda la información sobre myclusteredtable en mydataset. mydataset en tu proyecto predeterminado.

bq show --format=prettyjson mydataset.myclusteredtable

El resultado debería ser similar a lo siguiente:

{
  "clustering": {
    "fields": [
      "customer_id"
    ]
  },
...
}

API

Llama al método bigquery.tables.get y proporciona los parámetros relevantes.

SQL

En cuanto a las tablas agrupadas, puedes consultar la columna CLUSTERING_ORDINAL_POSITION en la vista INFORMATION_SCHEMA.COLUMNS a fin de recuperar información sobre las columnas de agrupamiento en clústeres de una tabla.

-- Set up a table with clustering.
CREATE TABLE myDataset.data (column1 INT64, column2 INT64)
PARTITION BY _PARTITIONDATE
CLUSTER BY column1, column2;

-- This query returns 1 for column1 and 2 for column2.
SELECT column_name, clustering_ordinal_position
FROM myDataset.INFORMATION_SCHEMA.COLUMNS;

Hay más metadatos de tabla disponibles a través de las vistas TABLES, TABLE_OPTIONS, COLUMNS y COLUMN_FIELD_PATH en INFORMATION_SCHEMA.

Haz una lista de tablas agrupadas en un conjunto de datos

Tienes las siguientes opciones para generar una lista de las tablas agrupadas en clústeres en los conjuntos de datos:

  • Mediante Cloud Console o la IU web clásica de BigQuery
  • Mediante el comando bq ls de la interfaz de línea de comandos
  • Mediante una llamada al método de la API tables.list
  • Con las bibliotecas cliente
  • Mediante una consulta a la columna CLUSTERING_ORDINAL_POSITION en la vista INFORMATION_SCHEMA.COLUMNS

Los permisos y los pasos requeridos a fin de crear una lista de tablas agrupadas son los mismos que para las tablas particionadas. Para obtener más información sobre cómo enumerar tablas, consulta la sección sobre cómo mostrar una lista de las tablas particionadas en un conjunto de datos.

Modifica la especificación de clústeres

Si llamas a los métodos tables.update o tables.patch, se pueden cambiar o quitar las especificaciones de agrupamiento en clústeres. También se puede cambiar el conjunto de columnas agrupadas en una tabla agrupada en clústeres a un conjunto diferente de columnas. Este método de actualización del conjunto de columnas de agrupamiento en clústeres es más útil para tablas con inserciones de transmisión continua, ya que no se pueden intercambiar con facilidad.

Cuando se convierte una tabla que no está agrupada en clústeres a una agrupada, o se cambia el conjunto de columnas agrupadas, el reagrupamiento en clústeres automático solo funciona a partir de ese momento. Por ejemplo, una tabla de 1 PB no agrupada que se convierte en una tabla agrupada mediante tables.update seguirá teniendo 1 PB de datos no agrupados. El reagrupamiento en clústeres automático solo se aplica a los datos nuevos que se agregan a la tabla después de la actualización.

Funciones en desarrollo

Las siguientes características están en desarrollo, pero aún no están disponibles en la versión Alfa:

  • Compatibilidad con tablas nativas en agrupamiento en clústeres (no particionadas)
  • Reducción de costos para tipos particulares de consultas que usan filtros en columnas en agrupamiento en clústeres

Próximos pasos