提供类似表的接口,可对 Google Cloud Storage 中的数据执行 SELECT 和 INSERT。需要 Storage Object User IAM role。
这是 s3 表函数 的别名。
如果你的集群中有多个副本,可以改用 s3Cluster 函数 (可与 GCS 配合使用) 来并行执行插入操作。
语法
gcs(url [, NOSIGN | hmac_key, hmac_secret] [,format] [,structure] [,compression_method] [,partition_strategy])
gcs(named_collection[, option=value [,..]])参数
| 参数 | 描述 |
|---|---|
url |
指向文件的存储桶路径。在只读模式下支持以下通配符:*、**、?、{abc,def} 和 {N..M},其中 N、M 表示数字,'abc'、'def' 表示字符串。 |
NOSIGN |
如果提供此关键字来代替认证凭据,则所有请求都不会被签名。 |
hmac_key and hmac_secret |
用于指定给定端点所使用认证凭据的键。可选。 |
format |
文件的格式。 |
structure |
表的结构。格式为 'column1_name column1_type, column2_name column2_type, ...'。 |
compression_method |
此参数可选。支持的值有:none、gzip 或 gz、brotli 或 br、xz 或 LZMA、zstd 或 zst。默认会根据文件扩展名自动检测压缩方法。 |
partition_strategy |
可选。支持的值有:wildcard 或 hive。wildcard 要求路径中包含 {_partition_id}。未显式指定策略时,包含 {_partition_id} 的路径使用 wildcard。包含其他 glob 的路径不使用分区策略,并忽略 PARTITION BY。不包含 glob 的路径在 file_like_engine_default_partition_strategy 为 hive 时使用 hive;否则不使用分区策略。 |
参数也可以通过命名集合传递。在这种情况下,url、format、structure、compression_method、partition_strategy 的用法相同,并且还支持一些额外参数:
| 参数 | 描述 |
|---|---|
access_key_id |
hmac_key,可选。 |
secret_access_key |
hmac_secret,可选。 |
filename |
如果指定,则会追加到 url。 |
use_environment_credentials |
默认启用,允许通过环境变量 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI、AWS_CONTAINER_CREDENTIALS_FULL_URI、AWS_CONTAINER_AUTHORIZATION_TOKEN、AWS_EC2_METADATA_DISABLED 传递额外参数。 |
no_sign_request |
默认禁用。 |
expiration_window_seconds |
默认值为 120。 |
返回值
一个具有指定结构的表,用于读取指定文件中的数据或向其中写入数据。
示例
从 GCS 文件 https://storage.googleapis.com/clickhouse_public_datasets/my-test-bucket-768/data.csv.gz 中选取前两行。压缩方法会根据 .gz 文件扩展名自动识别:
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 如下:
- 'https://storage.googleapis.com/my-test-bucket-768/some_prefix/some_file_1.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/some_prefix/some_file_2.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/some_prefix/some_file_3.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/some_prefix/some_file_4.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/another_prefix/some_file_1.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/another_prefix/some_file_2.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/another_prefix/some_file_3.csv'
- 'https://storage.googleapis.com/my-test-bucket-768/another_prefix/some_file_4.csv'
统计文件名以 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.csv、file-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 表达式,系统会为每个分区值分别创建一个文件。将数据拆分到不同文件中,有助于提升读取操作的效率。
包含 {_partition_id} 的路径意味着使用 wildcard 分区策略,因此以下示例中显式设置 partition_strategy='wildcard' 是可选的。包含其他 glob 的路径不使用分区策略,并会忽略 PARTITION BY。不含 glob 的路径在 file_like_engine_default_partition_strategy 为 hive 时使用 hive;否则不使用分区策略。
示例
- 在 key 中使用分区 ID 会创建单独的文件:
INSERT INTO TABLE FUNCTION
gcs('http://bucket.amazonaws.com/my_bucket/file_{_partition_id}.csv', 'CSV', 'a String, b UInt32, c UInt32', partition_strategy='wildcard')
PARTITION BY a VALUES ('x', 2, 3), ('x', 4, 5), ('y', 11, 12), ('y', 13, 14), ('z', 21, 22), ('z', 23, 24);因此,数据会写入三个文件:file_x.csv、file_y.csv 和 file_z.csv。
- 在 存储桶 名称中使用分区 ID,会在不同的 存储桶 中创建文件:
INSERT INTO TABLE FUNCTION
gcs('http://bucket.amazonaws.com/my_bucket_{_partition_id}/file.csv', 'CSV', 'a UInt32, b UInt32, c UInt32', partition_strategy='wildcard')
PARTITION BY a VALUES (1, 2, 3), (1, 4, 5), (10, 11, 12), (10, 13, 14), (20, 21, 22), (20, 23, 24);因此,数据会被写入不同存储桶中的三个文件:my_bucket_1/file.csv、my_bucket_10/file.csv 和 my_bucket_20/file.csv。