假设我有一个包含三列 A、B、C 的表。如果源停止发送 B 数据(我们假设它已在文件中删除,而不是在表模式中删除)。几天后,如果来源想将该列添加回来,但在其他位置,如 B、A、C。iceberg 如何解决这种情况?冰山将如何映射列名称?我尝试使用一些冰山表属性,但没有任何效果。它抛出一个错误
在 Iceberg 中,列映射是通过
column IDs
处理的,而不是依赖于列位置或名称。
1。初始表架构: 列:
A, B, C
每列都由 Iceberg 分配一个唯一的列 ID。
2。当 B 列缺失时: 如果源停止发送
B
但模式仍然包含 B,Iceberg 会将其解释为新数据文件中 B
的空值,并且不会对模式进行任何更改。
3.添加回 B: 当源开始发送回
B
但处于新位置 (e.g., B, A, C)
时,如果您尝试将 B
映射为新列或在未显式协调的情况下对列重新排序,则模式演化将会失败。这显然是因为 Iceberg 通过 ID 而不是通过位置来识别列。如果您尝试重新添加 B
而不确保它与原始列 ID 匹配,Iceberg 会将其视为新列,从而导致冲突。
那么解决办法是什么?
确保列映射一致:
要正确恢复
B
,请确保其 column ID
与其 original ID
匹配。这需要更新架构以使用其现有元数据重新引入 B
。这个想法是 REORDER
而不是仅仅添加/删除列。
ALTER TABLE table_name REPLACE COLUMN `B` COMMENT 'Restoring/Reordering B to new position';
最好的方法是-
注意: 默认情况下,Iceberg 维护严格的模式演化规则。您可以调整
schema.alter.order.columns
等属性来启用列重新排序。但是,这不会影响列 ID 映射,也不会直接解决此问题。
最佳实践:
column IDs
而不是列位置或列名称进行映射。