Snowflake SQL 转换指南
数据类型
数值类型
在 ClickHouse 和 Snowflake 之间移动数据的用户会立即注意到,
ClickHouse 提供了更细粒度的数字声明精度。例如,
Snowflake 提供数字类型 Number。这个类型要求用户指定精度(总位数)和小数位数(小数点右侧的位数),总共最多为 38。整数声明与 Number 同义,仅定义固定的精度和小数位数,而且范围相同。这种便利性得益于在 Snowflake 中修改精度(对于整数小数位数为 0)并不会影响磁盘上的数据大小 - 在微分区级别写入时会使用最小所需的字节来满足数值范围。然而,小数位数确实会影响存储空间,并通过压缩进行抵消。Float64
类型提供更大的值范围,但精度有所下降。
将其与 ClickHouse 对比,后者提供多种有符号和无符号的浮点和整数精度。借助这些,ClickHouse 用户可以明确整数所需的精度以优化存储和内存开销。Decimal 类型,相当于 Snowflake 的 Number 类型,也提供两倍的精度和76位小数。除了类似的 Float64
值,ClickHouse 还提供 Float32
,用于当精度不那么关键而压缩至关重要的情况。
字符串类型
ClickHouse 和 Snowflake 在字符串数据存储方面采取了对比鲜明的方法。Snowflake 中的 VARCHAR
存储 UTF-8 编码的 Unicode 字符,允许用户指定最大长度。此长度对存储或性能没有影响,始终使用最小字节数来存储字符串,而只是提供有用的约束供下游工具使用。其他类型如 Text
和 NChar
只是此类型的别名。相反,ClickHouse 将所有 字符串数据作为原始字节 存储,使用 String
类型(不需要指定长度),编码的任务推给用户,并提供 查询时函数 来处理不同的编码。我们建议读者参考 "不透明数据参数" 来了解背后的动机。因此,ClickHouse 的 String
类型在实现上更可比于 Snowflake 的 Binary 类型。 Snowflake 和 ClickHouse 均支持“排序”,允许用户覆盖字符串的排序和比较方式。
半结构化类型
Snowflake 支持半结构化数据的 VARIANT
、OBJECT
和 ARRAY
类型。
ClickHouse 提供相应的 Variant
、Object
(现已弃用,替代为原生 JSON
类型)和 Array
类型。此外,ClickHouse 还具有 JSON
类型,该类型取代了现已弃用的 Object('json')
类型,并在 与其他本地 JSON 类型的比较中 特别高效和节省存储。
ClickHouse 还支持命名的 Tuple
和通过 Nested
类型的元组数组,允许用户明确映射嵌套结构。这允许在整个层次结构中应用编解码器和类型优化,与 Snowflake 不同,后者要求用户使用 OBJECT
、VARIANT
和 ARRAY
类型用于外部对象,并且不允许 明确的内部类型。这种内部类型也简化了 ClickHouse 中嵌套数字的查询,因为无需转换,可以在索引定义中使用。
在 ClickHouse 中,编解码器和优化类型也可以应用于子结构。这带来了一个附加好处,即与扁平化数据相比,嵌套结构的压缩效果依然出色。相比之下,由于无法对子结构应用特定类型,Snowflake 建议 扁平化数据以获得最佳压缩效果。Snowflake 还对这些数据类型 施加大小限制。
类型参考
Snowflake | ClickHouse | 注意 |
---|---|---|
NUMBER | Decimal | ClickHouse 支持的精度和小数位数是 Snowflake 的两倍 - 76 位与 38 位。 |
FLOAT , FLOAT4 , FLOAT8 | Float32 , Float64 | Snowflake 中的所有浮点数都是 64 位。 |
VARCHAR | String | |
BINARY | String | |
BOOLEAN | Bool | |
DATE | Date , Date32 | 在 Snowflake 中的 DATE 提供比 ClickHouse 更广泛的日期范围,例如 Date32 的最小值为 1900-01-01 ,而 Date 为 1970-01-01 。ClickHouse 的 Date 提供更具成本效益(两字节)的存储。 |
TIME(N) | 没有直接等价类型,但可以表示为 DateTime 和 DateTime64(N) . | DateTime64 使用相同的精度概念。 |
TIMESTAMP - TIMESTAMP_LTZ , TIMESTAMP_NTZ , TIMESTAMP_TZ | DateTime 和 DateTime64 | DateTime 和 DateTime64 可以选择性为列定义 TZ 参数。如果不存在,将使用服务器的时区。此外,客户端还可以使用 --use_client_time_zone 参数。 |
VARIANT | JSON , Tuple , Nested | JSON 类型在 ClickHouse 中是实验性的。该类型在插入时推断列类型。Tuple 、Nested 和 Array 也可用于构建显式类型结构作为替代方案。 |
OBJECT | Tuple , Map , JSON | OBJECT 和 Map 类似于 ClickHouse 中的 JSON 类型,其中键为 String 。ClickHouse 要求值保持一致并具有强类型,而 Snowflake 使用 VARIANT 。这意味着不同键的值可以是不同的类型。如果 ClickHouse 中需要此功能,请使用 Tuple 显式定义层次结构,或依赖于 JSON 类型。 |
ARRAY | Array , Nested | Snowflake 中的 ARRAY 使用 VARIANT 作为元素 - 一种超类型。相比之下,这些在 ClickHouse 中是强类型的。 |
GEOGRAPHY | Point , Ring , Polygon , MultiPolygon | Snowflake 使用坐标系统(WGS 84),而 ClickHouse 在查询时应用。 |
GEOMETRY | Point , Ring , Polygon , MultiPolygon |
ClickHouse 类型 | 描述 |
---|---|
IPv4 和 IPv6 | IP 特定类型,可能比 Snowflake 更有效率地存储。 |
FixedString | 允许使用固定长度的字节,这对哈希很有用。 |
LowCardinality | 允许任何类型进行字典编码。当基数预期小于 100k 时非常有用。 |
Enum | 允许以 8 位或 16 位范围有效编码命名值。 |
UUID | 用于高效存储 UUID。 |
Array(Float32) | 向量可以表示为 Float32 数组,并支持距离函数。 |
最后,ClickHouse 提供了存储聚合函数 中间状态 的独特能力。该状态是实现特定的,但允许存储聚合结果并随后查询(带有相应的合并函数)。通常,此功能通过物化视图使用,如下面所示,通过存储对插入数据的查询增量结果来提高特定查询的性能,并以最小的存储成本实现(更多细节请参见这里)。