从输入数据自动推断模式
ClickHouse可以自动确定输入数据的结构,几乎支持所有输入格式。 本文将描述何时使用模式推断,它如何与不同的输入格式协作,以及哪些设置可以控制它。
使用方法
当ClickHouse需要以特定数据格式读取数据且结构未知时,会使用模式推断。
表函数 file, s3, url, hdfs, azureBlobStorage.
这些表函数具有可选参数structure
,用于指定输入数据的结构。如果未指定该参数或将其设置为auto
,则结构将从数据中推断。
示例:
假设我们在user_files
目录中有一个名为hobbies.jsonl
的文件,格式为JSONEachRow,内容如下:
ClickHouse可以在不指定其结构的情况下读取这些数据:
注意:格式JSONEachRow
是通过文件扩展名.jsonl
自动确定的。
可以使用DESCRIBE
查询查看自动确定的结构:
表引擎 File, S3, URL, HDFS, azureBlobStorage
如果在CREATE TABLE
查询中未指定列列表,表的结构将从数据中自动推断。
示例:
我们使用文件hobbies.jsonl
。可以使用引擎File
创建一个包含此文件数据的表:
clickhouse-local
clickhouse-local
具有可选参数-S/--structure
,用于指定输入数据的结构。如果未指定该参数或将其设置为auto
,则结构将从数据中推断。
示例:
我们使用文件hobbies.jsonl
。可以通过clickhouse-local
查询此文件中的数据:
从插入表中使用结构
当使用表函数file/s3/url/hdfs
将数据插入表中时,可以选择从插入表中使用结构,而不是从数据中提取它。
这可以提高插入性能,因为模式推断可能需要一些时间。此外,当表具有优化过的模式时,这也将很有用,因此不会在类型之间执行转换。
有一个特殊设置 use_structure_from_insertion_table_in_table_functions 控制此行为。它有3个可能的值:
- 0 - 表函数将从数据中提取结构。
- 1 - 表函数将使用插入表中的结构。
- 2 - ClickHouse将自动确定是否可以使用插入表中的结构或使用模式推断。默认值。
示例 1:
让我们创建一个名为hobbies1
的表,具有以下结构:
并从文件hobbies.jsonl
中插入数据:
在这种情况下,文件中的所有列都未更改地插入到表中,因此ClickHouse将使用插入表中的结构,而不是模式推断。
示例 2:
让我们创建一个名为hobbies2
的表,具有以下结构:
并从文件hobbies.jsonl
中插入数据:
在这种情况下,SELECT
查询中的所有列都在表中,因此ClickHouse将使用插入表中的结构。
注意,它仅适用于支持读取列子集的输入格式,如JSONEachRow、TSKV、Parquet等(因此对于TSV格式就不起作用)。
示例 3:
让我们创建一个名为hobbies3
的表,具有以下结构:
并从文件hobbies.jsonl
中插入数据:
在这种情况下,SELECT
查询中使用的列id
在表中不存在(表中有名为identifier
的列),因此ClickHouse无法使用插入表中的结构,而将使用模式推断。
示例 4:
让我们创建一个名为hobbies4
的表,具有以下结构:
并从文件hobbies.jsonl
中插入数据:
在这种情况下,SELECT
查询中对列hobbies
执行了一些操作,因此ClickHouse无法使用插入表的结构,而将使用模式推断。
模式推断缓存
对于大多数输入格式,模式推断会读取一些数据以确定其结构,此过程可能会花费一些时间。 为防止ClickHouse每次从同一文件读取数据时都推断相同的模式,推断出的模式会被缓存,当再次访问同一文件时,ClickHouse将使用缓存中的模式。
有一些特殊设置控制该缓存:
schema_inference_cache_max_elements_for_{file/s3/hdfs/url/azure}
- 对应于表函数的最大缓存模式数。默认值为4096
。这些设置应在服务器配置中设置。schema_inference_use_cache_for_{file,s3,hdfs,url,azure}
- 允许启用/禁用模式推断的缓存使用。这些设置可以在查询中使用。
文件的模式可以通过修改数据或更改格式设置来更改。 因此,模式推断缓存通过文件源、格式名称、使用的格式设置以及文件的最后修改时间来标识模式。
注意:一些通过URL访问的文件在url
表函数中可能不包含有关最后修改时间的信息;对于这种情况,有一个特殊设置schema_inference_cache_require_modification_time_for_url
。禁用此设置允许对这些文件使用缓存中的模式,而不考虑最后的修改时间。
还有一个系统表 schema_inference_cache 包含缓存中的所有当前模式,系统查询SYSTEM DROP SCHEMA CACHE [FOR File/S3/URL/HDFS]
允许清除所有源的模式缓存或特定源的模式缓存。
示例:
让我们尝试从s3推断样本数据集github-2022.ndjson.gz
的结构,并查看模式推断缓存的工作原理:
如您所见,第二个查询几乎立即成功。
让我们尝试更改一些可能影响推断模式的设置:
如您所见,因为更改了可能影响推断模式的设置,因此没有使用缓存中的模式。
让我们检查一下system.schema_inference_cache
表的内容:
可以看出,同一文件有两种不同的模式。
我们可以使用系统查询清除模式缓存:
文本格式
对于文本格式,ClickHouse逐行读取数据,根据格式提取列值,然后使用一些递归解析器和启发式方法来确定每个值的类型。 在模式推断中,从数据中读取的最大行数和字节数由设置input_format_max_rows_to_read_for_schema_inference
(默认为25000)和input_format_max_bytes_to_read_for_schema_inference
(默认为32Mb)控制。
默认情况下,所有推断类型都是Nullable,但可以通过设置schema_inference_make_columns_nullable
来更改(请参阅设置部分中的示例)。
JSON格式
在JSON格式中,ClickHouse根据JSON规范解析值,然后尝试为它们找到最合适的数据类型。
让我们看看它是如何工作的,可以推断出什么类型,以及在JSON格式中可以使用哪些具体设置。
示例
在这里以及后续部分,示例将使用format表函数。
整数、浮点数、布尔值、字符串:
日期、日期时间:
数组:
如果数组包含null
,ClickHouse将使用其他数组元素的类型:
具名元组:
启用设置input_format_json_try_infer_named_tuples_from_objects
时,在模式推断期间ClickHouse将尝试从JSON对象推断具名元组。
生成的具名元组将包含来自样本数据的所有对应JSON对象中的所有元素。
无名元组:
在JSON格式中,我们将元素类型不同的数组视为无名元组。
如果某些值为null
或为空,则使用其他行对应值的类型:
映射:
在JSON中,我们可以读取具有相同类型值的对象作为Map类型。
注意:这只有在设置input_format_json_read_objects_as_strings
和input_format_json_try_infer_named_tuples_from_objects
被禁用时才有效。
JSON对象类型(如果启用设置allow_experimental_object_type
):
嵌套复杂类型:
如果ClickHouse无法确定某些键的类型,因为数据仅包含null/空对象/空数组,将使用类型String
(如果启用设置input_format_json_infer_incomplete_types_as_strings
)或抛出异常(否则):
JSON设置
input_format_json_try_infer_numbers_from_strings
启用此设置允许从字符串值中推断出数字。
该设置默认禁用。
示例:
input_format_json_try_infer_named_tuples_from_objects
启用此设置允许从JSON对象中推断具名元组。
生成的具名元组将包含所有来自样本数据的对应JSON对象中的所有元素。
当JSON数据不稀疏时,这很有用,因为数据样本将包含所有可能的对象键。
此设置默认启用。
示例:
结果:
结果:
input_format_json_use_string_type_for_ambiguous_paths_in_named_tuples_inference_from_objects
启用此设置允许在从 JSON 对象推断命名元组时,对模糊路径使用 String 类型(当 input_format_json_try_infer_named_tuples_from_objects
被启用时),而不是抛出异常。
它允许读取 JSON 对象作为命名元组,即使存在模糊路径。
默认情况下禁用。
示例
禁用设置时:
结果:
启用设置时:
结果:
input_format_json_read_objects_as_strings
启用此设置允许将嵌套的 JSON 对象作为字符串读取。 此设置可以用来在不使用 JSON 对象类型的情况下读取嵌套的 JSON 对象。
该设置默认启用。
注意:启用此设置仅在 input_format_json_try_infer_named_tuples_from_objects
设置被禁用时才会生效。
input_format_json_read_numbers_as_strings
启用此设置允许将数值作为字符串读取。
该设置默认启用。
示例
input_format_json_read_bools_as_numbers
启用此设置允许将 Bool 值作为数字读取。
该设置默认启用。
示例:
input_format_json_read_bools_as_strings
启用此设置允许将 Bool 值作为字符串读取。
该设置默认启用。
示例:
input_format_json_read_arrays_as_strings
启用此设置允许将 JSON 数组值作为字符串读取。
该设置默认启用。
示例
input_format_json_infer_incomplete_types_as_strings
启用此设置允许在模式推断过程中,使用 String 类型处理数据样本中仅包含 Null
/{}
/[]
的 JSON 键。
在 JSON 格式中,如果启用所有相关设置(它们默认都是启用的),可以将任何值读取为 String,从而避免错误,如 无法通过前 25000 行数据确定列 'column_name' 的类型,可能是该列只包含 Null 或空数组/映射
,并且可以通过对未知类型的键使用 String 类型来避免这些错误。
示例:
结果:
CSV
在 CSV 格式下,ClickHouse 根据定界符从行中提取列值。ClickHouse 期望所有类型(除了数字和字符串)都用双引号括起来。 如果值用双引号括起来,ClickHouse 尝试使用递归解析器解析引号内的数据,然后尝试为其找到最合适的数据类型。如果值不是用双引号括起来,ClickHouse 尝试将其解析为数字,若值不是数字,ClickHouse 将其视作字符串。
如果您不希望 ClickHouse 尝试使用某些解析器和启发式方法来确定复杂类型,您可以禁用设置 input_format_csv_use_best_effort_in_schema_inference
,并且 ClickHouse 会将所有列视为字符串。
如果设置 input_format_csv_detect_header
被启用,ClickHouse 会在推断模式时尝试检测列名(可能还有类型)的头。该设置默认启用。
示例:
整数,浮点数,布尔值,字符串:
没有引号的字符串:
日期,日期时间:
数组:
如果数组包含 null,ClickHouse 将使用其他数组元素的类型:
映射:
嵌套数组和映射:
如果 ClickHouse 无法确定引号内的类型,因为数据仅包含 null,ClickHouse 将其视为字符串:
禁用设置 input_format_csv_use_best_effort_in_schema_inference
的示例:
自动检测头的示例(当 input_format_csv_detect_header
被启用时):
仅名称:
名称和类型:
注意,头部只能在至少有一列具有非字符串类型时才能被检测。如果所有列都是字符串类型,则不会检测到头部:
CSV 设置
input_format_csv_try_infer_numbers_from_strings
启用此设置允许从字符串值推断出数字。
该设置默认禁用。
示例:
TSV/TSKV
在 TSV/TSKV 格式下,ClickHouse 根据制表符分隔的定界符从行中提取列值,然后使用递归解析器解析提取值以确定最适合的类型。如果类型无法确定,ClickHouse 将此值视为字符串。
如果您不希望 ClickHouse 尝试使用某些解析器和启发式方法来确定复杂类型,您可以禁用设置 input_format_tsv_use_best_effort_in_schema_inference
,ClickHouse 将把所有列视为字符串。
如果设置 input_format_tsv_detect_header
被启用,ClickHouse 会在推断模式时尝试检测列名(可能还有类型)的头。该设置默认启用。
示例:
整数,浮点数,布尔值,字符串:
日期,日期时间:
数组:
如果数组包含 null,ClickHouse 将使用其他数组元素的类型:
元组:
映射:
嵌套数组、元组和映射:
如果 ClickHouse 无法确定类型,因为数据仅包含 null,ClickHouse 将其视为字符串:
禁用设置 input_format_tsv_use_best_effort_in_schema_inference
的示例:
自动检测头的示例(当 input_format_tsv_detect_header
被启用时):
仅名称:
名称和类型:
注意,头部只能在至少有一列具有非字符串类型时才能被检测。如果所有列都是字符串类型,则不会检测到头部:
Values
在 Values 格式中,ClickHouse 从行中提取列值,然后使用递归解析器解析它,类似于文字的解析方式。
示例:
整数,浮点数,布尔值,字符串:
日期,日期时间:
数组:
如果数组包含 null,ClickHouse 将使用其他数组元素的类型:
元组:
映射:
嵌套数组,元组和映射:
如果 ClickHouse 无法确定类型,因为数据仅包含 null,将引发异常:
示例,禁用设置 input_format_tsv_use_best_effort_in_schema_inference
:
CustomSeparated
在 CustomSeparated 格式中,ClickHouse 首先根据指定的分隔符提取所有列值,然后尝试根据转义规则推断每个值的数据类型。
如果设置 input_format_custom_detect_header
被启用,ClickHouse 会尝试在推断模式中检测列名(也许还有类型)为标准。这项设置默认开启。
示例
自动检测标头的示例(当 input_format_custom_detect_header
被启用时):
Template
在 Template 格式中,ClickHouse 首先根据指定模板提取所有列值,然后尝试根据其转义规则推断每个值的数据类型。
示例
假设我们有一个文件 resultset
,内容如下:
以及一个文件 row_format
,内容如下:
然后我们可以执行以下查询:
Regexp
与 Template 类似,在 Regexp 格式中,ClickHouse 首先根据指定的正则表达式从行中提取所有列值,然后尝试根据指定的转义规则推断每个值的数据类型。
示例
Settings for text formats
input_format_max_rows_to_read_for_schema_inference/input_format_max_bytes_to_read_for_schema_inference
这些设置控制在模式推断过程中要读取的数据量。 读取的行/字节越多,花费在模式推断上的时间越长,但正确确定类型的机会更大(尤其是当数据包含大量 null 时)。
默认值:
25000
用于input_format_max_rows_to_read_for_schema_inference
。33554432
(32 Mb) 用于input_format_max_bytes_to_read_for_schema_inference
。
column_names_for_schema_inference
用于没有显式列名的格式的模式推断的列名列表。指定的名称将替代默认的 c1,c2,c3,...
。格式:column1,column2,column3,...
。
示例
schema_inference_hints
列名和类型的列表,用于模式推断,而不是自动确定的类型。格式:'column_name1 column_type1, column_name2 column_type2, ...'。 此设置可用于指定无法自动确定类型的列的类型,或优化模式。
示例
schema_inference_make_columns_nullable
控制在模式推断过程中使推断类型为 Nullable
的操作。
如果启用,则所有推断类型将为 Nullable
,如果禁用,则推断类型将永远不会是 Nullable
,如果设置为 auto
,则只有当在解析过程中样本中包含 NULL
或文件元数据包含有关列 nullability 的信息时,推断类型才会为 Nullable
。
默认情况下启用。
示例
input_format_try_infer_integers
如果启用,ClickHouse 将尝试在文本格式的模式推断中推断整数而不是浮点数。
如果列中的所有数字都是整数,则结果类型为 Int64
,如果至少有一个数字是浮点数,则结果类型为 Float64
。
如果样本数据中仅包含整数,并且至少有一个整数是正数并且超过 Int64
,则 ClickHouse 会推断为 UInt64
。
默认情况下启用。
示例
input_format_try_infer_datetimes
如果启用,ClickHouse 将尝试从文本格式的字符串字段中推断类型 DateTime
或 DateTime64
。
如果来自样本数据的列中的所有字段都成功解析为日期时间,则结果类型为 DateTime
或 DateTime64(9)
(如果任何日期时间具有小数部分),
如果至少有一个字段未解析为日期时间,则结果类型为 String
。
默认情况下启用。
示例
input_format_try_infer_dates
如果启用,ClickHouse 将尝试从文本格式的字符串字段中推断类型 Date
。
如果来自样本数据的列中的所有字段都成功解析为日期,则结果类型为 Date
。
如果至少有一个字段未解析为日期,则结果类型为 String
。
默认情况下启用。
示例
input_format_try_infer_exponent_floats
如果启用,ClickHouse 将尝试在文本格式中推断指数形式的浮点数(除了 JSON,JSON 中指数形式的数字总是被推断为浮点数)。
默认情况下禁用。
示例
Self describing formats
自描述格式在数据中包含有关数据结构的信息, 它可以是一些带有描述的标题,二进制类型树或某种表。 要从此类格式的文件中自动推断模式,ClickHouse 会读取包含有关类型的信息的数据部分并将其转换为 ClickHouse 表的模式。
Formats with -WithNamesAndTypes suffix
ClickHouse 支持一些带有 -WithNamesAndTypes 后缀的文本格式。此后缀意味着数据在实际数据之前包含两行附加的列名和类型。 在处理这些格式的模式推断时,ClickHouse 读取前两行并提取列名和类型。
示例
带有元数据的 JSON 格式
某些 JSON 输入格式 (JSON, JSONCompact, JSONColumnsWithMetadata) 包含带有列名和类型的元数据。在这些格式的模式推断中,ClickHouse 会读取这些元数据。
示例
Avro
在 Avro 格式中,ClickHouse 从数据中读取其模式,并使用以下类型匹配将其转换为 ClickHouse 模式:
Avro 数据类型 | ClickHouse 数据类型 |
---|---|
boolean | Bool |
int | Int32 |
int (date) * | Date32 |
long | Int64 |
float | Float32 |
double | Float64 |
bytes , string | String |
fixed | FixedString(N) |
enum | Enum |
array(T) | Array(T) |
union(null, T) , union(T, null) | Nullable(T) |
null | Nullable(Nothing) |
string (uuid) * | UUID |
binary (decimal) * | Decimal(P, S) |
其他 Avro 类型不受支持。
Parquet
在 Parquet 格式中,ClickHouse 从数据中读取其模式,并使用以下类型匹配将其转换为 ClickHouse 模式:
Parquet 数据类型 | ClickHouse 数据类型 |
---|---|
BOOL | Bool |
UINT8 | UInt8 |
INT8 | Int8 |
UINT16 | UInt16 |
INT16 | Int16 |
UINT32 | UInt32 |
INT32 | Int32 |
UINT64 | UInt64 |
INT64 | Int64 |
FLOAT | Float32 |
DOUBLE | Float64 |
DATE | Date32 |
TIME (ms) | DateTime |
TIMESTAMP , TIME (us, ns) | DateTime64 |
STRING , BINARY | String |
DECIMAL | Decimal |
LIST | Array |
STRUCT | Tuple |
MAP | Map |
其他 Parquet 类型不受支持。默认情况下,所有推断的类型都在 Nullable
里面,但可以通过设置 schema_inference_make_columns_nullable
更改。
Arrow
在 Arrow 格式中,ClickHouse 从数据中读取其模式,并使用以下类型匹配将其转换为 ClickHouse 模式:
Arrow 数据类型 | ClickHouse 数据类型 |
---|---|
BOOL | Bool |
UINT8 | UInt8 |
INT8 | Int8 |
UINT16 | UInt16 |
INT16 | Int16 |
UINT32 | UInt32 |
INT32 | Int32 |
UINT64 | UInt64 |
INT64 | Int64 |
FLOAT , HALF_FLOAT | Float32 |
DOUBLE | Float64 |
DATE32 | Date32 |
DATE64 | DateTime |
TIMESTAMP , TIME32 , TIME64 | DateTime64 |
STRING , BINARY | String |
DECIMAL128 , DECIMAL256 | Decimal |
LIST | Array |
STRUCT | Tuple |
MAP | Map |
其他 Arrow 类型不受支持。默认情况下,所有推断的类型都在 Nullable
里面,但可以通过设置 schema_inference_make_columns_nullable
更改。
ORC
在 ORC 格式中,ClickHouse 从数据中读取其模式,并使用以下类型匹配将其转换为 ClickHouse 模式:
ORC 数据类型 | ClickHouse 数据类型 |
---|---|
Boolean | Bool |
Tinyint | Int8 |
Smallint | Int16 |
Int | Int32 |
Bigint | Int64 |
Float | Float32 |
Double | Float64 |
Date | Date32 |
Timestamp | DateTime64 |
String , Char , Varchar ,BINARY | String |
Decimal | Decimal |
List | Array |
Struct | Tuple |
Map | Map |
其他 ORC 类型不受支持。默认情况下,所有推断的类型都在 Nullable
里面,但可以通过设置 schema_inference_make_columns_nullable
更改。
Native
Native 格式在 ClickHouse 内部使用,并包含数据中的模式。在模式推断中,ClickHouse 从数据中读取模式而不进行任何转换。
具有外部模式的格式
这类格式需要一个描述数据的单独文件中的模式,以特定的模式语言。为了自动从此类格式的文件中推断出模式,ClickHouse 从单独的文件中读取外部模式,并将其转换为 ClickHouse 表模式。
Protobuf
在 Protobuf 格式的模式推断中,ClickHouse 使用以下类型匹配:
Protobuf 数据类型 | ClickHouse 数据类型 |
---|---|
bool | UInt8 |
float | Float32 |
double | Float64 |
int32 , sint32 , sfixed32 | Int32 |
int64 , sint64 , sfixed64 | Int64 |
uint32 , fixed32 | UInt32 |
uint64 , fixed64 | UInt64 |
string , bytes | String |
enum | Enum |
repeated T | Array(T) |
message , group | Tuple |
CapnProto
在 CapnProto 格式的模式推断中,ClickHouse 使用以下类型匹配:
CapnProto 数据类型 | ClickHouse 数据类型 |
---|---|
Bool | UInt8 |
Int8 | Int8 |
UInt8 | UInt8 |
Int16 | Int16 |
UInt16 | UInt16 |
Int32 | Int32 |
UInt32 | UInt32 |
Int64 | Int64 |
UInt64 | UInt64 |
Float32 | Float32 |
Float64 | Float64 |
Text , Data | String |
enum | Enum |
List | Array |
struct | Tuple |
union(T, Void) , union(Void, T) | Nullable(T) |
强类型二进制格式
在此类格式中,每个序列化值包含有关其类型(并可能包含有关其名称)的信息,但没有关于整个表的信息。在此类格式的模式推断中,ClickHouse 按行读取数据(最多 input_format_max_rows_to_read_for_schema_inference
行或 input_format_max_bytes_to_read_for_schema_inference
字节),并从数据中提取每个值的类型(并可能是名称),然后将这些类型转换为 ClickHouse 类型。
MsgPack
在 MsgPack 格式中,行之间没有分隔符,要使用此格式进行模式推断,您需使用设置 input_format_msgpack_number_of_columns
指定表中的列数。ClickHouse 使用以下类型匹配:
MessagePack 数据类型 (INSERT ) | ClickHouse 数据类型 |
---|---|
int N , uint N , negative fixint , positive fixint | Int64 |
bool | UInt8 |
fixstr , str 8 , str 16 , str 32 , bin 8 , bin 16 , bin 32 | String |
float 32 | Float32 |
float 64 | Float64 |
uint 16 | Date |
uint 32 | DateTime |
uint 64 | DateTime64 |
fixarray , array 16 , array 32 | Array |
fixmap , map 16 , map 32 | Map |
默认情况下,所有推断的类型都在 Nullable
里面,但可以通过设置 schema_inference_make_columns_nullable
更改。
BSONEachRow
在 BSONEachRow 中,每行数据表示为一个 BSON 文档。在模式推断中,ClickHouse 逐个读取 BSON 文档并提取值、名称和类型,然后使用以下类型匹配将这些类型转换为 ClickHouse 类型:
BSON 类型 | ClickHouse 类型 |
---|---|
\x08 boolean | Bool |
\x10 int32 | Int32 |
\x12 int64 | Int64 |
\x01 double | Float64 |
\x09 datetime | DateTime64 |
\x05 binary with\x00 binary subtype, \x02 string, \x0E symbol, \x0D JavaScript code | String |
\x07 ObjectId, | FixedString(12) |
\x05 binary with \x04 uuid subtype, size = 16 | UUID |
\x04 array | Array/Tuple (如果嵌套类型不同) |
\x03 document | Named Tuple/Map (带字符串键) |
默认情况下,所有推断的类型都在 Nullable
里面,但可以通过设置 schema_inference_make_columns_nullable
更改。
具有固定模式的格式
此类格式中的数据始终具有相同的模式。
LineAsString
在此格式中,ClickHouse 将整行从数据中读取到一个 String
数据类型的单列中。此格式的推断类型始终是 String
,列名为 line
。
示例
JSONAsString
在此格式中,ClickHouse 将整个 JSON 对象从数据中读取到一个 String
数据类型的单列中。此格式的推断类型始终是 String
,列名为 json
。
示例
JSONAsObject
在此格式中,ClickHouse 将整个 JSON 对象从数据中读取到一个 Object('json')
数据类型的单列中。此格式的推断类型始终是 String
,列名为 json
。
注意:此格式仅在启用了 allow_experimental_object_type
时有效。
示例
模式推断模式
从数据文件集进行模式推断可以在两种不同模式下工作:default
(默认)和 union
(联合)。该模式由设置 schema_inference_mode
控制。
默认模式
在默认模式下,ClickHouse 假设所有文件都有相同的模式,并尝试通过逐个读取文件直到成功来推断模式。
示例:
假设我们有 3 个文件 data1.jsonl
、data2.jsonl
和 data3.jsonl
,其内容如下:
data1.jsonl
:
data2.jsonl
:
data3.jsonl
:
让我们尝试在这 3 个文件上使用模式推断:
结果:
正如我们所见,文件 data3.jsonl
中的 field3
没有被包含。这是因为 ClickHouse 首先尝试从文件 data1.jsonl
推断模式,因 field2
只有空值而失败,然后尝试从 data2.jsonl
推断并成功,因此未读取 data3.jsonl
的数据。
联合模式
在联合模式下,ClickHouse 假设文件可能具有不同的模式,因此会推断所有文件的模式,然后将它们合并为公共模式。
假设我们有 3 个文件 data1.jsonl
、data2.jsonl
和 data3.jsonl
,其内容如下:
data1.jsonl
:
data2.jsonl
:
data3.jsonl
:
让我们尝试在这 3 个文件上使用模式推断:
结果:
如我们所见,我们从所有文件中都得到了所有字段。
注意:
- 由于某些文件可能不包含结果模式中的一些列,因此联合模式仅支持那些支持读取列子集的格式(如 JSONEachRow、Parquet、TSVWithNames 等),而不适用于其他格式(如 CSV、TSV、JSONCompactEachRow 等)。
- 如果 ClickHouse 无法从其中一个文件推断模式,将抛出异常。
- 如果文件数量较多,从所有文件读取模式可能会消耗大量时间。
自动格式检测
如果未指定数据格式且无法通过文件扩展名确定,ClickHouse 将尝试根据内容检测文件格式。
示例:
假设我们有一个内容为以下内容的 data
:
我们可以在不指定格式或结构的情况下检查和查询此文件:
ClickHouse 仅能检测某些子集的格式,而这种检测需要一些时间,始终显式指定格式是更好的选择。