> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 在 ClickHouse 中使用 Parquet

> 介绍如何在 ClickHouse 中使用 Parquet 的页面

Parquet 是一种高效的文件格式，可按列式方式存储数据。
ClickHouse 支持读取和写入 Parquet 文件。

<Tip>
  当你在查询中引用文件路径时，ClickHouse 实际尝试读取的位置取决于你使用的是哪种 ClickHouse 版本。

  如果你使用的是 [`clickhouse-local`](/docs/zh/concepts/features/tools-and-utilities/clickhouse-local)，它会从相对于你启动 ClickHouse Local 时所在位置的路径读取。
  如果你通过 `clickhouse client` 使用 ClickHouse Server 或 ClickHouse Cloud，它会从服务器上的 `/var/lib/clickhouse/user_files/` 目录下的相对路径读取。
</Tip>

<div id="importing-from-parquet">
  ## 从 Parquet 导入
</div>

在加载数据之前，我们可以使用 [file()](/docs/zh/reference/functions/regular-functions/files#file) 函数查看[示例 Parquet 文件](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/data.parquet)的结构：

```sql theme={null}
DESCRIBE TABLE file('data.parquet', Parquet);
```

我们将 [Parquet](/docs/zh/reference/formats/Parquet/Parquet) 用作第二个参数，这样 ClickHouse 就能识别文件格式。这将输出带类型的列：

```response theme={null}
┌─name─┬─type─────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ Nullable(String) │              │                    │         │                  │                │
│ date │ Nullable(String) │              │                    │         │                  │                │
│ hits │ Nullable(Int64)  │              │                    │         │                  │                │
└──────┴──────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
```

我们还可以在真正导入数据之前，借助 SQL 的强大能力先分析文件：

```sql theme={null}
SELECT *
FROM file('data.parquet', Parquet)
LIMIT 3;
```

```response theme={null}
┌─path──────────────────────┬─date───────┬─hits─┐
│ Akiba_Hebrew_Academy      │ 2017-08-01 │  241 │
│ Aegithina_tiphia          │ 2018-02-01 │   34 │
│ 1971-72_Utah_Stars_season │ 2016-10-01 │    1 │
└───────────────────────────┴────────────┴──────┘
```

<Tip>
  我们可以省略对 `file()` 和 `INFILE`/`OUTFILE` 的显式格式设置。
  在这种情况下，ClickHouse 会根据文件扩展名自动识别格式。
</Tip>

<div id="importing-to-an-existing-table">
  ## 导入到现有表
</div>

先创建一个用于导入 Parquet 数据的表：

```sql theme={null}
CREATE TABLE sometable
(
    `path` String,
    `date` Date,
    `hits` UInt32
)
ENGINE = MergeTree
ORDER BY (date, path);
```

现在可以使用 `FROM INFILE` 子句导入数据：

```sql theme={null}
INSERT INTO sometable
FROM INFILE 'data.parquet' FORMAT Parquet;

SELECT *
FROM sometable
LIMIT 5;
```

```response theme={null}
┌─path──────────────────────────┬───────date─┬─hits─┐
│ 1988_in_philosophy            │ 2015-05-01 │   70 │
│ 2004_Green_Bay_Packers_season │ 2015-05-01 │  970 │
│ 24_hours_of_lemans            │ 2015-05-01 │   37 │
│ 25604_Karlin                  │ 2015-05-01 │   20 │
│ ASCII_ART                     │ 2015-05-01 │    9 │
└───────────────────────────────┴────────────┴──────┘
```

请注意，ClickHouse 会自动将 Parquet 字符串 (`date` 列中的字符串) 转换为 `Date` 类型。这是因为 ClickHouse 会根据目标表中的类型自动进行类型转换。

<div id="inserting-a-local-file-to-remote-server">
  ## 将本地文件插入远程服务器
</div>

如果你想将本地 Parquet 文件插入远程 ClickHouse 服务器，可以像下面这样通过管道将文件内容传给 `clickhouse-client`：

```sql theme={null}
clickhouse client -q "INSERT INTO sometable FORMAT Parquet" < data.parquet
```

<div id="creating-new-tables-from-parquet-files">
  ## 从 Parquet 文件创建新表
</div>

由于 ClickHouse 会读取 Parquet 文件的 schema，因此我们可以动态创建表：

```sql theme={null}
CREATE TABLE imported_from_parquet
ENGINE = MergeTree
ORDER BY tuple() AS
SELECT *
FROM file('data.parquet', Parquet)
```

这会根据给定的 Parquet 文件自动创建并填充一张表：

```sql theme={null}
DESCRIBE TABLE imported_from_parquet;
```

```response theme={null}
┌─name─┬─type─────────────┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┬─ttl_expression─┐
│ path │ Nullable(String) │              │                    │         │                  │                │
│ date │ Nullable(String) │              │                    │         │                  │                │
│ hits │ Nullable(Int64)  │              │                    │         │                  │                │
└──────┴──────────────────┴──────────────┴────────────────────┴─────────┴──────────────────┴────────────────┘
```

默认情况下，ClickHouse 会严格校验列名、类型和值。但有时，我们可以在导入时跳过不存在的列或不受支持的值。这可以通过 [Parquet 设置](/docs/zh/reference/formats/Parquet/Parquet#format-settings) 来控制。

<div id="exporting-to-parquet-format">
  ## 导出为 Parquet 格式
</div>

<Tip>
  在 ClickHouse Cloud 中使用 `INTO OUTFILE` 时，需要在文件将要写入的那台机器上，通过 `clickhouse client` 运行这些命令。
</Tip>

要将任意表或查询结果导出为 Parquet 文件，可以使用 `INTO OUTFILE` 子句：

```sql theme={null}
SELECT *
FROM sometable
INTO OUTFILE 'export.parquet'
FORMAT Parquet
```

这会在当前工作目录中创建 `export.parquet` 文件。

<div id="clickhouse-and-parquet-data-types">
  ## ClickHouse 和 Parquet 数据类型
</div>

ClickHouse 和 Parquet 的数据类型大多相同，但仍[略有差异](/docs/zh/reference/formats/Parquet/Parquet#data-types-matching-parquet)。例如，ClickHouse 会将 `DateTime` 类型导出为 Parquet 的 `int64`。如果再将其导入回 ClickHouse，我们看到的将是数字 ([time.parquet file](https://clickhouse-docs-assets.s3.us-east-1.amazonaws.com/time.parquet))：

```sql theme={null}
SELECT * FROM file('time.parquet', Parquet);
```

```response theme={null}
┌─n─┬───────time─┐
│ 0 │ 1673622611 │
│ 1 │ 1673622610 │
│ 2 │ 1673622609 │
│ 3 │ 1673622608 │
│ 4 │ 1673622607 │
└───┴────────────┘
```

此时可使用[类型转换](/docs/zh/reference/functions/regular-functions/type-conversion-functions)：

```sql theme={null}
SELECT
    n,
    toDateTime(time)                 <--- int to time
FROM file('time.parquet', Parquet);
```

```response theme={null}
┌─n─┬────toDateTime(time)─┐
│ 0 │ 2023-01-13 15:10:11 │
│ 1 │ 2023-01-13 15:10:10 │
│ 2 │ 2023-01-13 15:10:09 │
│ 3 │ 2023-01-13 15:10:08 │
│ 4 │ 2023-01-13 15:10:07 │
└───┴─────────────────────┘
```

<div id="further-reading">
  ## 延伸阅读
</div>

ClickHouse 支持多种格式，包括文本格式和二进制格式，以适应各种场景和平台。你可以在以下文章中进一步了解更多格式及其使用方式：

* [CSV 和 TSV 格式](/docs/zh/guides/clickhouse/data-formats/csv-tsv)
* [Avro、Arrow 和 ORC](/docs/zh/guides/clickhouse/data-formats/arrow-avro-orc)
* [JSON 格式](/docs/zh/guides/clickhouse/data-formats/json/intro)
* [Regex 和 Template](/docs/zh/guides/clickhouse/data-formats/templates-regex)
* [Native 和二进制格式](/docs/zh/guides/clickhouse/data-formats/binary)
* [SQL 格式](/docs/zh/guides/clickhouse/data-formats/sql)

另外，也可以查看 [clickhouse-local](https://clickhouse.com/blog/extracting-converting-querying-local-files-with-sql-clickhouse-local)——这是一个便携且功能完整的工具，可用于处理本地/远程文件，无需 ClickHouse server。
