gcs 表函数
提供一个类似表的接口,用于从 Google Cloud Storage 中 SELECT
和 INSERT
数据。需要 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 XML API 和 HMAC 密钥与 Google Cloud Storage 集成。有关端点和 HMAC 的更多详细信息,请参阅 Google 互操作性文档。
参数
url
— 文件的 Bucket 路径。在只读模式下支持以下通配符:*
、**
、?
、{abc,def}
和{N..M}
,其中N
、M
— 数字,'abc'
、'def'
— 字符串。GCSGCS 路径采用此格式,因为 Google XML API 的端点与 JSON API 不同
https://storage.googleapis.com/<bucket>/<folder>/<filename(s)>
NOSIGN
— 如果提供此关键字代替凭据,则所有请求将不会被签名。hmac_key
和hmac_secret
— 用于指定与给定端点一起使用的凭据的密钥。可选。format
— 文件的 格式。structure
— 表的结构。格式'column1_name column1_type, column2_name column2_type, ...'
。compression_method
— 参数是可选的。支持的值:none
、gzip
或gz
、brotli
或br
、xz
或LZMA
、zstd
或zst
。默认情况下,它将通过文件扩展名自动检测压缩方法。
参数也可以使用 命名集合 传递。在这种情况下,url
、format
、structure
、compression_method
的工作方式相同,并且支持一些额外的参数
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/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 的文件
- '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 表达式,则会为每个分区值创建一个单独的文件。将数据拆分为单独的文件有助于提高读取操作效率。
示例
- 在键中使用分区 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.csv、file_y.csv 和 file_z.csv。
- 在 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.csv、my_bucket_10/file.csv 和 my_bucket_20/file.csv。
另请参阅