9.1按天划分的表
hive> CREATE TABLE supply_2011_01_02 (id int, part string, quantity int);
hive> CREATE TABLE supply_2011_01_03 (id int, part string, quantity int);
hive> CREATE TABLE supply_2011_01_04 (id int, part string, quantity int);
hive> …. load data …
hive> SELECT part,quantity supply_2011_01_02
> UNION ALL
> SELECT part,quantity from supply_2011_01_03
> WHERE quantity < 4;
对于这种情况,应该使用分区表。
hive> CREATE TABLE supply (id int, part string, quantity int)
> PARTITIONED BY (int day);hive> ALTER TABLE supply add PARTITION (day=20110102);
hive> ALTER TABLE supply add PARTITION (day=20110103);
hive> ALTER TABLE supply add PARTITION (day=20110102);hive> .... load data ...
hive> SELECT part,quantity FROM supply
> WHERE day>=20110102 AND day<20110103 AND quantity < 4;
9.2 关于分区
hive> CREATE TABLE weblogs (url string, time long )
> PARTITIONED BY (day int, state string, city string);
hive> SELECT * FROM weblogs WHERE day=20110102;
hive> CREATE TABLE weblogs (url string, time long, state string, city string )
> PARTITIONED BY (day int);
hive> SELECT * FROM weblogs WHERE day=20110102;
对上述语句使用两个级别的分区。
hive> CREATE TABLE weblogs (url string, time long, city string )
> PARTITIONED BY (day int, state string);
hive> SELECT * FROM weblogs WHERE day=20110102;
9.3 唯一建和标准化
Hive没有主键或基于序列密钥生成自增键的概念。
9.4 同一份数据多种处理
hive> INSERT OVERWRITE TABLE sales
> SELECT * FROM history WHERE action='purchased';
hive> INSERT OVERWRITE TABLE credits
> SELECT * FROM history WHERE action='returned';
以上语句表达的意思是从源表history
读取数据,然后导入到2个不同的表中。然而这种写法,虽然语法正确,但执行效率底下。可使用下面的查询达到同样的目的,且只扫描一次history
表。如:
hive> FROM history
> INSERT OVERWRITE sales SELECT * WHERE action='purchased'
> INSERT OVERWRITE credits SELECT * WHERE action='returned';
9.5 对于每个表的分区
9.6 分桶表数据存储
分区是一种提供隔离数据和优化查询的方式。
分桶是将数据集分解成更容易管理的若干部分的一种技术。
hive> CREATE TABLE weblog (url STRING, source_ip STRING)
> PARTITIONED BY (dt STRING, user_id INT);
hive> FROM raw_weblog
> INSERT OVERWRITE TABLE page_view PARTITION(dt='2012-06-08', user_id)
> SELECT server_name, url, source_ip, dt, user_id;
hive> CREATE TABLE weblog (user_id INT, url STRING, source_ip STRING)
> PARTITIONED BY (dt STRING)
> CLUSTERED BY (user_id) INTO 96 BUCKETS;
在使用NSERT … TABLE
语句时,需要设置hive.enforce.bucketing
属性为目标表的分桶初始化过程设置正确的reducer
个数。如:
hive> SET hive.enforce.bucketing = true;
hive> FROM raw_logs
> INSERT OVERWRITE TABLE weblog
> PARTITION (dt='2009-02-25')
> SELECT user_id, url, source_ip WHERE dt='2009-02-25';
若没有设置hive.enforce.bucketing
属性,就需要设置和分桶个数相匹配的reducer
个数。如set mapred.reduce.tasks=96
,在INSERT
语句中,在SELECT
语句后增加CLUSTER BY
语句。
9.7 为表增加列
Hive使用SerDe
用于从输入中提取数据。也可以用于输出数据。
使用ALTER TABLE ADD COLUMN
语句添加新字段。如:
hive> ALTER TABLE weblogs ADD COLUMNS (user_id string);
无法在现有字段前和中间增加新字段。
9.8 使用列存储表
Hive通常使用行式存储。不过也提供了一个列式SerDe
来以混合列式格式存储信息。
9.8.1 重复数据
有足够多的行。如:
state uid age
NY Bob 40
NJ Sara 32
NY Peter 14
NY Sandra 4
9.8.2 多列
state uid age server tz many_more …
NY Bob 40 web1 est stuff
NJ Sara 32 web1 est stuff
NY Peter 14 web3 pst stuff
NY Sandra 4 web45 pst stuff
hive> SELECT distinct(state) from weblogs;
NY
NJ
基于列式存储。使得表分析数据更快。