Créer des tables partitionnées

Cette page explique comment créer des tables partitionnées dans BigQuery. Pour une vue d'ensemble des tables partitionnées, consultez la page Présentation des tables partitionnées.

Autorisations requises

Pour créer une table, vous devez disposer au minimum des autorisations suivantes :

  • Autorisations bigquery.tables.create pour créer la table
  • Autorisations bigquery.tables.updateData pour écrire des données dans la table à l'aide d'une tâche de chargement, de requête ou de copie
  • Autorisations bigquery.jobs.create pour exécuter une tâche de requête, de chargement ou de copie qui écrit des données dans la table

Des autorisations supplémentaires, par exemple bigquery.tables.getData, peuvent être nécessaires pour accéder aux données que vous écrivez dans la table.

Les rôles IAM prédéfinis suivants incluent les autorisations bigquery.tables.create et bigquery.tables.updateData :

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

Les rôles IAM prédéfinis suivants incluent les autorisations bigquery.jobs.create :

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

En outre, si un utilisateur possède les autorisations bigquery.datasets.create, il obtient également un accès bigquery.dataOwner à l'ensemble de données qu'il crée. L'accès correspondant au rôle bigquery.dataOwner donne à l'utilisateur la possibilité de créer et de mettre à jour des tables dans l'ensemble de données.

Pour en savoir plus sur les rôles et les autorisations IAM dans BigQuery, consultez la page Rôles prédéfinis et autorisations.

Créer une table partitionnée vide

Les étapes permettant de créer une table partitionnée dans BigQuery sont semblables à la création d'une table standard, à la différence que vous spécifiez les options de partitionnement et d'autres options de table.

Créer une table partitionnée par colonne d'unité de temps

Pour créer une table partitionnée par colonne d'unité de temps vide avec une définition de schéma, procédez comme suit :

Console

  1. Ouvrez la page "BigQuery" dans Cloud Console.

    Accéder à la page "BigQuery"

  2. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  3. Développez l'option  Actions puis cliquez sur Ouvrir.

  4. Dans le panneau de détails, cliquez sur Créer une table.

  5. Dans la section Source de la page Créer une table, sélectionnez Table vide.

  6. Dans la section Destination :

    • Sous Dataset name (Nom de l'ensemble de données), sélectionnez l'ensemble de données approprié.
    • Dans le champ Nom de la table, saisissez le nom de la table.
    • Vérifiez que Type de table est défini sur Table native.
  7. Dans la section Schéma, saisissez la définition du schéma. Assurez-vous que le schéma inclut une colonne DATE, TIMESTAMP ou DATETIME pour la colonne de partitionnement. Pour en savoir plus, consultez la section Spécifier un schéma.

  8. Dans la section Paramètres de partitionnement et de clustering, dans la liste déroulante Partitionnement, sélectionnez Partitionner par champ, puis choisissez la colonne de partitionnement. Cette option n'est disponible que si le schéma contient une colonne DATE, TIMESTAMP ou DATETIME.

  9. Sélectionnez le Type de partitionnement pour choisir le partitionnement quotidien, horaire, mensuel ou annuel.

  10. (Facultatif) Pour exiger un filtre de partitionnement sur toutes les requêtes de cette table, cochez la case Demander un filtre de partitionnement. Ce type de filtre peut contribuer à réduire les coûts et à améliorer les performances. Pour en savoir plus, consultez la section Interroger des tables partitionnées.

  11. Cliquez sur Créer une table.

SQL

Pour créer une table partitionnée par colonnes d'unités de temps, utilisez l'instruction CREATE TABLE avec une clause PARTITION BY.

L'exemple suivant crée une table avec des partitions quotidiennes basées sur la colonne transaction_date.

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY
  transaction_date
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Le type de partitionnement par défaut pour les colonnes DATE est le partitionnement quotidien. Pour spécifier un type de partitionnement différent, incluez la fonction DATE_TRUNC dans la clause PARTITION BY. Par exemple, la requête suivante crée une table avec des partitions mensuelles :

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY
  DATE_TRUNC(transaction_date, MONTH)
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Vous pouvez également spécifier une colonne TIMESTAMP ou DATETIME en tant que colonne de partitionnement. Dans ce cas, incluez la fonction TIMESTAMP_TRUNC ou DATETIME_TRUNC dans la clause PARTITION BY pour spécifier le type de partition. Par exemple, l'instruction suivante crée une table avec des partitions quotidiennes basées sur une colonne TIMESTAMP :

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_ts TIMESTAMP)
PARTITION BY
  TIMESTAMP_TRUNC(transaction_ts, DAY)
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Pour en savoir plus sur l'exécution des requêtes, consultez la section Exécuter des requêtes interactives.

bq

Exécutez la commande bq mk avec l'option --table (ou le raccourci -t) :

bq mk --table \
  --schema SCHEMA \
  --time_partitioning_field COLUMN \
  --time_partitioning_type UNIT_TIME \
  --time_partitioning_expiration EXPIRATION_TIME \
  --require_partition_filter=BOOLEAN
  PROJECT_ID:DATASET.TABLE

Remplacez les éléments suivants :

  • SCHEMA : définition de schéma au format column:data_type,column:data_type ou chemin d'accès à un fichier de schéma JSON sur votre ordinateur local. Pour en savoir plus, consultez la section Spécifier un schéma.
  • COLUMN : nom de la colonne de partitionnement. Dans le schéma de la table, cette colonne doit être de type TIMESTAMP, DATETIME ou DATE.
  • UNIT_TIME : type de partitionnement. Valeurs autorisées : DAY, HOUR, MONTH ou YEAR.
  • EXPIRATION_TIME : délai d'expiration des partitions de la table, en secondes. L'option --time_partitioning_expiration est facultative.
  • BOOLEAN : si true, les requêtes de cette table doivent inclure un filtre de partition. L'option --require_partition_filter est facultative.
  • PROJECT_ID : ID du projet. S'il est omis, votre projet par défaut est utilisé.
  • DATASET : nom d'un ensemble de données dans votre projet.
  • TABLE : nom de la table à créer.

Pour connaître les autres options de ligne de commande, consultez la section bq mk.

L'exemple suivant crée une table nommée mytable qui est partitionnée sur la colonne ts, à l'aide du partitionnement horaire. Le délai d'expiration du partitionnement est défini sur 259 200 secondes (trois jours).

bq mk -t \
  --schema 'ts:TIMESTAMP,qtr:STRING,sales:FLOAT' \
  --time_partitioning_field ts \
  --time_partitioning_type HOUR \
  --time_partitioning_expiration 259200  \
  mydataset.mytable

API

Appelez la méthode tables.insert avec une ressource de table définie qui spécifie les propriétés timePartitioning et schema.

Go

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Go décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence sur l'API BigQuery en langage Go.

import (
	"context"
	"fmt"
	"time"

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

// createTablePartitioned demonstrates creating a table and specifying a time partitioning configuration.
func createTablePartitioned(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: "name", Type: bigquery.StringFieldType},
		{Name: "post_abbr", Type: bigquery.IntegerFieldType},
		{Name: "date", Type: bigquery.DateFieldType},
	}
	metadata := &bigquery.TableMetadata{
		TimePartitioning: &bigquery.TimePartitioning{
			Field:      "date",
			Expiration: 90 * 24 * time.Hour,
		},
		Schema: sampleSchema,
	}
	tableRef := client.Dataset(datasetID).Table(tableID)
	if err := tableRef.Create(ctx, metadata); err != nil {
		return err
	}
	return nil
}

Java

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Java décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Java.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
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;

// Sample to create a partition table
public class CreatePartitionedTable {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    Schema schema =
        Schema.of(
            Field.of("name", StandardSQLTypeName.STRING),
            Field.of("post_abbr", StandardSQLTypeName.STRING),
            Field.of("date", StandardSQLTypeName.DATE));
    createPartitionedTable(datasetName, tableName, schema);
  }

  public static void createPartitionedTable(String datasetName, String tableName, Schema schema) {
    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.newBuilder(TimePartitioning.Type.DAY)
              .setField("date") //  name of column to use for partitioning
              .setExpirationMs(7776000000L) // 90 days
              .build();

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

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

Node.js

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Node.js décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Node.js.

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function createTablePartitioned() {
  // Creates a new partitioned table named "my_table" in "my_dataset".

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_dataset";
  // const tableId = "my_table";
  const schema = 'Name:string, Post_Abbr:string, Date:date';

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/tables#resource
  const options = {
    schema: schema,
    location: 'US',
    timePartitioning: {
      type: 'DAY',
      expirationMS: '7776000000',
      field: 'date',
    },
  };

  // Create a new table in the dataset
  const [table] = await bigquery
    .dataset(datasetId)
    .createTable(tableId, options);
  console.log(`Table ${table.id} created with partitioning: `);
  console.log(table.metadata.timePartitioning);
}

Python

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Python décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Python.

# from google.cloud import bigquery
# client = bigquery.Client()
# project = client.project
# dataset_ref = bigquery.DatasetReference(project, 'my_dataset')

table_ref = dataset_ref.table("my_partitioned_table")
schema = [
    bigquery.SchemaField("name", "STRING"),
    bigquery.SchemaField("post_abbr", "STRING"),
    bigquery.SchemaField("date", "DATE"),
]
table = bigquery.Table(table_ref, schema=schema)
table.time_partitioning = bigquery.TimePartitioning(
    type_=bigquery.TimePartitioningType.DAY,
    field="date",  # name of column to use for partitioning
    expiration_ms=7776000000,
)  # 90 days

table = client.create_table(table)

print(
    "Created table {}, partitioned on column {}".format(
        table.table_id, table.time_partitioning.field
    )
)

Créer une table partitionnée par date d'ingestion

Pour créer une table partitionnée par date d'ingestion vide avec une définition de schéma, procédez comme suit :

Console

  1. Ouvrez la page "BigQuery" dans Cloud Console.

    Accéder à la page "BigQuery"

  2. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  3. Développez l'option  Actions puis cliquez sur Ouvrir.

  4. Dans le panneau de détails, cliquez sur Créer une table.

  5. Dans la section Source de la page Créer une table, sélectionnez Table vide.

  6. Dans la section Destination :

    • Sous Dataset name (Nom de l'ensemble de données), sélectionnez l'ensemble de données approprié.
    • Dans le champ Nom de la table, saisissez le nom de la table.
    • Vérifiez que Type de table est défini sur Table native.
  7. Dans la section Schema (Schéma), saisissez la définition du schéma.

  8. Dans la section Paramètres de partitionnement et de clustering, pour le champ Partitionnement, cliquez sur Partitionner par date d'ingestion.

  9. (Facultatif) Pour exiger un filtre de partitionnement sur toutes les requêtes de cette table, cochez la case Demander un filtre de partitionnement. Ce type de filtre peut contribuer à réduire les coûts et à améliorer les performances. Pour en savoir plus, consultez la section Interroger des tables partitionnées.

  10. Cliquez sur Créer une table.

SQL

Pour créer une table partitionnée par date d'ingestion, utilisez l'instruction CREATE TABLE avec une clause PARTITION BY qui partitionne selon _PARTITIONTIME.

L'exemple suivant crée une table avec des partitions quotidiennes.

CREATE TABLE
  mydataset.newtable (transaction_id INT64)
PARTITION BY
  _PARTITIONDATE
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Le type de partitionnement par défaut pour le partitionnement par date d'ingestion est le partitionnement quotidien. Pour spécifier un type de partitionnement différent, incluez la fonction DATE_TRUNC dans la clause PARTITION BY. Par exemple, la requête suivante crée une table avec des partitions mensuelles :

CREATE TABLE
  mydataset.newtable (transaction_id INT64)
PARTITION BY
  DATE_TRUNC(_PARTITIONTIME, MONTH)
OPTIONS(
  partition_expiration_days=3,
  require_partition_filter=true
)

Pour en savoir plus sur l'exécution des requêtes, consultez la section Exécuter des requêtes interactives.

bq

Exécutez la commande bq mk avec l'option --table (ou le raccourci -t) :

bq mk --table \
  --schema SCHEMA \
  --time_partitioning_type UNIT_TIME \
  --time_partitioning_expiration EXPIRATION_TIME \
  --require_partition_filter=BOOLEAN  \
  PROJECT_ID:DATASET.TABLE

Remplacez les éléments suivants :

  • SCHEMA : définition au format column:data_type,column:data_type ou chemin d'accès à un fichier de schéma JSON sur votre ordinateur local. Pour en savoir plus, consultez la section Spécifier un schéma.
  • UNIT_TIME : type de partitionnement. Valeurs autorisées : DAY, HOUR, MONTH ou YEAR.
  • EXPIRATION_TIME : délai d'expiration des partitions de la table, en secondes. L'option --time_partitioning_expiration est facultative.
  • BOOLEAN : si true, les requêtes de cette table doivent inclure un filtre de partition. L'option --require_partition_filter est facultative.
  • PROJECT_ID : ID du projet. S'il est omis, votre projet par défaut est utilisé.
  • DATASET : nom d'un ensemble de données dans votre projet.
  • TABLE : nom de la table à créer.

Pour connaître les autres options de ligne de commande, consultez la section bq mk.

L'exemple suivant crée une table partitionnée par date d'ingestion nommée mytable. La table est partitionnée par jour, avec un délai d'expiration de partitionnement défini sur 259 200 secondes (trois jours).

bq mk -t \
  --schema qtr:STRING,sales:FLOAT,year:STRING \
  --time_partitioning_type DAY \
  --time_partitioning_expiration 259200 \
  mydataset.mytable

API

Appelez la méthode tables.insert avec une ressource de table définie qui spécifie les propriétés timePartitioning et schema.

Créer une table partitionnée par plages d'entiers

Pour créer une table partitionnée par plages d'entiers vide avec une définition de schéma, procédez comme suit :

Console

  1. Ouvrez la page "BigQuery" dans Cloud Console.

    Accéder à la page "BigQuery"

  2. Dans le panneau Explorateur, développez votre projet et sélectionnez un ensemble de données.

  3. Développez l'option  Actions puis cliquez sur Ouvrir.

  4. Dans le panneau de détails, cliquez sur Créer une table.

  5. Dans la section Source de la page Créer une table, sélectionnez Table vide.

  6. Dans la section Destination :

    • Sous Dataset name (Nom de l'ensemble de données), sélectionnez l'ensemble de données approprié.
    • Dans le champ Nom de la table, saisissez le nom de la table.
    • Vérifiez que Type de table est défini sur Table native.
  7. Dans la section Schéma, saisissez la définition du schéma. Assurez-vous que le schéma inclut une colonne INTEGER pour la colonne de partitionnement. Pour en savoir plus, consultez la section Spécifier un schéma.

  8. Dans la section Paramètres de partitionnement et de clustering, dans la liste déroulante Partitionnement, sélectionnez Partitionner par champ, puis choisissez la colonne de partitionnement. Cette option n'est disponible que si le schéma contient une colonne INTEGER.

  9. Indiquez des valeurs pour start, end et interval :

    • Start est le début de la première plage de partitions (inclusive).
    • End est la fin de la dernière plage de partitions (exclusive).
    • Interval est la largeur de chaque plage de partitions.

    Les valeurs non comprises dans ces plages sont incluses dans une partition __UNPARTITIONED__ spéciale.

  10. (Facultatif) Pour exiger un filtre de partitionnement sur toutes les requêtes de cette table, cochez la case Demander un filtre de partitionnement. Ce type de filtre peut contribuer à réduire les coûts et à améliorer les performances. Pour en savoir plus, consultez la section Interroger des tables partitionnées.

  11. Cliquez sur Créer une table.

SQL

Pour créer une table partitionnée par plages d'entiers, utilisez l'instruction CREATE TABLE avec une clause PARTITION BY.

L'exemple suivant crée une table partitionnée dans la colonne customer_id avec les valeurs commençant par 0 et finissant par 100, avec un intervalle de 10.

CREATE TABLE mydataset.newtable (customer_id INT64, date1 DATE)
PARTITION BY
  RANGE_BUCKET(customer_id, GENERATE_ARRAY(0, 100, 10))
OPTIONS(
  require_partition_filter=true
)

Pour en savoir plus sur l'exécution des requêtes, consultez la section Exécuter des requêtes interactives.

bq

Exécutez la commande bq mk avec l'option --table (ou le raccourci -t) :

bq mk \
  --schema schema \
  --range_partitioning=COLUMN_NAME,START,END,INTERVAL \
  --require_partition_filter=BOOLEAN  \
  PROJECT_ID:DATASET.TABLE

Remplacez les éléments suivants :

  • SCHEMA : définition de schéma intégrée au format column:data_type,column:data_type ou le chemin d'accès à un fichier de schéma JSON sur votre machine locale. Pour en savoir plus, consultez la section Spécifier un schéma.
  • COLUMN_NAME : nom de la colonne de partitionnement. Dans le schéma de la table, cette colonne doit être de type INTEGER.
  • START : début de la première plage de partition (inclusive).
  • END : fin de la dernière plage de partitions (exclusive).
  • INTERVAL : largeur de chaque plage de partition.
  • BOOLEAN : si true, les requêtes de cette table doivent inclure un filtre de partition. L'option --require_partition_filter est facultative.
  • PROJECT_ID : ID du projet. S'il est omis, votre projet par défaut est utilisé.
  • DATASET : nom d'un ensemble de données dans votre projet.
  • TABLE : nom de la table à créer.

Les valeurs non comprises dans la plage de partitions sont incluses dans une partition __UNPARTITIONED__ spéciale.

Pour connaître les autres options de ligne de commande, consultez la section bq mk.

L'exemple suivant crée une table nommée mytable qui est partitionnée en fonction de la colonne customer_id.

bq mk -t \
  --schema 'customer_id:INTEGER,qtr:STRING,sales:FLOAT' \
  --range_partitioning=customer_id,0,100,10 \
  mydataset.mytable

API

Appelez la méthode tables.insert avec une ressource de table définie qui spécifie les propriétés rangePartitioning et schema.

Java

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Java décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Java.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Field;
import com.google.cloud.bigquery.RangePartitioning;
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;

// Sample to create a range partitioned table
public class CreateRangePartitionedTable {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    Schema schema =
        Schema.of(
            Field.of("integerField", StandardSQLTypeName.INT64),
            Field.of("stringField", StandardSQLTypeName.STRING),
            Field.of("booleanField", StandardSQLTypeName.BOOL),
            Field.of("dateField", StandardSQLTypeName.DATE));
    createRangePartitionedTable(datasetName, tableName, schema);
  }

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

      // Note: The field must be a top- level, NULLABLE/REQUIRED field.
      // The only supported type is INTEGER/INT64
      RangePartitioning partitioning =
          RangePartitioning.newBuilder()
              .setField("integerField")
              .setRange(
                  RangePartitioning.Range.newBuilder()
                      .setStart(1L)
                      .setInterval(2L)
                      .setEnd(10L)
                      .build())
              .build();

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

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

Node.js

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Node.js décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Node.js.

// Import the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');
const bigquery = new BigQuery();

async function createTableRangePartitioned() {
  // Creates a new integer range partitioned table named "my_table"
  // in "my_dataset".

  /**
   * TODO(developer): Uncomment the following lines before running the sample.
   */
  // const datasetId = "my_dataset";
  // const tableId = "my_table";

  const schema = [
    {name: 'fullName', type: 'STRING'},
    {name: 'city', type: 'STRING'},
    {name: 'zipcode', type: 'INTEGER'},
  ];

  // To use integer range partitioning, select a top-level REQUIRED or
  // NULLABLE column with INTEGER / INT64 data type. Values that are
  // outside of the range of the table will go into the UNPARTITIONED
  // partition. Null values will be in the NULL partition.
  const rangePartition = {
    field: 'zipcode',
    range: {
      start: 0,
      end: 100000,
      interval: 10,
    },
  };

  // For all options, see https://cloud.google.com/bigquery/docs/reference/v2/tables#resource
  const options = {
    schema: schema,
    rangePartitioning: rangePartition,
  };

  // Create a new table in the dataset
  const [table] = await bigquery
    .dataset(datasetId)
    .createTable(tableId, options);

  console.log(`Table ${table.id} created with integer range partitioning: `);
  console.log(table.metadata.rangePartitioning);
}

Python

Avant d'essayer l'exemple ci-dessous, suivez la procédure de configuration pour Python décrite dans le guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery Python.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to create.
# table_id = "your-project.your_dataset.your_table_name"

schema = [
    bigquery.SchemaField("full_name", "STRING"),
    bigquery.SchemaField("city", "STRING"),
    bigquery.SchemaField("zipcode", "INTEGER"),
]

table = bigquery.Table(table_id, schema=schema)
table.range_partitioning = bigquery.RangePartitioning(
    # To use integer range partitioning, select a top-level REQUIRED /
    # NULLABLE column with INTEGER / INT64 data type.
    field="zipcode",
    range_=bigquery.PartitionRange(start=0, end=100000, interval=10),
)
table = client.create_table(table)  # Make an API request.
print(
    "Created table {}.{}.{}".format(table.project, table.dataset_id, table.table_id)
)

Créer une table partitionnée à partir d'un résultat de requête

Vous pouvez créer une table partitionnée à partir d'un résultat de requête de plusieurs manières :

  • Utiliser l'outil de ligne de commande bq ou l'API BigQuery pour définir une table de destination pour une requête. Lorsque la requête s'exécute, BigQuery écrit les résultats dans la table de destination. Vous pouvez utiliser cette approche pour n'importe quel type de partitionnement.

  • En SQL, utiliser une instruction CREATE TABLE ... AS SELECT. Vous pouvez utiliser cette approche pour créer une table partitionnée par colonnes d'unités de temps ou par plages d'entiers, mais pas par date d'ingestion.

SQL

Utilisez l'instruction CREATE TABLE avec une clause SELECT AS pour la requête. Incluez une clause PARTITION BY pour configurer le partitionnement.

L'exemple suivant crée une table partitionnée dans la colonne transaction_date.

CREATE TABLE
  mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY
  transaction_date
AS SELECT transaction_id, transaction_date FROM mydataset.mytable

bq

Pour créer une table partitionnée à partir d'une requête, exécutez la commande bq query avec l'option --destination_table et l'option --time_partitioning_type.

Partitionnement par colonnes d'unités de temps :

bq query \
  --use_legacy_sql=false \
  --destination_table TABLE_NAME \
  --time_partitioning_field COLUMN \
  --time_partitioning_type UNIT_TIME \
  'QUERY_STATEMENT'

Partitionnement par date d'ingestion :

bq query \
  --use_legacy_sql=false \
  --destination_table TABLE_NAME \
  --time_partitioning_type UNIT_TIME \
  'QUERY_STATEMENT'

Partitionnement par plages d'entiers :

bq query \
  --use_legacy_sql=false \
  --destination_table PROJECT_ID:DATASET.TABLE \
  --range_partitioning COLUMN,START,END,INTERVAL \
  'QUERY_STATEMENT'

Remplacez les éléments suivants :

  • PROJECT_ID : ID du projet. S'il est omis, votre projet par défaut est utilisé.
  • DATASET : nom d'un ensemble de données dans votre projet.
  • TABLE : nom de la table à créer.
  • COLUMN : nom de la colonne de partitionnement.
  • UNIT_TIME : type de partitionnement. Valeurs autorisées : DAY, HOUR, MONTH ou YEAR.
  • START : valeur de début inclusive du partitionnement par plages.
  • END : valeur de fin exclusive du partitionnement par plages.
  • INTERVAL : largeur de chaque plage au sein de la partition.
  • QUERY_STATEMENT : requête utilisée pour renseigner la table.

L'exemple suivant crée une table partitionnée suivant la colonne transaction_date, à l'aide du partitionnement mensuel.

bq query \
  --use_legacy_sql=false
  --destination_table mydataset.newtable
  --time_partitioning_field transaction_id
  --time_partitioning_type MONTH
  'SELECT transaction_id, transaction_date FROM mydataset.mytable'

L'exemple suivant crée une table partitionnée suivant la colonne customer_id, à l'aide du partitionnement par plages d'entiers.

bq query \
  --use_legacy_sql=false
  --destination_table mydataset.newtable
  --range_partitioning customer_id,0,100,10
  'SELECT * FROM mydataset.ponies'

Pour les tables partitionnées par date d'ingestion, vous pouvez également charger des données dans une partition spécifique à l'aide d'un décorateur de partition. L'exemple suivant crée une table partitionnée par date d'ingestion et charge des données dans la partition 20180201 (1er février 2018) :

bq query \
  --use_legacy_sql=false  \
  --time_partitioning_type=DAY
  --destination_table='newtable$20180201' \
  'SELECT * FROM mydataset.mytable'

API

Pour enregistrer des résultats de requête dans une table partitionnée, appelez la méthode jobs.insert. Configurez une tâche query. Spécifiez la table de destination dans destinationTable. Spécifiez le partitionnement dans la propriété timePartitioning ou dans la propriété rangePartitioning.

Écrire des données sur une partition spécifique

Les décorateurs de partition vous permettent d'écrire des données dans une partition spécifique. Un décorateur de partition se présente sous la forme suivante :

table_name$partition_id

L'exemple suivant écrit des données dans la partition 20160501 (1er mai 2016) d'une table existante, en supposant que la table est déjà partitionnée par date :

bq load --source_format=CSV 'mydataset.mytable$20160501' data.csv

Vous pouvez également écrire les résultats d'une requête dans une partition spécifique :

bq query \
  --use_legacy_sql=false  \
  --destination_table='mytable$20160501' \
  --append_table=true \
  'SELECT * FROM mydataset.another_table'

Avec le partitionnement par date d'ingestion, vous pouvez utiliser cette technique pour charger des données plus anciennes ou ajuster les fuseaux horaires. Par exemple, si vous êtes à l'heure normale du Pacifique (PST), vous pouvez charger les données générées le 1er mai 2016 PST dans la partition pour cette date, à l'aide du décorateur de partition correspondant : $20160501. (Par défaut, les partitions par date d'ingestion sont basées sur l'heure UTC.)

Pour les tables partitionnées par colonnes d'unités de temps et par plages d'entiers, l'ID de partition spécifié dans le décorateur doit correspondre aux données en cours d'écriture. Par exemple, si la table est partitionnée suivant une colonne DATE, le décorateur doit correspondre à la valeur de cette colonne. Dans le cas contraire, une erreur se produit. Toutefois, si vous savez au préalable que vos données se trouvent dans une seule partition, la spécification du décorateur de partition peut améliorer les performances d'écriture.

Pour en savoir plus sur le chargement des données, consultez la page intitulée Présentation du chargement de données dans BigQuery.

Convertir des tables segmentées par date en tables partitionnées par date d'ingestion

Si vous avez déjà créé des tables segmentées par date, vous pouvez convertir l'ensemble des tables associées en une seule table partitionnée par date d'ingestion en exécutant la commande partition dans l'outil de ligne de commande bq.

bq --location=LOCATION partition \
  --time_partitioning_type=PARTION_TYPE \
  --time_partitioning_expiration INTEGER \
  PROJECT_ID:SOURCE_DATASET.SOURCE_TABLE \
  PROJECT_ID:DESTINATION_DATASET.DESTINATION_TABLE

Remplacez les éléments suivants :

  • LOCATION : nom de votre emplacement. L'option --location est facultative.
  • PARTITION_TYPE : type de partition. Les valeurs possibles sont DAY, HOUR, MONTH ou YEAR.
  • INTEGER : délai d'expiration de la partition, en secondes. Il n'y a pas de valeur minimale. Le délai d'expiration correspond à la date UTC de la partition plus la valeur entière. L'option time_partitioning_expiration est facultative.
  • PROJECT_ID : ID de votre projet.
  • SOURCE_DATASET : ensemble de données contenant les tables segmentées par date.
  • SOURCE_TABLE : préfixe de vos tables segmentées par date.
  • DESTINATION_DATASET : ensemble de données pour la nouvelle table partitionnée.
  • DESTINATION_TABLE : nom de la table partitionnée à créer.

La commande partition ne fonctionne pas avec les options --label, --expiration ou --description. Vous pouvez ajouter des libellés, un délai d'expiration de la table et une description à la table après l'avoir créée.

Lorsque vous exécutez la commande partition, BigQuery crée une tâche de copie qui génère des partitions à partir des tables segmentées.

L'exemple suivant crée une table partitionnée par date d'ingestion nommée mytable_partitioned à partir d'un ensemble de tables segmentées par date avec le préfixe sourcetable_. La nouvelle table est partitionnée quotidiennement, avec un délai d'expiration de partitionnement de 259 200 secondes (trois jours).

bq partition \
--time_partitioning_type=DAY \
--time_partitioning_expiration 259200 \
mydataset.sourcetable_ \
mydataset.mytable_partitioned

Si les tables segmentées par date sont sourcetable_20180126 et sourcetable_20180127, cette commande crée les partitions suivantes : mydataset.mytable_partitioned$20180126 et mydataset.mytable_partitioned$20180127.

Sécurité des tables

Pour savoir comment contrôler l'accès aux tables dans BigQuery, consultez la page Présentation des contrôles d'accès aux tables.

Étapes suivantes