
# Iceberg隐式分区和分区演进介绍
隐式分区是Iceberg内置的自动分区机制，由表自动根据原始字段（例如时间戳）通过内置函数计算分区，用户无需手动维护分区列，使得查询与物理存储解耦，可直接修改分区规则而不用迁移数据。
典型使用场景：
- 日志、埋点、时序数据按天/小时/月分区。
- 多维度分区（时间 + 级别/类型/业务线）。
- 表需要修改分区策略但无需重写数据。
- 多人协作，避免手动分区字段误写错。
Iceberg隐式分区的核心是自动根据原始字段计算分区、无需用户维护物理分区列，既能通过分区裁剪大幅提升查询效率，又能实现存储与逻辑解耦，支持分区方案灵活演进且无需进行数据迁移。
#### 隐式分区转换规则
隐式分区转换规则请参见[表1]，其中：
- 所有转换对于null输入值都必须返回null。
- void转换可用于替换现有分区字段中的转换，以便在v1表中有效地删除该字段，详细说明请参见[分区演进]。

- bucket\[N\]：用于对源值应用哈希函数（通常是Iceberg的特定实现），然后对N取模，得到一个介于0到N-1之间的桶号。 不同的数据类型（例如int和string）即使逻辑值相同（例如34和"34"），也会产生不同的哈希值，因此不能直接进行类型升级。
  
- truncate\[W\]
  - 对于数字类型（int、long、decimal）：将值截断为不超过该值、且为W倍数的最大数值。例如，truncate\[10\]会将17转换为10。
  
  - 对于字符串和二进制类型：截断到前W个字符/字节。例如，truncate\[3\]会将**"iceberg"** 转换为**"ice"**。
   
 表1隐式分区转换规则 
| 转换名称          | 说明           | 源类型                                                                                                   | 转换结果类型  |
|:---|:---|:---|:---|
| identity      | 源值，未经修改。     | 除geometry、geography、variant外的任何类型。                                                                    | 源类型     |
| bucket\[N\]   | 值的哈希值，对N取模。  | int、long、decimal、date、time、timestamp、timestamptz、timestamp_ns、timestamptz_ns、string、uuid、fixed、binary | int     |
| truncate\[W\] | 值被截断到宽度W。    | int、long、decimal、string、binary                                                                        | 源类型     |
| year          | 提取日期或时间戳的年份。 | date、timestamp、timestamptz、timestamp_ns、timestamptz_ns                                                | int     |
| month         | 提取日期或时间戳的月份。 | date、timestamp、timestamptz、timestamp_ns、timestamptz_ns                                                | int     |
| day           | 提取日期或时间戳的日期。 | date、timestamp、timestamptz、timestamp_ns、timestamptz_ns                                                | int     |
| hour          | 提取时间戳的小时。    | timestamp、timestamptz、timestamp_ns、timestamptz_ns                                                     | int     |
| void          | 总是产生null。    | 任何数据类型                                                                                                | 源类型或int |
   
 #### 分区演进
表分区可以通过添加、删除、重命名或重新排序分区规范字段来进行演进。
更改分区规范会产生一个新的规范，该规范由一个唯一的规范ID标识。新规范会被添加到表的分区规范列表中，并且可以被设置为表的默认规范。
演进规则：
- 保持字段ID稳定：在演化规范时，更改不应导致分区字段ID发生变化。分区字段ID在清单文件中被用作分区元组的字段ID。
- v2表：在v2中，必须为每个分区字段显式跟踪其分区字段ID。新的ID根据表元数据中最后分配的分区ID来分配。
- v1表（兼容性）：在v1中，分区字段ID没有被显式跟踪，但在参考实现中是按顺序从1000开始分配的。由于具有相同ID的分区字段可能包含不同的数据类型，这种分配方式在基于来自多个规范的清单文件读取元数据表时会产生问题。为了与旧版本兼容，建议v1表的分区演化遵循以下规则：
  - 不要重新排序分区字段。
  
  - 不要删除分区字段，应使用void转换替换该字段的转换方式来"软删除"。
  
  - 只能在先前分区规范的末尾添加新的分区字段。
   
 
