Delta Lake – 类型扩展

原文:towardsdatascience.com/delta-lake-type-widening-82935384a0f5

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/acace178c5ac1b448730e038c86a9cb0.png

图片由 Luca FlorioUnsplash 提供

Delta Lake 正在发布新的大版本,当然,社区中每个人都广泛期待的功能有很多。其中之一被称为类型扩展,本文将致力于解释它是什么以及为什么它是有用的。


生活中唯一不变的是变化 – 赫拉克利特

赫拉克利特的名言不仅适用于我们所生活的世界,而且也适用于谈论数据,描述它的信息。我们正处于一个快节奏的商业环境时代,适应是跟上我们不断变化的世界中涌现出的所有新要求的关键。这些变化往往会导致我们数据的基本结构发生变化,因此我们需要能够适应这些变化,以保持对所描述内容的真实性。

在 Delta Lake 中,我们使用 Delta 表来描述我们的数据,并且有几种方法可以使用当前的架构演变功能无缝地适应这些更改。我们可以:添加一个更好地描述我们实体的新列;需要重命名以更相关名称的列;如果列顺序未优化,则重新排序列;如果我们不再需要它,则删除列;或者由于例如缺少刻度(数字无法放入整数中,需要存储在 long 中)而更改列的类型。虽然上述所有示例在 Delta Lake 中都已可能,但更改列类型需要重写整个表****,这并不理想,尤其是对于规模达到千兆字节的表。这就是类型扩展发挥作用的地方。

*****使用列映射有解决方案,但它们并不非常用户友好。

类型扩展

类型扩展允许将给定列的类型更改为更宽的类型(可以存储相同或更多信息)。

有两种类型的类型扩展,自动的,正如其名所示,是自动应用的,以及显式类型扩展,它将需要使用 ALTER TABLE 命令。所有自动类型更改都由显式类型更改支持。

自动

  • Byte → Short → Int → Long

  • Float → Double

  • 小数刻度和精度增加(6,2)→(10,4)

  • Date → TimestampNTZ (无时区的时间戳)

  • varchar(x) → varchar(y) – (x < y)

  • varchar(x) → string

仅显式

  • int → double

  • byte/short/int/long → decimal

  • char(x) → char(y)/varchar(y) – (x < y)

  • char(x) → string

这些更改也支持嵌套字段以及数组或映射内部。

如何使用它?

如前所述,我们可以进行自动或显式类型扩展。要使用此功能,我们需要启用它,如下所示:

ALTER TABLE t SET TBLPROPERTIES ('delta.enableTypeWidening' = true)

对于自动的,在为我们将要写入的表格启用功能后,我们需要确保会话已启用模式演变,以便在源包含比相应目标更宽的类型时自动扩展类型。

可以像这样启用模式演变:

write(Stream).option("mergeSchema", "true")

or

SET spark.databricks.delta.schema.autoMerge.enabled = true

对于显式的类型提升,我们明确运行带有请求(有效)变更的 ALTER TABLE 命令:

ALTER TABLE t CHANGE COLUMN col TYPE type

类型变更时会发生什么?

当类型被扩展时,表格的模式通过元数据操作进行更改。即使已经存在的文件是用不同的模式编写的,它们仍然保持不变,如果没有启用类型提升,我们本应需要重写所有这些文件以获得相同的结果。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9dff0fbef3d20ebe3ea6544499f92f9b.png

表格类型从整数变为长整型 - 图片由作者提供

为了维护模式中所有变更的历史记录,将在相关字段的元数据下存储附加信息,这将成为作者协议的一部分。以下是在映射键中此类变更的示例:

{
    "name" : "mapColumn",
    "type" : {
      "type": "map",
      "keyType": "integer",
      "valueType": "long",
      "valueContainsNull": true
    },
    "nullable" : true,
    "metadata" : { 
      "delta.typeChanges": [
        {
          "tableVersion": 2,
          "fromType": "short",
          "toType": "integer",
          "fieldPath": "value"
        },
        {
          "tableVersion": 5,
          "fromType": "integer",
          "toType": "long",
          "fieldPath": "value"
        }
      ]
    }
  }

四条信息将存储在 delta.typeChanges 中的元数据字段下:

  • tableVersion – 应用变更时的表格版本

  • fromType – 变更前的列类型

  • toType – 变更后的列类型

  • fieldPath(可选) – keyvalueelement 分别用于表示映射的键、值和数组类型。对于嵌套数组和映射,它使用从父级开始的完整路径作为前缀

此信息将由读者使用,以便他们在读取仍包含 fromType 类型的旧文件时提升类型。

随着时间的推移,UPDATE/MERGE 操作将运行并触发所有仍在使用旧模式的文件的天然重写。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/52197d79e3f2dadff3bd17c328bdcfdb.png

自然重写 – 图片由作者

在此情况下,如果所有文件都具有与最新元数据操作类型变更相同的模式,作者将移除存在于 delta.typeChanges 中的元数据信息。这样,读者可以无需对包含先前类型的文件进行特殊处理即可读取表格。

如何禁用类型提升?

要完全禁用此功能,我们只需将其设置为 false:

ALTER TABLE t SET TBLPROPERTIES ('delta.enableTypeWidening' = false)

or

ALTER TABLE t DROP FEATURE typeWidening

禁用类型提升后,Delta 需要确保所有不兼容的读者都可以无问题地读取表格。

如果在可用的历史记录中没有对类型进行更改,则该特性将成功删除。然而,如果当前表版本包含类型更改,则将触发所选文件的重写(RowCommitVersion ≥ 包含类型更改的最新元数据操作)以及所有类型拓宽元数据将被移除。作业执行后,将抛出异常,提示用户在保留期过期后重新运行DROP FEATURE命令。对于仅包含历史版本中类型拓宽残留的表(仅通过时间旅行可用),将仅抛出异常,提示在保留期过期后重新运行命令,类似于前一种情况。

结论

在这篇帖子中,我们学习了类型拓宽(Type Widening)的概念及其重要性,它允许在不进行完整表重写的情况下进行类型更改。这个特性在撰写本文时仍在开发中(见:github.com/delta-io/delta/issues/2622),可能会发生变化,但总体思路是类型更改应该更加用户友好,并且不需要复杂的操作。在此期间,让我们等待 Delta 的新主要版本及其将包含的所有酷炫特性!


如果你希望阅读我关于高度请求的 Delta Lake 特性——液态聚类(Liquid Clustering)的最新帖子,请确保在以下链接阅读:

Delta Lake – 分区、Z-顺序和液态聚类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值