Hive 1.1.0 某些字段的查询结果为NULL

本文探讨了Hive中表元数据与分区元数据不一致的问题,并对比了不同Hive版本下查询结果的差异。解释了Hive0.10与Hive1.1.0在处理此类问题上的区别。
 现象查询fct_traffic_navpage_path_detl的 2015-01-19 分区显示结果如下

    Hive 1.1.0 返回结果如下,可见最后一个字段为NULL

87FQEZT1UEDXJHJQPFFX7G7ET8S2DVPM 2357378283356 91501191044440048 7326356 NULL

87FQEZT1UEDXJHJQPFFX7G7ET8S2DVPM 2357378283356 121501191035580028 7326356 NULL
UBDTK8D9XUZ9GRZU8NZNXDEG73D4PCZG 2362223711289 161501191549050061 14837289 NULL
Y49EY895ACABHS95DRQEE8DVFEB8JSE1 2360853052224 111501191426280023 115883224 NULL

     Hive 0.10 返回结果”正确“如下:

87FQEZT1UEDXJHJQPFFX7G7ET8S2DVPM 2357378283356 91501191044440048 7326356 2015-01-19 10:44:44
87FQEZT1UEDXJHJQPFFX7G7ET8S2DVPM 2357378283356 121501191035580028 7326356 2015-01-19 10:35:58
UBDTK8D9XUZ9GRZU8NZNXDEG73D4PCZG 2362223711289 161501191549050061 14837289 2015-01-19 15:49:05
Y49EY895ACABHS95DRQEE8DVFEB8JSE1 2360853052224 111501191426280023 115883224 2015-01-19 14:26:28


后来发现,这表的meta和 2015-01-19 这个分区的meta不一样。


hive> desc  dw.fct_traffic_navpage_path_detl;

OK

date_id                 string                                      

chanl_id                bigint                                      

sessn_id                string                                      

。。                                      

detl_event_id           string                                      

nav_refer_intrn_reslt_sum       string                                      

nav_intrn_reslt_sum     string                                      

nav_refer_intrn_kw      string                                      

nav_intrn_kw            string                                      

detl_track_time         string                                      

cart_track_time         string                                      

ds                      string                                      

                 

# Partition Information          

# col_name              data_type               comment             

                 

ds                      string 


hive> desc  dw.fct_traffic_navpage_path_detl partition(ds='2015-01-09');

OK

date_id                 string                                      

chanl_id                bigint                                      

sessn_id                string                                      

。。

                                     

detl_event_id           string                                      

ds                      string                                      

                 

# Partition Information          

# col_name              data_type               comment             

                 

ds                      string 


如上可见表的meta比partition(ds='2015-01-09')的meta多了如下几个字段,

nav_refer_intrn_reslt_sum       string                                      

nav_intrn_reslt_sum     string                                      

nav_refer_intrn_kw      string                                      

nav_intrn_kw            string                                      

detl_track_time         string                                      

cart_track_time         string


后来查了一下,hive是允许表meta和分区meta不一样的,见

http://mail-archives.apache.org/mod_mbox/hive-user/201110.mbox/%3CCA+v58Ocy=uoHsLNQGrYYpRhawFse-p-6U4sjmzNL6VERYrSKTg@mail.gmail.com%3E

还有加改字段的时候可以指定分区:

ALTER TABLE table_name [PARTITION partition_spec]

  ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

  [CASCADE|RESTRICT]


那为啥hive 0.10显示”正确“,hive 1.1.0显示错误呢?

    后来查看jira发现,hive0.10 Sedre的时候是以Table的meta为准,而hive 0.11以后得版本以parition的meta为准,可见

https://issues.apache.org/jira/browse/HIVE-3833  可以说hive 0.11这么做是一种改进。虽然hive 0.10显示“正确 “,其实这是误打误撞读取了tabel的meta所以那些字段显示了出来,其实结果是错误的,是hive0.10的缺陷。


<think>我们正在讨论Hive表中添加新字段的问题。根据用户的问题“我想在Hive表中添加新字段请问Hive addnew columnto table”,我们需要提供在Hive中添加新的方法。根据引用[1]和[2],我们可以使用ALTERTABLE ...ADD COLUMNS语句来添加新。具体步骤:1.添加单个:可以使用`ALTER TABLEtable_nameADD COLUMNS(new_col INT);`,其中new_col是名,INT是数据类型。2.添加多个:可以一次添加多个,例如:`ALTERTABLE table_name ADDCOLUMNS (c1INT,c2STRING);`3.添加并添加注释:`ALTER TABLEtable_nameADD COLUMNS(new_col INTCOMMENT 'a comment');`注意:-默认情况下,新会被添加为最后一。-如果表是分区表,则需要在添加之前指定分区(但根据引用[4],ALTERTABLE ADDCOLUMNS也可以用于分区表,但语法中不需要指定分区,因为它是表级别的操作,会应用到所有分区)。另外,引用[2]提到了REPLACECOLUMNS,但这是用于替换所有(即删除现有并添加新集),通常用于删除或完全改变表结构。而用户只是添加新,所以应该使用ADDCOLUMNS。引用[3]提醒我们,对于ORC类型的表,使用REPLACECOLUMNS删除可能会抛出异常,但我们的操作是ADDCOLUMNS,所以不受此影响。引用[4]详细说明了CHANGE COLUMN,它用于更改现有(如重命名、修改类型、位置等),而不是添加新。因此,添加新应使用ADDCOLUMNS。因此,我们给出以下示例:假设我们有一个表`employee`,现在要添加一个`age`,数据类型为INT,并添加注释“员工年龄”: ```sqlALTER TABLEemployee ADDCOLUMNS (age INTCOMMENT '员工年龄'); ```如果要添加多个,比如`age`和`address`: ```sqlALTER TABLEemployee ADDCOLUMNS (age INTCOMMENT'员工年龄',address STRING COMMENT'家庭住址'); ```注意事项:1.添加操作不会影响现有数据。当查询时,新的值对于旧数据会显示为NULL(除非表使用特殊的SerDe,但通常如此)。2.如果表是分区表,添加后,新也会出现在所有已有分区中。3.Hive中,不能指定新的位置(除了成为最后一),除非使用CHANGE COLUMN语句来调整的顺序(引用[4]提到CHANGECOLUMN可以改变的位置,但ADD COLUMNS不能)。所以,如果需要在特定位置添加,可以先添加,然后用CHANGECOLUMN移动的位置,但这需要多个步骤。例如,如果我们想在`name`后面添加`age`,可以先添加,然后将移动到指定位置: ```sql--先添加(成为最后一) ALTERTABLE employeeADD COLUMNS(ageINT COMMENT'员工年龄');--然后将age移动到name后面ALTER TABLEemployee CHANGECOLUMNage ageINTCOMMENT'员工年龄'AFTER name; ```但是,请注意,移动位置可能会比较繁琐,特别是对于有很多的表。另外,引用[4]提到,ALTER TABLECHANGE COLUMN命令可以使用CASCADE或RESTRICT(默认RESTRICT)。在添加时,我们通常使用默认的RESTRICT,因为它只修改表元数据。而CASCADE会级联到所有分区元数据(在Hive1.1.0及以上版本可用)。对于ADD COLUMNS操作,它本身就是表级别的操作,会自动应用到所有分区,所以不需要指定CASCADE。因此,我们推荐使用ADDCOLUMNS来添加新。最后,生成相关问题。</think>### Hive 表中添加新字段的方法 在 Hive 中向现有表添加新字段,主要使用 `ALTER TABLE ... ADD COLUMNS` 语法。以下是详细操作指南: #### 1. **添加单个字段** ```sql -- 基本语法(默认添加到最后一) ALTER TABLE table_name ADD COLUMNS (new_column_name data_type); -- 示例:添加 INT 类型的 age 字段 ALTER TABLE employee ADD COLUMNS (age INT); ``` #### 2. **添加多个字段** ```sql -- 同时添加多个字段 ALTER TABLE table_name ADD COLUMNS ( column1 data_type, column2 data_type ); -- 示例:添加 salary (DOUBLE) 和 department (STRING) 字段 ALTER TABLE employee ADD COLUMNS ( salary DOUBLE, department STRING ); ``` #### 3. **添加带注释的字段** ```sql -- 添加字段并设置注释 ALTER TABLE table_name ADD COLUMNS ( new_column_name data_type COMMENT '字段描述' ); -- 示例:添加带注释的 join_date 字段 ALTER TABLE employee ADD COLUMNS (join_date DATE COMMENT '入职日期'); ``` #### 4. **添加字段到指定位置** > *需配合 `CHANGE COLUMN` 实现(Hive 0.14+)* ```sql -- 先添加字段 ALTER TABLE employee ADD COLUMNS (phone STRING); -- 再移动字段位置(将 phone 移到 email 后) ALTER TABLE employee CHANGE COLUMN phone phone STRING AFTER email; ``` --- ### ⚠️ 重要注意事项 1. **元数据更新** 添加操作 **仅修改元数据**,不影响现有数据文件。查询时新字段值为 `NULL`[^4]。 2. **分区表处理** 对分区表执行 `ADD COLUMNS` 后: ```sql -- 新字段会自动添加到所有分区 ALTER TABLE partitioned_table ADD COLUMNS (new_col INT); ``` 3. **SerDe 兼容性** - 对于 ORC/Parquet 等格式表,避免使用 `REPLACE COLUMNS` 删除字段,可能引发 SerDe 异常[^3]。 - 添加字段时优先使用 `ADD COLUMNS` 而非 `REPLACE COLUMNS`[^2]。 4. **保留关键字处理** 若字段名是保留关键字(如 `date`),需使用反引号: ```sql ALTER TABLE logs ADD COLUMNS (`date` STRING); ``` --- ### 示例完整流程 ```sql -- 创建示例表 CREATE TABLE employee ( id INT, name STRING, email STRING ); -- 添加多个字段(带注释) ALTER TABLE employee ADD COLUMNS ( age INT COMMENT '员工年龄', salary DOUBLE COMMENT '月薪' ); -- 验证表结构 DESCRIBE employee; ``` 输出结果: ``` id int name string email string age int 员工年龄 salary double 月薪 ``` --- ### 常见问题解决 **Q: 添加字段查询显示 `NULL`?** A: 这是预期行为,Hive 不会自动填充历史数据。需通过 `INSERT` 或 `UPDATE`(需启用 ACID)填充新字段值[^4]。 **Q: 分区表添加字段后新分区不显示?** A: 确保使用 Hive 0.14+ 版本,新字段会自动同步到所有分区元数据[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值