クラスタ化テーブルの作成と使用

このドキュメントでは、BigQuery でクラスタ化テーブルを作成および使用する方法について説明します。BigQuery でのクラスタ化テーブルに対するサポートの概要については、クラスタ化テーブルの概要をご覧ください。

クラスタ化テーブルを作成する

クラスタ化テーブルは次の方法で作成できます。

テーブルの命名

BigQuery でテーブルを作成するとき、テーブル名はデータセットごとに一意である必要があります。テーブル名の要件は次のとおりです。

  • UTF-8 バイトの文字を合計で 1,024 バイト以下にする。
  • カテゴリ L(文字)、M(マーク)、N(数字)、Pc(コネクタ、アンダースコアを含む)、Pd(ダッシュ)、Zs(スペース)の Unicode 文字を含む。詳しくは、一般カテゴリをご覧ください。

table 01ग्राहक00_お客様étudiant-01 などが有効なテーブル名です。

注意点:

  • テーブル名では、デフォルトで大文字と小文字が区別されます。mytableMyTable は、大文字と小文字を区別しないデータセットでない限り、同じデータセット内に共存できます。
  • 一部のテーブル名とテーブル名の接頭辞は予約済みです。テーブル名または接頭辞が予約されているというエラーが表示された場合は、別の名前を選択して、もう試してください。
  • ドット演算子(.)を連続して含めると、重複する演算子が暗黙的に削除されます。

    たとえば、project_name....dataset_name..table_name

    project_name.dataset_name.table_name のようになります。

必要な権限

テーブルを作成するには、次の IAM 権限が必要です。

  • bigquery.tables.create
  • bigquery.tables.updateData
  • bigquery.jobs.create

また、テーブルに書き込むデータにアクセスするために bigquery.tables.getData 権限が必要になる場合があります。

次の各事前定義 IAM ロールには、テーブルの作成に必要な権限が含まれています。

  • roles/bigquery.dataEditor
  • roles/bigquery.dataOwner
  • roles/bigquery.adminbigquery.jobs.create 権限を含む)
  • roles/bigquery.userbigquery.jobs.create 権限を含む)
  • roles/bigquery.jobUserbigquery.jobs.create 権限を含む)

また、bigquery.datasets.create 権限がある場合は、自分が作成したデータセット内のテーブルを作成および更新できます。

BigQuery での IAM のロールと権限については、事前定義ロールと権限をご覧ください。

スキーマ定義を使用して空のクラスタ化テーブルを作成する

BigQuery でテーブルを作成するときにクラスタリング列を指定します。テーブルが作成されたら、クラスタリング列を変更できます。詳細については、クラスタリング仕様の変更をご覧ください。

クラスタリング列は最上位の非繰り返し列で、そのデータ型は次のシンプルなデータ型のいずれかでなければなりません。

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

最大 4 つのクラスタリング列を指定できます。複数の列を指定する場合、列の順序によってデータの並べ替え方法が決まります。たとえば、テーブルが列 a、b、c によってクラスタ化されている場合、データは同じ順序(列 a、列 b、列 c の順)で並べ替えられます。ベスト プラクティスとして、最も頻繁にフィルタリングまたは集計される列を最初に置いてください。

クラスタリング列の順序は、クエリのパフォーマンスと料金にも影響します。クラスタ化テーブルのクエリのベスト プラクティスについては、クラスタ化テーブルのクエリをご覧ください。

スキーマ定義を使用して空のクラスタ化テーブルを作成するには:

コンソール

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. [エクスプローラ] ペインでプロジェクトを開き、データセットを選択します。
  3. [データセット情報] セクションで、[ テーブルを作成] をクリックします。
  4. [テーブルを作成] パネルで、次の詳細を指定します。
    1. [ソース] セクションの [テーブルの作成元] リストで [空のテーブル] を選択します。
    2. [宛先] セクションで、次の詳細を指定します。
      1. [データセット] で、テーブルを作成するデータセットを選択します。
      2. [テーブル] フィールドに、作成するテーブルの名前を入力します。
      3. [テーブルタイプ] フィールドが [ネイティブ テーブル] に設定されていることを確認します。
    3. [スキーマ] セクションにスキーマ定義を入力します。スキーマ情報は、次のいずれかの方法で手動で入力できます。
      • オプション 1: [テキストとして編集] をクリックし、スキーマを JSON 配列の形式で貼り付けます。JSON 配列を使用する場合は、JSON スキーマ ファイルの作成と同じプロセスを使用してスキーマを生成します。既存のテーブルのスキーマを JSON 形式で表示するには、次のコマンドを入力します。
            bq show --format=prettyjson dataset.table
            
      • オプション 2: [フィールドを追加] をクリックして、テーブル スキーマを入力します。各フィールドの名前モードを指定します。
    4. [クラスタリング順序] で、1~4 個のフィールド名をカンマで区切って入力します。
    5. 省略可: [詳細オプション] セクションで、顧客管理の暗号鍵を使用する場合は、[顧客管理の暗号鍵(CMEK)を使用] オプションを選択します。BigQuery のデフォルトでは、Google が管理する鍵を使用して、保存されているお客様のコンテンツを暗号化します。
    6. [テーブルを作成] をクリックします。

SQL

CREATE TABLE DDL ステートメント コマンドと CLUSTER BY オプションを使用します。次の例では、myclusteredtable という名前のクラスタ化テーブルを mydataset に作成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで次のステートメントを入力します。

    CREATE TABLE mydataset.myclusteredtable
    (
      customer_id STRING,
      transaction_amount NUMERIC
    )
    CLUSTER BY
      customer_id
      OPTIONS (
        description = 'a table clustered by customer_id');
    

  3. [実行] をクリックします。

クエリの実行方法については、インタラクティブ クエリを実行するをご覧ください。

bq

次のフラグを指定して、bq mk コマンドを使用します。

  • --table(または -t ショートカット)。
  • --schema。テーブルのスキーマ定義をインラインで、または JSON スキーマ ファイルを使用して指定できます。
  • --clustering_fields。最大 4 つのクラスタリング列を指定できます。

オプション パラメータには --expiration--description--time_partitioning_type--time_partitioning_field--time_partitioning_expiration--destination_kms_key--label があります。

デフォルト以外のプロジェクトでテーブルを作成する場合は、project_id:dataset の形式でプロジェクト ID をデータセットに追加します。

--destination_kms_key はここでは説明しません。--destination_kms_key の使用方法の詳細については、顧客管理の暗号鍵をご覧ください。

次のコマンドを入力して、スキーマ定義を指定して空のクラスタ化テーブルを作成します。

bq mk \
    --table \
    --expiration INTEGER1 \
    --schema SCHEMA \
    --clustering_fields CLUSTER_COLUMNS \
    --description "DESCRIPTION" \
    --label KEY:VALUE,KEY:VALUE \
    PROJECT_ID:DATASET.TABLE

次のように置き換えます。

  • INTEGER1: テーブルのデフォルトの存続期間(秒)です。最小値は 3,600 秒(1 時間)です。現在の UTC 時間にこの整数値を足した値が有効期限になります。テーブルの作成時に有効期限を設定した場合、データセットのデフォルトのテーブル有効期限設定は無視されます。この値を設定すると、指定した時間が経過したときにテーブルは削除されます。
  • SCHEMA: COLUMN:DATA_TYPE,COLUMN:DATA_TYPE の形式のインライン スキーマ定義か、ローカルマシン上の JSON スキーマ ファイルのパスです。
  • CLUSTER_COLUMNS: 最大 4 つのクラスタリング列のカンマ区切りリスト。リストには、スペースを含めることはできません。
  • DESCRIPTION: テーブルの説明です。引用符で囲みます。
  • KEY:VALUE: ラベルを表す Key-Value ペアです。カンマ区切りのリストを使用して複数のラベルを入力できます。
  • PROJECT_ID: プロジェクト ID。
  • DATASET: プロジェクト内のデータセット。
  • TABLE: 作成するテーブルの名前。

コマンドラインでスキーマを指定する場合、RECORDSTRUCT)型と列の説明を含めることはできません。また、列のモードも指定できません。すべてのモードはデフォルトの NULLABLE になります。説明、モード、RECORD 型を含めるには、JSON スキーマ ファイルを指定します。

例:

デフォルト プロジェクトにある mydataset 内に myclusteredtable という名前のクラスタ化テーブルを作成するには、次のコマンドを入力します。テーブルの有効期限は 2,592,000 秒(1 か月、つまり 30 日)、説明は This is my clustered table、ラベルは organization:development に設定されます。このコマンドでは --table ではなく -t ショートカットを使用しています。

スキーマはインラインで timestamp:timestamp,customer_id:string,transaction_amount:float と指定されています。指定されたクラスタリング フィールド customer_id は、テーブルをクラスタ化するために使用されます。

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

デフォルト プロジェクトではない myotherproject 内に myclusteredtable という名前のクラスタ化テーブルを作成するには、次のコマンドを入力します。説明は This is my clustered table に、ラベルは organization:development に設定されます。このコマンドでは --table ではなく -t ショートカットを使用しています。このコマンドではテーブルの有効期限を指定していません。データセットにデフォルトのテーブル有効期限がある場合、それが適用されます。データセットにデフォルトのテーブル有効期限がない場合、テーブルは期限切れになりません。

スキーマは、/tmp/myschema.json というローカル JSON ファイルで定義されています。customer_id フィールドは、テーブルをクラスタ化するために使用されます。

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

テーブルの作成後に、テーブルの説明ラベルを更新できます。

Terraform

google_bigquery_table リソースを使用します。

次の例では、ID 列と Created 列でクラスタ化される mytable というテーブルを作成します。

resource "google_bigquery_dataset" "default" {
  dataset_id                      = "mydataset"
  default_partition_expiration_ms = 2592000000  # 30 days
  default_table_expiration_ms     = 31536000000 # 365 days
  description                     = "dataset description"
  location                        = "US"
  max_time_travel_hours           = 96 # 4 days

  labels = {
    billing_group = "accounting",
    pii           = "sensitive"
  }
}

resource "google_bigquery_table" "default" {
  dataset_id          = google_bigquery_dataset.default.dataset_id
  table_id            = "mytable"
  deletion_protection = false # set to "true" in production

  clustering = ["ID", "Created"]

  schema = <<EOF
[
  {
    "name": "ID",
    "type": "INT64",
    "description": "Item ID"
  },
  {
    "name": "Item",
    "type": "STRING",
    "mode": "NULLABLE"
  },
 {
   "name": "Created",
   "type": "TIMESTAMP"
 }
]
EOF

}

Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。

Cloud Shell を準備する

  1. Cloud Shell を起動します。
  2. Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。

    このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。

ディレクトリを準備する

Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。

  1. Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は .tf にする必要があります(例: main.tf)。このチュートリアルでは、このファイルを main.tf とします。
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。

    新しく作成した main.tf にサンプルコードをコピーします。

    必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。

  3. 環境に適用するサンプル パラメータを確認し、変更します。
  4. 変更を保存します。
  5. Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行います。
    terraform init

    最新バージョンの Google プロバイダを使用する場合は、-upgrade オプションを使用します。

    terraform init -upgrade

変更を適用する

  1. 構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
    terraform plan

    必要に応じて構成を修正します。

  2. 次のコマンドを実行します。プロンプトで「yes」と入力して、Terraform 構成を適用します。
    terraform apply

    Terraform に「Apply complete!」というメッセージが表示されるまで待ちます。

  3. Google Cloud プロジェクトを開いて結果を表示します。Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。

API

clustering.fields プロパティと schema プロパティを指定する定義済みのテーブル リソースを使用して tables.insert メソッドを呼び出します。

Python

このサンプルを試す前に、クライアント ライブラリを使用した BigQuery クイックスタートPython の手順に沿って設定を行ってください。詳細については、BigQuery Python API のリファレンス ドキュメントをご覧ください。

BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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.clustering_fields = ["city", "zipcode"]
table = client.create_table(table)  # Make an API request.
print(
    "Created clustered table {}.{}.{}".format(
        table.project, table.dataset_id, table.table_id
    )
)

Go

このサンプルを試す前に、クライアント ライブラリを使用した BigQuery クイックスタートGo の手順に沿って設定を行ってください。詳細については、BigQuery Go API のリファレンス ドキュメントをご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した BigQuery クイックスタートJava の手順に沿って設定を行ってください。詳細については、BigQuery Java API のリファレンス ドキュメントをご覧ください。

BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

クエリ結果からクラスタ化テーブルを作成する

クエリ結果からクラスタ化テーブルを作成するには、次の 2 つの方法があります。

パーティション分割テーブル、パーティション分割されていないテーブルのいずれのクエリからでも、クラスタ化テーブルを作成できます。クエリ結果を使用して、既存のテーブルをクラスタ化テーブルに変更することはできません。

クエリ結果からクラスタ化テーブルを作成する場合、標準 SQL を使用する必要があります。現時点では、クラスタ化テーブルをクエリする場合や、クエリ結果をクラスタ化テーブルに書き込む場合に、レガシー SQL はサポートされていません。

SQL

クエリ結果からクラスタ化テーブルを作成するには、CLUSTER BY オプションを指定して CREATE TABLE DDL ステートメントを使用します。次の例では、クラスタ化されていない既存のテーブルに対してクエリを実行し、customer_id でクラスタ化された新しいテーブルを作成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで次のステートメントを入力します。

    CREATE TABLE mydataset.clustered_table
    (
      customer_id STRING,
      transaction_amount NUMERIC
    )
    CLUSTER BY
      customer_id
    AS (
      SELECT * FROM mydataset.unclustered_table
    );
    

  3. [実行] をクリックします。

クエリの実行方法については、インタラクティブ クエリを実行するをご覧ください。

bq

次のコマンドを入力して、クエリ結果から新しいクラスタ化テーブルを作成します。

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

次のように置き換えます。

  • LOCATION: ロケーションの名前。--location フラグは省略可能です。たとえば、BigQuery を東京リージョンで使用している場合は、このフラグの値を asia-northeast1 に設定します。.bigqueryrc ファイルを使用してロケーションのデフォルト値を設定できます。
  • QUERY: GoogleSQL 構文のクエリ。現時点では、レガシー SQL を使用して、クラスタ化テーブルをクエリすることや、クエリ結果をクラスタ化テーブルに書き込むことはできません。クエリには、クラスタ化テーブルを作成するためのオプションを指定した CREATE TABLE DDL ステートメントを含めることができます。個々のコマンドライン フラグを指定するのではなく、DDL を使用できます。

例:

次のコマンドを入力すると、mydataset 内の myclusteredtable というクラスタ化テーブルにクエリ結果が書き込まれます。mydataset はデフォルト プロジェクトにあります。このクエリは、パーティション分割されていないテーブル(mytable)からデータを取得します。このテーブルの customer_id 列は、テーブルのクラスタ化に使用されます。このテーブルの timestamp 列は、パーティション分割テーブルの作成に使用されます。

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

API

クエリ結果をクラスタ化テーブルに保存するには、jobs.insert メソッドを呼び出し、query ジョブを構成して、クラスタ化テーブルを作成する CREATE TABLE DDL ステートメントを含めます。

ジョブリソースjobReference セクションにある location プロパティでロケーションを指定します。

データの読み込み時にクラスタ化テーブルを作成する

新しいテーブルにデータを読み込むときに、クラスタリング列を指定することによってクラスタ化テーブルを作成できます。データを読み込む前に空のテーブルを作成する必要はありません。クラスタ化テーブルを作成すると同時にデータを読み込むことができます。

データの読み込みの詳細については、BigQuery へのデータの読み込みの概要をご覧ください。

読み込みジョブを定義するときにクラスタリングを定義するには:

SQL

LOAD DATA ステートメントを使用します。次の例では、AVRO データを読み込んで transaction_date フィールドで分割されたテーブルを作成し、customer_id フィールドでクラスタ化しています。また、パーティションが 3 日後に期限切れになるように構成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで次のステートメントを入力します。

    LOAD DATA INTO mydataset.mytable
    PARTITION BY transaction_date
    CLUSTER BY customer_id
      OPTIONS (
        partition_expiration_days = 3)
    FROM FILES(
      format = 'AVRO',
      uris = ['gs://bucket/path/file.avro']);
    

  3. [実行] をクリックします。

クエリの実行方法については、インタラクティブ クエリを実行するをご覧ください。

API

読み込みジョブを介してテーブルを作成する際にクラスタリング構成を定義するには、テーブルの Clustering プロパティをテーブルに入力します。

Go

このサンプルを試す前に、クライアント ライブラリを使用した BigQuery クイックスタートGo の手順に沿って設定を行ってください。詳細については、BigQuery Go API のリファレンス ドキュメントをご覧ください。

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

このサンプルを試す前に、クライアント ライブラリを使用した BigQuery クイックスタートJava の手順に沿って設定を行ってください。詳細については、BigQuery Java API のリファレンス ドキュメントをご覧ください。

BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

Python

このサンプルを試す前に、クライアント ライブラリを使用した BigQuery クイックスタートPython の手順に沿って設定を行ってください。詳細については、BigQuery Python API のリファレンス ドキュメントをご覧ください。

BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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"

job_config = bigquery.LoadJobConfig(
    skip_leading_rows=1,
    source_format=bigquery.SourceFormat.CSV,
    schema=[
        bigquery.SchemaField("timestamp", bigquery.SqlTypeNames.TIMESTAMP),
        bigquery.SchemaField("origin", bigquery.SqlTypeNames.STRING),
        bigquery.SchemaField("destination", bigquery.SqlTypeNames.STRING),
        bigquery.SchemaField("amount", bigquery.SqlTypeNames.NUMERIC),
    ],
    time_partitioning=bigquery.TimePartitioning(field="timestamp"),
    clustering_fields=["origin", "destination"],
)

job = client.load_table_from_uri(
    ["gs://cloud-samples-data/bigquery/sample-transactions/transactions.csv"],
    table_id,
    job_config=job_config,
)

job.result()  # Waits for the job to complete.

table = client.get_table(table_id)  # Make an API request.
print(
    "Loaded {} rows and {} columns to {}".format(
        table.num_rows, len(table.schema), table_id
    )
)

クラスタ化テーブルへのアクセスを制御する

テーブルとビューへのアクセスを構成するには、エンティティに次のレベルで IAM ロールを付与します。以下に、各レベルを許可されるリソースの範囲が大きい順に一覧で示します。

  • Google Cloud リソース階層の上位レベル(プロジェクト、フォルダ、組織レベルなど)
  • データセット レベル
  • テーブルまたはビューレベル

次の方法で、テーブル内のデータアクセスを制限することもできます。

IAM で保護されているリソースを使用したアクセスは追加型です。たとえば、エンティティにプロジェクトなどの上位レベルのアクセス権がない場合は、データセット レベルでアクセス権を付与すると、データセット内のテーブルとビューにアクセスできます。同様に、エンティティに高レベルまたはデータセット レベルでのアクセス権がない場合は、テーブルまたはビューレベルでエンティティにアクセス権を付与できます。

プロジェクト、フォルダ、組織レベルなど、Google Cloud リソース階層の上位レベルで IAM ロールを付与すると、エンティティは幅広いリソースのセットにアクセスできるようになります。たとえば、プロジェクト レベルでエンティティにロールを付与すると、そのエンティティには、プロジェクトに含まれるすべてのデータセットに適用される権限が付与されます。

データセット レベルでロールを付与すると、そのエンティティが上位レベルでアクセスできない場合でも、そのデータセットのテーブルとビューで実行できるオペレーションが指定されます。データセット レベルのアクセス制御を構成する方法については、データセットへのアクセスの制御をご覧ください。

テーブルまたはビューレベルでロールを付与すると、エンティティに上位レベルのアクセスがない場合でも、特定のテーブルやビューに対してエンティティが実行できるオペレーションが特定されます。テーブルレベルのアクセス制御の構成については、テーブルおよびビューへのアクセスの制御をご覧ください。

また、IAM カスタムロールを作成することもできます。カスタムロールを作成する場合、エンティティに実行を許可する特定のオペレーションによって、付与する権限は異なります。

IAM で保護されているリソースに「拒否」権限を設定することはできません。

ロールと権限の詳細については、IAM のドキュメントでロールの概要と BigQuery の IAM のロールと権限をご覧ください。

クラスタ化テーブルを使用する

クラスタ化テーブルに関する情報を取得する

テーブルに関する情報は、次の方法で取得できます。

  • Google Cloud コンソールを使用する。
  • bq コマンドライン ツールの bq show コマンドを使用する。
  • tables.get API メソッドを呼び出す。
  • INFORMATION_SCHEMA ビューのクエリを実行する。

必要な権限

テーブルに関する情報を取得するには、少なくとも bigquery.tables.get 権限が付与されている必要があります。次の事前定義済みの IAM ロールには bigquery.tables.get 権限が含まれています。

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

また、bigquery.datasets.create 権限を持つユーザーがデータセットを作成すると、そのデータセットに対する bigquery.dataOwner アクセス権がユーザーに付与されます。bigquery.dataOwner アクセス権により、データセットのテーブルに関する情報の取得が許可されます。

BigQuery での IAM のロールと権限について詳しくは、事前定義ロールと権限をご覧ください。

クラスタ化テーブルの情報を取得する

クラスタ化テーブルに関する情報を表示するには:

コンソール

  1. Google Cloud Console で、[リソース] ペインに移動します。データセット名をクリックして展開し、表示するテーブル名をクリックします。

  2. [詳細] をクリックします。このページには、クラスタリング列を含むテーブルの詳細情報が表示されます。

    テーブルの詳細。

SQL

クラスタ化テーブルの場合、INFORMATION_SCHEMA.COLUMNS ビューCLUSTERING_ORDINAL_POSITION 列をクエリして、テーブルのクラスタリング列内の列の 1 から始まるオフセットを検索できます。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで次のステートメントを入力します。

    CREATE TABLE mydataset.data (column1 INT64, column2 INT64)
    CLUSTER BY column1, column2;
    SELECT
      column_name, clustering_ordinal_position
    FROM
      mydataset.INFORMATION_SCHEMA.COLUMNS;
    

  3. [実行] をクリックします。

クエリの実行方法については、インタラクティブ クエリを実行するをご覧ください。

クラスタリングの順序位置は、column1 の場合は 1、column2 の場合は 2 です。テーブルに関するその他のメタデータは INFORMATION_SCHEMATABLESTABLE_OPTIONSCOLUMNSCOLUMN_FIELD_PATH の各ビューで取得できます。

bq

すべてのテーブル情報を表示するには、bq show コマンドを発行します。テーブルのスキーマ情報のみを表示するには、--schema フラグを使用します。--format フラグを使用して出力を制御できます。

デフォルト以外のプロジェクトにあるテーブルの情報を取得する場合は、project_id:dataset の形式でプロジェクト ID をデータセットに追加します。

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

次のように置き換えます。

  • PROJECT_ID: プロジェクト ID
  • DATASET: データセットの名前。
  • TABLE: テーブルの名前。

例:

次のコマンドを入力して、mydataset にある myclusteredtable に関するすべての情報を表示します。mydataset はデフォルトのプロジェクトにあります。

bq show --format=prettyjson mydataset.myclusteredtable

出力は次のようになります。

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

API

bigquery.tables.get メソッドを呼び出し、関連パラメータを指定します。

データセット内のクラスタ化テーブルを一覧表示する

データセット内のクラスタ化テーブルは、次の方法で一覧表示できます。

  • Google Cloud コンソールを使用する。
  • bq コマンドライン ツールの bq ls コマンドを使用する。
  • tables.list API メソッドを呼び出す。
  • クライアント ライブラリを使用する。
  • INFORMATION_SCHEMA.COLUMNS ビューで CLUSTERING_ORDINAL_POSITION 列をクエリする。

クラスタ化テーブルを一覧表示するために必要な権限と、それらを一覧表示する手順は、標準テーブルの場合と同じです。テーブルの一覧表示の詳細については、データセット内のテーブルの一覧表示をご覧ください。

クラスタリング仕様を変更する

テーブルのクラスタリング仕様の変更や削除を行うことができます。また、クラスタ化テーブル内のクラスタ化列のセットを変更することもできます。クラスタリング列セットを更新するこの方法は、継続的ストリーミング挿入を使用するテーブルに対して有効です。これらのテーブルは他の方法では簡単に入れ替えできません。

パーティション分割されていないテーブルまたはパーティション分割テーブルに新しいクラスタリング仕様を適用する手順は次のとおりです。

  1. bq ツールで、新しいクラスタリングと一致するようにテーブルのクラスタリング仕様を更新します。

     bq update --clustering_fields=CLUSTER_COLUMN DATASET.ORIGINAL_TABLE 

    次のように置き換えます。

    • CLUSTER_COLUMN: クラスタリングする列(例: mycolumn
    • DATASET: テーブルを含むデータセットの名前(例: mydataset
    • ORIGINAL_TABLE: 元のテーブルの名前(例: mytable

    tables.update または tables.patch の API メソッドを呼び出して、クラスタリング仕様を変更することもできます。

  2. 新しいクラスタリング仕様に従ってすべての行をクラスタ化するには、次の UPDATE ステートメントを実行します。

    UPDATE DATASET.ORIGINAL_TABLE SET CLUSTER_COLUMN=CLUSTER_COLUMN WHERE true
    

テーブルのセキュリティ

BigQuery でテーブルへのアクセスを制御するには、テーブルのアクセス制御の概要をご覧ください。

次のステップ

  • クラスタ化テーブルのクエリについては、