跳到内容

Delta 类型拓宽

类型拓宽功能允许将 Delta 表中列的类型更改为更宽的类型。这使得可以使用 ALTER TABLE ALTER COLUMN 命令进行手动类型更改,并在写入操作期间通过模式演进进行自动类型迁移。

该功能在 Delta Lake 3.2 中引入了一组有限的受支持类型更改,并在 Delta Lake 4.0 及更高版本中进行了扩展。

源类型支持的更宽类型 - Delta 3.2支持的更宽类型 - Delta 4.0
byteshort, intshort, int, long, decimal, double
shortintint, long, decimal, double
intlong, decimal, double
longdecimal
floatdouble
decimal具有更高精度和小数位数的 decimal
datetimestampNTZ

为避免意外将整数值提升为小数,您必须手动提交byteshortintlongdecimaldouble 的类型更改。当将整数类型提升为 decimaldouble 时,如果任何下游摄取将此值写回整数列,Spark 默认将截断值的小数部分。

类型更改支持顶级列以及结构体、映射和数组中嵌套的字段。

您可以通过将 delta.enableTypeWidening 表属性设置为 true 来在现有表上启用类型拓宽

ALTER TABLE <table_name> SET TBLPROPERTIES ('delta.enableTypeWidening' = 'true')

或者,您可以在创建表时启用类型拓宽

CREATE TABLE <table_name> USING DELTA TBLPROPERTIES('delta.enableTypeWidening' = 'true')

要禁用类型拓宽

ALTER TABLE <table_name> SET TBLPROPERTIES ('delta.enableTypeWidening' = 'false')

禁用类型拓宽可防止将来对表应用类型更改。它不影响先前应用的类型更改,特别是它不会移除类型拓宽表特性,也不允许不支持类型拓宽表特性的客户端读写该表。

要从表中移除类型拓宽表特性并允许不支持此特性的其他客户端读写该表,请参阅移除类型拓宽表特性

当 Delta 表上启用了类型拓宽时,您可以使用 ALTER COLUMN 命令更改列的类型

ALTER TABLE <table_name> ALTER COLUMN <col_name> TYPE <new_type>

表架构会更新,而无需重写底层 Parquet 文件。

模式演进与类型拓宽协同工作,以更新目标表中的数据类型,使其与传入数据的类型匹配。

要在摄取过程中使用模式演进拓宽列的数据类型,您必须满足以下条件

  • 写入命令在启用自动模式演进的情况下运行。
  • 目标表已启用类型拓宽。
  • 源列类型比目标列类型宽。
  • 类型拓宽支持类型更改。
  • 类型更改不是从 byteshortintlongdecimaldouble。这些类型更改只能使用 ALTER TABLE 手动应用,以避免将整数意外提升为小数。

不满足所有这些条件的类型不匹配将遵循正常的模式强制规则。

可以使用 DROP FEATURE 命令从 Delta 表中移除类型拓宽特性

ALTER TABLE <table_name> DROP FEATURE 'typeWidening' [TRUNCATE HISTORY]

有关删除 Delta 表特性的更多信息,请参阅删除 Delta 表特性

删除类型拓宽特性时,如有必要,会重写底层 Parquet 文件,以确保文件中的列类型与 Delta 表架构中的列类型匹配。从表中移除类型拓宽特性后,不支持该特性的 Delta 客户端可以读写该表。

Iceberg 不支持类型拓宽涵盖的所有类型更改,请参阅 Iceberg 模式演进。特别是,Iceberg V2 不支持以下类型更改

  • byteshortintlongdecimaldouble
  • decimal 精度增加
  • datetimestampNTZ

当 Delta 表上启用了带有 Iceberg 兼容性的 UniForm 时,应用这些类型更改之一将导致错误。

如果将这些不受支持的类型更改之一应用到 Delta 表,则在表上启用带有 Iceberg 兼容性的 UniForm 将导致错误。要解决此错误,您必须删除类型拓宽表特性