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

数据类型二进制编码规范

本规范描述了一种用于对 ClickHouse 数据类型进行二进制编码和解码的二进制格式。该格式用于 Dynamic 列的二进制序列化,并且在相应设置下可用于输入/输出格式 RowBinaryWithNamesAndTypesNative

下表描述了每种数据类型在二进制格式中的表示方式。每种数据类型的编码由 1 个字节的类型标识和一些可选的附加信息组成。 二进制编码中的 var_uint 表示大小使用可变长度整数(Variable-Length Quantity)压缩方式进行编码。

ClickHouse 数据类型二进制编码
Nothing0x00
UInt80x01
UInt160x02
UInt320x03
UInt640x04
UInt1280x05
UInt2560x06
Int80x07
Int160x08
Int320x09
Int640x0A
Int1280x0B
Int2560x0C
Float320x0D
Float640x0E
Date0x0F
Date320x10
DateTime0x11
DateTime(time_zone)0x12<var_uint_time_zone_name_size><time_zone_name_data>
DateTime64(P)0x13<uint8_precision>
DateTime64(P, time_zone)0x14<uint8_precision><var_uint_time_zone_name_size><time_zone_name_data>
String0x15
FixedString(N)0x16<var_uint_size>
Enum80x17<var_uint_number_of_elements><var_uint_name_size_1><name_data_1><int8_value_1>...<var_uint_name_size_N><name_data_N><int8_value_N>
Enum160x18<var_uint_number_of_elements><var_uint_name_size_1><name_data_1><int16_little_endian_value_1>...><var_uint_name_size_N><name_data_N><int16_little_endian_value_N>
Decimal32(P, S)0x19<uint8_precision><uint8_scale>
Decimal64(P, S)0x1A<uint8_precision><uint8_scale>
Decimal128(P, S)0x1B<uint8_precision><uint8_scale>
Decimal256(P, S)0x1C<uint8_precision><uint8_scale>
UUID0x1D
Array(T)0x1E<nested_type_encoding>
Tuple(T1, ..., TN)0x1F<var_uint_number_of_elements><nested_type_encoding_1>...<nested_type_encoding_N>
Tuple(name1 T1, ..., nameN TN)0x20<var_uint_number_of_elements><var_uint_name_size_1><name_data_1><nested_type_encoding_1>...<var_uint_name_size_N><name_data_N><nested_type_encoding_N>
Set0x21
间隔0x22<interval_kind>(参见 interval_kind 的二进制编码
Nullable(T)0x23<nested_type_encoding>
Function0x24<var_uint_number_of_arguments><argument_type_encoding_1>...<argument_type_encoding_N><return_type_encoding>
AggregateFunction(function_name(param_1, ..., param_N), arg_T1, ..., arg_TN)0x25<var_uint_version><var_uint_function_name_size><function_name_data><var_uint_number_of_parameters><param_1>...<param_N><var_uint_number_of_arguments><argument_type_encoding_1>...<argument_type_encoding_N>(参见 聚合函数参数的二进制编码
LowCardinality(T)0x26<nested_type_encoding>
Map(K, V)0x27<key_type_encoding><value_type_encoding>
IPv40x28
IPv60x29
Variant(T1, ..., TN)0x2A<var_uint_number_of_variants><variant_type_encoding_1>...<variant_type_encoding_N>
Dynamic(max_types=N)0x2B<uint8_max_types>
Custom typeRingPolygon 等)0x2C<var_uint_type_name_size><type_name_data>
Bool0x2D
SimpleAggregateFunction(function_name(param_1, ..., param_N), arg_T1, ..., arg_TN)0x2E<var_uint_function_name_size><function_name_data><var_uint_number_of_parameters><param_1>...<param_N><var_uint_number_of_arguments><argument_type_encoding_1>...<argument_type_encoding_N>(参见聚合函数参数二进制编码
Nested(name1 T1, ..., nameN TN)0x2F<var_uint_number_of_elements><var_uint_name_size_1><name_data_1><nested_type_encoding_1>...<var_uint_name_size_N><name_data_N><nested_type_encoding_N>
JSON(max_dynamic_paths=N, max_dynamic_types=M, path Type, SKIP skip_path, SKIP REGEXP skip_path_regexp)0x30<uint8_serialization_version><var_int_max_dynamic_paths><uint8_max_dynamic_types><var_uint_number_of_typed_paths><var_uint_path_name_size_1><path_name_data_1><encoded_type_1>...<var_uint_number_of_skip_paths><var_uint_skip_path_size_1><skip_path_data_1>...<var_uint_number_of_skip_path_regexps><var_uint_skip_path_regexp_size_1><skip_path_data_regexp_1>...
BFloat160x31
时间0x32
Time64(P)0x34<uint8_precision>
QBit(T, N)0x36<element_type_encoding><var_uint_dimension>

对于类型 JSON,字节 uint8_serialization_version 表示序列化版本。当前版本固定为 0,但如果将来为 JSON 类型引入新的参数,该值可能会发生变化。

Interval 间隔种类的二进制编码

下表说明了 Interval 数据类型中不同间隔种类的二进制编码方式。

间隔种类 (Interval kind)二进制编码 (Binary encoding)
Nanosecond0x00
Microsecond0x01
Millisecond0x02
Second0x03
Minute0x04
Hour0x05
Day0x06
Week0x07
Month0x08
Quarter0x09
Year0x1A

聚合函数参数的二进制编码

下表描述了 AggregateFunctionSimpleAggregateFunction 的参数是如何进行编码的。 每个参数的编码由 1 个用于指示参数类型的字节和参数值本身组成。

参数类型二进制编码
Null0x00
UInt640x01<var_uint_value>
Int640x02<var_int_value>
UInt1280x03<uint128_little_endian_value>
Int1280x04<int128_little_endian_value>
UInt2560x05<uint256_little_endian_value>
Int2560x06<int256_little_endian_value>
Float640x07<float64_little_endian_value>
Decimal320x08<var_uint_scale><int32_little_endian_value>
Decimal640x09<var_uint_scale><int64_little_endian_value>
Decimal1280x0A<var_uint_scale><int128_little_endian_value>
Decimal2560x0B<var_uint_scale><int256_little_endian_value>
String0x0C<var_uint_size><data>
Array0x0D<var_uint_size><value_encoding_1>...<value_encoding_N>
Tuple0x0E<var_uint_size><value_encoding_1>...<value_encoding_N>
Map0x0F<var_uint_size><key_encoding_1><value_encoding_1>...<key_encoding_N><value_encoding_N>
IPv40x10<uint32_little_endian_value>
IPv60x11<uint128_little_endian_value>
UUID0x12<uuid_value>
Bool0x13<bool_value>
Object0x14<var_uint_size><var_uint_key_size_1><key_data_1><value_encoding_1>...<var_uint_key_size_N><key_data_N><value_encoding_N>
AggregateFunctionState0x15<var_uint_name_size><name_data><var_uint_data_size><data>
Negative infinity0xFE
Positive infinity0xFF