跳到主要内容
跳到主要内容

gcs 表函数

提供一个类表接口,用于在 Google Cloud Storage(GCS) 中执行 SELECTINSERT 操作。需要具备 Storage Object User IAM 角色

这是 s3 表函数 的别名。

如果集群中有多个副本,可以改用 s3Cluster 函数(同样适用于 GCS)来并行化写入。

语法

gcs(url [, NOSIGN | hmac_key, hmac_secret] [,format] [,structure] [,compression_method])
gcs(named_collection[, option=value [,..]])
GCS

GCS 表函数通过 GCS XML API 和 HMAC 密钥与 Google Cloud Storage 集成。 有关端点和 HMAC 的更多信息,请参阅 Google 互操作性文档

参数

参数描述
url文件在 bucket 中的路径。在只读模式下支持以下通配符:***?{abc,def}{N..M},其中 NM 为数字,'abc''def' 为字符串。
NOSIGN如果在凭证位置提供该关键字,则所有请求都不会进行签名。
hmac_key and hmac_secret指定用于给定 endpoint 的凭证密钥。可选。
format文件的格式
structure表结构。格式:'column1_name column1_type, column2_name column2_type, ...'
compression_method可选参数。支持的值:nonegzipgzbrotlibrxzLZMAzstdzst。默认情况下,将根据文件扩展名自动检测压缩方法。
GCS

GCS 路径采用此格式,是因为 Google XML API 的 endpoint 与 JSON API 不同:

  https://storage.googleapis.com/<bucket>/<folder>/<filename(s)>

而不是 https://storage.cloud.google.com

参数也可以通过命名集合进行传递。在这种情况下,urlformatstructurecompression_method 的行为相同,并且还支持一些额外参数:

ParameterDescription
access_key_idhmac_key,可选。
secret_access_keyhmac_secret,可选。
filename如果指定,则会追加到 URL 末尾。
use_environment_credentials默认启用,允许通过环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URIAWS_CONTAINER_CREDENTIALS_FULL_URIAWS_CONTAINER_AUTHORIZATION_TOKENAWS_EC2_METADATA_DISABLED 传递额外参数。
no_sign_request默认禁用。
expiration_window_seconds默认值为 120。

返回值

具有指定结构的表,用于从指定文件读取或向其写入数据。

示例

从 GCS 文件 https://storage.googleapis.com/my-test-bucket-768/data.csv 中选取表的前两行:

SELECT *
FROM gcs('https://storage.googleapis.com/clickhouse_public_datasets/my-test-bucket-768/data.csv.gz', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
LIMIT 2;
┌─column1─┬─column2─┬─column3─┐
│       1 │       2 │       3 │
│       3 │       2 │       1 │
└─────────┴─────────┴─────────┘

类似的示例,不过来自使用 gzip 压缩方式的文件:

SELECT *
FROM gcs('https://storage.googleapis.com/clickhouse_public_datasets/my-test-bucket-768/data.csv.gz', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32', 'gzip')
LIMIT 2;
┌─column1─┬─column2─┬─column3─┐
│       1 │       2 │       3 │
│       3 │       2 │       1 │
└─────────┴─────────┴─────────┘

用法

假设我们在 GCS 中有若干文件,其 URI 如下:

统计文件名以数字 1 到 3 结尾的文件中的行数:

SELECT count(*)
FROM gcs('https://storage.googleapis.com/clickhouse_public_datasets/my-test-bucket-768/{some,another}_prefix/some_file_{1..3}.csv', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
┌─count()─┐
│      18 │
└─────────┘

计算这两个目录中所有文件的总行数:

SELECT count(*)
FROM gcs('https://storage.googleapis.com/clickhouse_public_datasets/my-test-bucket-768/{some,another}_prefix/*', 'CSV', 'column1 UInt32, column2 UInt32, column3 UInt32')
┌─count()─┐
│      24 │
└─────────┘
注意

如果你的文件列表中包含带前导零的编号范围,请对每一位数字分别使用花括号的形式,或者使用 ?

统计名为 file-000.csvfile-001.csv、…、file-999.csv 这些文件中的总行数:

SELECT count(*)
FROM gcs('https://storage.googleapis.com/clickhouse_public_datasets/my-test-bucket-768/big_prefix/file-{000..999}.csv', 'CSV', 'name String, value UInt32');
┌─count()─┐
│      12 │
└─────────┘

向文件 test-data.csv.gz 中插入数据:

INSERT INTO FUNCTION gcs('https://storage.googleapis.com/my-test-bucket-768/test-data.csv.gz', 'CSV', 'name String, value UInt32', 'gzip')
VALUES ('test-data', 1), ('test-data-2', 2);

将现有表中的数据导出到文件 test-data.csv.gz

INSERT INTO FUNCTION gcs('https://storage.googleapis.com/my-test-bucket-768/test-data.csv.gz', 'CSV', 'name String, value UInt32', 'gzip')
SELECT name, value FROM existing_table;

Glob 模式 ** 可用于递归遍历目录。参考以下示例,它会递归地获取 my-test-bucket-768 目录下的所有文件:

SELECT * FROM gcs('https://storage.googleapis.com/my-test-bucket-768/**', 'CSV', 'name String, value UInt32', 'gzip');

下面的示例将递归地从 my-test-bucket 目录下各级子目录中的所有 test-data.csv.gz 文件中获取数据:

SELECT * FROM gcs('https://storage.googleapis.com/my-test-bucket-768/**/test-data.csv.gz', 'CSV', 'name String, value UInt32', 'gzip');

在生产环境中,推荐使用命名集合。示例如下:


CREATE NAMED COLLECTION creds AS
        access_key_id = '***',
        secret_access_key = '***';
SELECT count(*)
FROM gcs(creds, url='https://s3-object-url.csv')

分区写入

如果在向 GCS 表插入数据时指定了 PARTITION BY 表达式,则会为每个分区值创建一个单独的文件。将数据拆分为多个独立文件有助于提升读操作的效率。

示例

  1. 在键中使用分区 ID 会创建单独的文件:
INSERT INTO TABLE FUNCTION
    gcs('http://bucket.amazonaws.com/my_bucket/file_{_partition_id}.csv', 'CSV', 'a String, b UInt32, c UInt32')
    PARTITION BY a VALUES ('x', 2, 3), ('x', 4, 5), ('y', 11, 12), ('y', 13, 14), ('z', 21, 22), ('z', 23, 24);

因此,数据会被写入三个文件:file_x.csvfile_y.csvfile_z.csv

  1. 在 bucket 名称中使用分区 ID 会在不同的 bucket 中生成文件:
INSERT INTO TABLE FUNCTION
    gcs('http://bucket.amazonaws.com/my_bucket_{_partition_id}/file.csv', 'CSV', 'a UInt32, b UInt32, c UInt32')
    PARTITION BY a VALUES (1, 2, 3), (1, 4, 5), (10, 11, 12), (10, 13, 14), (20, 21, 22), (20, 23, 24);

因此,数据将被写入位于不同 bucket 中的三个文件:my_bucket_1/file.csvmy_bucket_10/file.csvmy_bucket_20/file.csv