使用 JSON 类格式输出 ClickHouse 大类型数字(比如 Int64 甚至更大的 Int128)时,会发现输出的数字变成字符串:
代码语言:javascript复制CREATE TABLE test (id Int64) ENGINE=Memory;
INSERT INTO test VALUES (1234567890);
SELECT * FROM test FORMAT JSONEachRow;
结果如下:
代码语言:javascript复制{"id":"1234567890"}
这是因为 ClickHouse 为了使 JSON 格式兼容 JavaScript,将数字类型全部用 double 存储。double 表达范围比 Int64 小,因此超出 double 表达范围的数字无法表达,为了解决这个问题有三种方法 [1]:
- 统一使用字符串表达大数字
- 丢弃无法表达的大数字
- 可以表达的用 double,不可以的用字符串
为了简单起见,ClickHouse 采用第一种。第二种会导致表达能力受限;第三种会导致未定义行为。
经过 issue 要求,ClickHouse 实现一个配置开关以控制是否采用第二种方式。[2]
在 user.xml
中每个用户配置项里配置 [3]:
<output_format_json_quote_64bit_integers>0</output_format_json_quote_64bit_integers>
即可。
- https://github.com/ClickHouse/ClickHouse/issues/114#issuecomment-248190752 ↩︎
- https://github.com/ClickHouse/ClickHouse/pull/126 ↩︎
- https://clickhouse.com/docs/en/operations/settings/formats#output_format_json_quote_64bit_integers ↩︎