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

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

制限事項

BigQuery のクラスタ化テーブルには、次の制限があります。

  • クラスタリングはパーティション分割テーブルに対してのみサポートされています。
  • クラスタ化テーブルのクエリと、クラスタ化テーブルに対するクエリ結果の書き込みについては、標準 SQL のみがサポートされています。
  • テーブルの作成時にはクラスタリング列のみを指定できます。
  • クラスタ化テーブルを作成した後、クラスタリング列を変更することはできません。
  • クラスタリング列は最上位の繰り返しでない列であることが必要です。データ型は次のいずれかでなければなりません。

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

    データ型の詳細については、標準 SQL のデータ型をご覧ください。

  • 最大 4 つのクラスタリング列を指定できます。

  • クラスタリングに STRING 型の列を使用する場合、BigQuery は最初の 1,024 文字のみを使用してデータをクラスタリングします。列の値自体は 1,024 文字を超える場合があります。

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

現在、クラスタ化できるのはパーティション分割テーブルのみです。これには、取り込み時間パーティション分割テーブルと、TIMESTAMP 列または DATE 列によってパーティション分割されたテーブルの両方が含まれます。

BigQuery では次のようにしてクラスタ化テーブルを作成できます。

テーブルの命名

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

  • 1,024 文字以内
  • 英字(大文字または小文字)、数字、アンダースコアだけが含まれている

必要な権限

テーブルを作成するには、少なくとも次の権限が付与されている必要があります。

  • bigquery.tables.create(テーブルを作成する権限)
  • bigquery.tables.updateData(読み込みジョブ、クエリジョブ、コピージョブを使用してテーブルにデータを書き込む権限)
  • bigquery.jobs.create(クエリジョブ、読み込みジョブ、コピージョブを実行してテーブルにデータを書き込む権限)

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

bigquery.tables.create 権限および bigquery.tables.updateData 権限はいずれも、事前定義された以下の Cloud IAM のロールに含まれています。

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

bigquery.jobs.create 権限は、事前定義された以下の Cloud IAM の役割に含まれています。

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

また、bigquery.datasets.create 権限を持つユーザーがデータセットを作成すると、そのデータセットに対する bigquery.dataOwner アクセス権がユーザーに付与されます。bigquery.dataOwner アクセス権があれば、データセット内でテーブルを作成および更新できます。

BigQuery での Cloud IAM の役割と権限については、事前定義された役割と権限をご覧ください。

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

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

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

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

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

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

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

Console

  1. Google Cloud Console で、BigQuery ウェブ UI に移動します。

    BigQuery ウェブ UI に移動

  2. ナビゲーション パネルの [リソース] セクションでプロジェクトを展開し、データセットを選択します。

  3. ウィンドウの右側の詳細パネルで、[テーブルを作成] をクリックします。

    [テーブルを作成] ボタン。

  4. [テーブルの作成] ページの [ソース] に移動し、[テーブルの作成元] で [空のテーブル] を選択します。

    [テーブルの作成元] オプション。

  5. [送信先] で次の操作を行います。

    • [データセット名] で該当するデータセットを選択し、作成するテーブルの名前を [テーブル名] フィールドに入力します。
    • [テーブルタイプ] が [ネイティブ テーブル] に設定されていることを確認します。
  6. [スキーマ] にスキーマ定義を入力します。

    • スキーマ情報を手動で入力します。

      • [テキストとして編集] を有効にし、テーブル スキーマを JSON 配列として入力します。

      • [フィールドを追加] を使用して、スキーマを手動で入力します。

  7. [パーティションとクラスタの設定] で [フィールドにより分割] を選択し、DATE 列または TIMESTAMP 列を選択します。スキーマに DATE 列または TIMESTAMP 列が含まれていない場合、このオプションは使用できません。

    取り込み時間パーティション分割テーブルを作成するには、[取り込み時間により分割] を選択します。

  8. (省略可)クエリを実行するパーティショニングを指定する WHERE 句の使用を必須にするには、[パーティショニング フィルタ] で [パーティション フィルタを要求] チェックボックスをクリックします。パーティション フィルタを必須にすると、コストが削減され、パフォーマンスが向上する場合があります。詳細については、パーティション分割テーブルのクエリをご覧ください。

  9. [クラスタリング順序] で、1~4 個のフィールド名をカンマで区切って入力します。

  10. (省略可)[詳細オプション] をクリックします。Cloud Key Management Service 鍵を使用する場合は、[暗号化] で [顧客管理の暗号鍵] をクリックします。[Google が管理する鍵] の設定をそのままにすると、BigQuery は保存データを暗号化します。

  11. [テーブルを作成] をクリックします。

従来の UI

  1. 従来の BigQuery ウェブ UI に移動します。

    従来の BigQuery ウェブ UI に移動

  2. ナビゲーション パネルで、データセット名の横にある下矢印アイコン 下矢印アイコン。 をクリックし、[Create new table] をクリックします。

  3. [Create Table] ページの [Source Data] セクションで、[Create empty table] をクリックします。

  4. [Create Table] ページの [Destination Table] セクションで、次の操作を行います。

    • [Table name] で適切なデータセットを選択し、作成するテーブルの名前をテーブル名のフィールドに入力します。
    • [Table type] が [Native table] に設定されていることを確認します。
  5. [Schema] セクションで、スキーマ定義を手動で入力します。

    • スキーマ情報は次の方法により手動で入力できます。

      • [Edit as Text] をクリックし、テーブル スキーマを JSON 配列として入力します。

      • [Add Field] を使用してスキーマを入力します。

  6. [Option] で次の操作を行います。

    • [Partitioning Type] で、[None] をクリックして [Day] を選択します。
    • [Partitioning Field] で、次のいずれかを選択します。
      • DATE 列または TIMESTAMP 列でパーティション分割されたテーブルを作成するには、timestamp を選択します。
      • 取り込み時間パーティション分割テーブルを作成するには、_PARTITIONTIME を選択します。
    • [Clustering Fields] で、1 つから 4 つまでのフィールド名を入力します。
    • [Destination Encryption] は Default のままにします。このプロパティは、顧客管理の暗号鍵に使用されます。BigQuery のデフォルトでは、格納するお客様のコンテンツを保存時に暗号化します。

      パーティション分割テーブルの詳細。

  7. [Create Table] をクリックします。

テーブルの作成後に、クラスタ化テーブルのテーブル有効期限説明ラベルを更新できます。BigQuery ウェブ UI を使用してテーブルを作成した後にパーティションの有効期限を追加することはできません。

bq

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

  • --table(または -t ショートカット)。
  • --schema。テーブルのスキーマ定義をインラインで、または JSON スキーマ ファイルを使用して指定できます。
  • --time_partitioning_type(取り込み時間パーティション分割テーブルの場合)、または --time_partitioning_field(パーティション分割テーブルの場合)。現時点では、--time_partitioning_type でサポートされている値は DAY のみです。
  • --clustering_fields。最大 4 つのクラスタリング列を指定できます。

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

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

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

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

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

以下を置き換えます。

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

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

例:

デフォルト プロジェクトにある mydataset 内に myclusteredtable という名前のクラスタ化テーブルを作成するには、次のコマンドを入力します。テーブルは(TIMESTAMP 列で分割された)パーティション分割テーブルです。パーティショニングの有効期限は 86,400 秒(1 日)、テーブルの有効期限は 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' \
--time_partitioning_field timestamp \
--clustering_fields customer_id \
--time_partitioning_expiration 86400  \
--description "This is my clustered table" \
--label org:dev \
mydataset.myclusteredtable

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

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

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

テーブルを作成した後に、パーティション分割テーブルのテーブル有効期限パーティション有効期限説明ラベルを更新できます。

API

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

Go

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

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 のリファレンス ドキュメントをご覧ください。

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 はサポートされていません。

Console

BigQuery ウェブ UI を使用してデータをクエリする場合は、DDL ステートメントを使用する場合を除き、宛先テーブルのクラスタリング オプションを指定することはできません。詳細については、データ定義言語ステートメントの使用をご覧ください。

従来の UI

従来の BigQuery ウェブ UI を使用してデータをクエリする場合は、DDL ステートメントを使用する場合を除き、宛先テーブルのクラスタリング オプションを指定することはできません。詳細については、データ定義言語ステートメントの使用をご覧ください。

bq

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

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

以下を置き換えます。

  • LOCATION: ロケーションの名前。--location フラグは省略可能です。たとえば、BigQuery を東京リージョンで使用している場合は、このフラグの値を asia-northeast1 に設定します。.bigqueryrc ファイルを使用してロケーションのデフォルト値を設定できます。
  • QUERY: 標準 SQL 構文のクエリ。現時点では、レガシー 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 へのデータの読み込みの概要をご覧ください。

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

API

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

Go

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

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 のリファレンス ドキュメントをご覧ください。

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

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

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

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

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

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

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

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

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

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

ロールと権限の詳細については、以下をご覧ください。

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

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

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

  • Cloud Console または従来の BigQuery ウェブ UI を使用する
  • bq show コマンドライン インターフェース コマンドを使用する
  • tables.get API メソッドを呼び出す
  • INFORMATION_SCHEMA ビューのクエリ

必要な権限

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

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

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

BigQuery での Cloud IAM の役割と権限については、事前定義された役割と権限をご覧ください。

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

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

Console

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

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

    テーブルの詳細。

従来の UI

  1. ナビゲーション パネルで、データセットの左側にある下矢印アイコン 下矢印アイコン。 をクリックして展開するか、データセット名をダブルクリックします。これにより、データセット内のテーブルとビューが表示されます。

  2. テーブル名をクリックします。

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

    クラスタ化テーブルの詳細

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 メソッドを呼び出し、関連パラメータを指定します。

SQL

クラスタ化テーブルの場合、INFORMATION_SCHEMA.COLUMNS ビュー内の CLUSTERING_ORDINAL_POSITION 列をクエリして、テーブルのクラスタリング列に関する情報を取得できます。

-- 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;

テーブルに関するその他のメタデータは INFORMATION_SCHEMATABLESTABLE_OPTIONSCOLUMNSCOLUMN_FIELD_PATH の各ビューで取得できます。

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

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

  • Cloud Console または従来の BigQuery ウェブ UI を使用する
  • bq ls コマンドライン インターフェース コマンドを使用する
  • tables.list API メソッドを呼び出す
  • クライアント ライブラリを使用する
  • INFORMATION_SCHEMA.COLUMNS ビューで CLUSTERING_ORDINAL_POSITION 列をクエリする

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

クラスタリング仕様の変更

tables.update メソッドまたは tables.patch メソッドを呼び出すと、テーブル クラスタリングの仕様を変更または削除できます。クラスタ化テーブル内のクラスタ化列のセットは、別の列のセットに変更することもできます。クラスタリング列セットを更新するこの方法は最も、継続的ストリーミング挿入を使用するテーブルに利用できます。その他の方法では簡単に入れ替えできません。

非クラスタ化テーブルがクラスタ化テーブルに変換、またはクラスタ化列セットが変更された場合、自動再クラスタリングはその時間以降にのみ使用できます。たとえば、tables.update を使用してクラスタ化テーブルに変換された 1 PB の非クラスタ化テーブルには、1 PB の非クラスタ化データが含まれたままです。自動再クラスタリングは、更新後にテーブルに保存された新しいデータにのみ適用されます。

開発中の機能

次の機能は開発中ですが、現時点のアルファ版では利用できません。

  • ネイティブ(パーティション分割されていない)テーブルのクラスタリングのサポート。
  • クラスタリング列でフィルタを使用する特定の種類のクエリのコストの削減。

次のステップ