注意:
此功能在 Delta Lake 3.2 及以上版本中以预览版形式提供,并在 Delta Lake 4.0 及以上版本中得到完全支持。
类型拓宽功能允许将 Delta 表中列的类型更改为更宽的类型。这既支持使用 ALTER TABLE ALTER COLUMN 命令手动更改类型,也支持在写入操作中通过模式演进而自动迁移类型。
支持的类型更改
该功能在 Delta Lake 3.2 中引入了一组有限的支持类型更改,并在 Delta Lake 4.0 及以上版本中进行了扩展。
| 源类型 | Delta 3.2 支持的更宽类型 | Delta 4.0 支持的更宽类型 |
|---|---|---|
| byte | short, int | short, int, long, decimal, double |
| short | int | int, long, decimal, double |
| int | long, decimal, double | |
| long | decimal | |
| float | double | |
| decimal | decimal(具有更高的精度和标度) | |
| date | timestampNTZ |
为避免意外将整数值提升为小数,必须手动将类型从 byte、short、int 或 long 转换为 decimal 或 double。当将整数类型提升为 decimal 或 double 时,如果下游的任何数据写入操作将该值写回整数列,Spark 默认会截断数值的小数部分。
注意
将整数或 decimal 类型转换为 decimal 时,总精度必须大于或等于原始精度。如果同时增加小数位数,总精度必须相应增加。也就是说,decimal(p, s) 可以转换为 decimal(p + k1, s + k2),当且仅当 k1 >= k2 >= 0。
例如,如果希望为一个 decimal(10,1) 的字段增加两位小数,最小目标类型是 decimal(12,3)。byte、short 和 int 类型的最小目标类型是 decimal(10,0)。long 类型的最小目标类型是 decimal(20,0)。
类型更改支持顶级列,也支持嵌套在结构体(struct)、映射(map)和数组(array)内部的字段。
如何启用 Delta Lake 类型拓宽
可以通过将表属性 delta.enableTypeWidening 设置为 true 来在现有表上启用类型拓宽:
ALTER TABLESET TBLPROPERTIES ('delta.enableTypeWidening' = 'true')
或者,可以在创建表时启用类型拓宽:
CREATE TABLEUSING DELTA TBLPROPERTIES('delta.enableTypeWidening' = 'true')
要禁用类型拓宽:
ALTER TABLESET TBLPROPERTIES ('delta.enableTypeWidening' = 'false')
禁用类型拓宽会阻止将来对表应用任何类型更改。它不会影响之前已应用的类型更改,特别需要注意的是,它不会移除类型拓宽的表功能,也不会允许不支持类型拓宽表功能的客户端对该表进行读写。
手动应用类型更改
当 Delta 表启用了类型拓宽功能时,可以使用 ALTER COLUMN 命令更改列的类型:
ALTER TABLEALTER COLUMNTYPE
表结构会更新,而无需重写底层的 Parquet 文件。
通过自动模式演进的类型更改
模式演进与类型拓宽配合使用,可以更新目标表中的数据类型,以匹配写入数据的类型。
注意:如果未启用类型拓宽,模式演进总是尝试向下转换数据,以匹配目标表中的列类型。如果不希望自动拓宽目标表中的数据类型,请在启用模式演进的情况下运行工作负载之前,禁用类型拓宽。
要在数据写入过程中使用模式演进拓宽列的数据类型,必须满足以下条件:
- 写入命令在启用自动模式演进的条件下运行。
- 目标表已启用类型拓宽。
- 源列的类型比目标列的类型更宽。
- 类型拓宽支持该类型更改。
- 该类型更改不是 byte、short、int 或 long 转换为 decimal 或 double。这些类型更改只能通过 ALTER TABLE 手动应用,以避免意外将整数提升为小数。
不满足所有这些条件的类型不匹配情况,将遵循正常的模式强制规则。
移除类型拓宽表功能
可以使用 DROP FEATURE 命令从 Delta 表中移除类型拓宽功能:
ALTER TABLEDROP FEATURE 'typeWidening' [TRUNCATE HISTORY]
注意: 使用 Delta Lake 3.2 启用类型拓宽的表,需要移除的是 typeWidening-preview 功能。
在移除类型拓宽功能时,如有必要,底层的 Parquet 文件会被重写,以确保文件中的列类型与 Delta 表结构中的列类型一致。从表中移除类型拓宽功能后,不支持该功能的 Delta 客户端就可以对该表进行读写操作了。