1) 创建一个测试表。
hive> create table test(id int,name string);
OK
Time taken: 0.385 seconds
hive> desc test;
OK
id int
name string
Time taken: 0.261 seconds, Fetched: 2 row(s)
2) 基于表 test 创建一个 test_view 视图。
hive> create view test_view(id,name_length) as select id,length(name) from test;
3) 查看 test_view 视图属性。
hive> desc test_view;
4) 查看视图结果。
hive> select * from test_view;
1) Hive 创建索引。
hive> create index user_index on table user(id) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild IN TABLE user_index_table;
2) 更新数据。
hive> alter index user_index on user rebuild;
3) 删除索引
hive> drop index user_index on user;
4) 查看索引
hive> show index on user;
5) 创建表和索引案例
hive> create table index_test(id INT,name STRING) PARTITIONED BY (dt STRING) ROW FORMAT DELIMITED FILEDS TERMINATED BY ',';
创建一个索引测试表 index_test,dt作为分区属性,“ROW FORMAT DELIMITED FILEDS TERMINATED BY ‘,’” 表示用逗号分割字符串,默认为‘\001’。
6) 创建一个临时索引表 index_tmp。
hive> create table index_tmp(id INT,name STRING,dt STRING) ROW FORMAT DELIMITED FILEDS TERMINATED BY ',';
7) 加载本地数据到 index_tmp 表中。
hive> load data local inpath '/home/hadoop/cs0/test.txt' into table index_tmp;
设置 Hive 的索引属性来优化索引查询,命令如下。
hive> set hive.exec.dynamic.partition.mode=nonstrict;----设置所有列为 dynamic partition
hive> set hive.exec.dynamic.partition=true;----使用动态分区
8) 查询index_tmp 表中的数据,插入 table_test 表中。
hive> insert overwrite table index_test partition(dt) select id,name,dt from index_tmp;
9) 使用 index_test 表,在属性 id 上创建一个索引 index1_index_test 。
hive> create index index1_index_test on table index_test(id) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' WITH DEFERERD REBUILD;
10) 填充索引数据。
hive> alter index index1_index_test on index_test rebuild;
11) 查看创建的索引。
hive> show index on index_test
12) 查看分区信息。
hive> show partitions index_test;
13) 查看索引数据。
$ hadoop fs -ls /usr/hive/warehouse/default_index_test_index1_index_test_
14) 删除索引。
hive> drop index index1_index_test on index_test;
show index on index_test;
15) 索引数据也被删除。
$ hadoop fs -ls /usr/hive/warehouse/default_index_test_index1_index_test_
no such file or directory
16) 修改配置文件信息。
< property>
< name>hive.optimize.index.filter< /name>
< value>true< /value>
< /property>
< property>
< name>hive.optimize.index.groupby< /name>
< value>true< /value>
< /property>
< property>
< name>hive.optimize.index.filter.compact.minsize< /name>
< value>5120< /value>
< /property>
hive.optimize.index.filter 和 hive.optimize.index.groupby 参数默认是 false。使用索引的时候必须把这两个参数开启,才能起到作用。
hive.optimize.index.filter.compact.minsize 参数为输入一个紧凑的索引将被自动采用最小尺寸、默认5368709120(以字节为单位)。
Hive 的分区通过在创建表时启动 PARTITION BY 实现,用来分区的维度并不是实际数据的某一列,具体分区的标志是由插入内容时给定的。当要查询某一分区的内容时可以采用 WHERE 语句, 例如使用 “WHERE tablename.partition_key>a” 创建含分区的表。创建分区语法如下。
CREATE TABLE table_name(
...
)
PARTITION BY (dt STRING,country STRING)
1、 创建分区
Hive 中创建分区表没有什么复杂的分区类型(范围分区、列表分区、hash 分区,混合分区等)。分区列也不是表中的一个实际的字段,而是一个或者多个伪列。意思是说,在表的数据文件中实际并不保存分区列的信息与数据。
创建一个简单的分区表。
hive> create table partition_test(member_id string,name string) partitioned by (stat_date string,province string) row format delimited fields terminated by ',';
这个例子中创建了 stat_date 和 province 两个字段作为分区列。通常情况下需要预先创建好分区,然后才能使用该分区。例如:
hive> alter table partition_test add partition (stat_date='2016-04-28',province='beijing');
这样就创建了一个分区。这时会看到 Hive 在HDFS 存储中创建了一个相应的文件夹。
$ hadoop fs -ls /user/hive/warehouse/partition_test/stat_date=2015-01-18
/user/hive/warehouse/partition_test/stat_date=2016-04-28/province=beijing----显示刚刚创建的分区
每一个分区都会有一个独立的文件夹,在上面例子中,stat_date 是主层次,province 是 副层次。
2、 插入数据
使用一个辅助的非分区表 partition_test_input 准备向 partition_test 中插入数据,实现步骤如下。
1) 查看 partition_test_input 表的结构,命令如下。
hive> desc partition_test_input;
2) 查看 partition_test_input 的数据,命令如下。
hive> select * from partition_test_input;
3) 向 partition_test 的分区中插入数据,命令如下。
insert overwrite table partition_test partition(stat_date='2015-01-18',province='jiangsu') select member_id,name from partition_test_input where stat_date='2016-04-28' and province='jiangsu';
向多个分区插入数据,命令如下。
hive> from partition_test_input
insert overwrite table partition_test partition(stat_date='2016-04-28',province='jiangsu') select member_id,name from partition_test_input where stat_date='2016-04-28' and province='jiangsu'
insert overwrite table partition_test partition(stat_date='2016-04-28',province='sichuan') select member_id,name from partition_test_input where stat_date='2016-04-28' and province='sichuan'
insert overwrite table partition_test partition(stat_date='2016-04-28',province='beijing') select member_id,name from partition_test_input where stat_date='2016-04-28' and province='beijing';
3、 动态分区
按照上面的方法向分区表中插入数据,如果数据源很大,针对一个分区就要写一个 insert ,非常麻烦。使用动态分区可以很好地解决上述问题。动态分区可以根据查询得到的数据自动匹配到相应的分区中去。
动态分区可以通过下面的设置来打开:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
动态分区的使用方法很简单,假设向 stat_date=’2016-04-28’ 这个分区下插入数据,至于 province 插到哪个子分区下让数据库自己来判断。stat_date 叫做静态分区列,province 叫做动态分区列。
hive> insert overwrite table partition_test partition(stat_date='2016-04-28',province)
select member_id,name province from partition_test_input where stat_date='2016-04-28';
注意,动态分区不允许主分区采用动态列而副分区采用静态列,这样将导致所有的主分区都要创建副分区静态列所定义的分区。
hive.exec.max.dynamic.partitions.pernode:每一个 MapReduce Job 允许创建的分区的最大数量,如果超过这个数量就会报错(默认值100)。
hive.exec.max.dynamic.partitions:一个 dml 语句允许创建的所有分区的最大数量(默认值100)。
hive.exec.max.created.files:所有 MapReduce Job 允许创建的文件的最大数量(默认值10000)。
尽量让分区列的值相同的数据在同一个 MapReduce 中,这样每一个 MapReduce 可以尽量少地产生新的文件夹,可以通过 DISTRIBUTE BY 将分区列值相同的数据放到一起,命令如下。
hive> insert overwrite table partition_test partition(stat_date,province)
select memeber_id,name,stat_date,province from partition_test_input distribute by stat_date,province;
Hive 中 table 可以拆分成 Partition table 和 桶(BUCKET),桶操作是通过 Partition 的 CLUSTERED BY 实现的,BUCKET 中的数据可以通过 SORT BY 排序。
BUCKET 主要作用如下。
1)数据 sampling;
2)提升某些查询操作效率,例如 Map-Side Join。
需要特别主要的是,CLUSTERED BY 和 SORT BY 不会影响数据的导入,这意味着,用户必须自己负责数据的导入,包括数据额分桶和排序。 ‘set hive.enforce.bucketing=true’ 可以自动控制上一轮 Reduce 的数量从而适配 BUCKET 的个数,当然,用户也可以自主设置 mapred.reduce.tasks 去适配 BUCKET 个数,推荐使用:
hive> set hive.enforce.bucketing=true;
操作示例如下。
1) 创建临时表 student_tmp,并导入数据。
hive> desc student_tmp;
hive> select * from student_tmp;
2) 创建 student 表。
hive> create table student(id int,age int,name string)
partitioned by (stat_date string)
clustered by (id) sorted by(age) into 2 bucket
row format delimited fields terminated by ',';
3) 设置环境变量。
hive> set hive.enforce.bucketing=true;
4) 插入数据。
hive> from student_tmp
insert overwrite table student partition(stat_date='2016-04-28')
select id,age,name where stat_date='2016-04-28' sort by age;
5) 查看文件目录。
$ hadoop fs -ls /usr/hive/warehouse/student/stat_date=2016-04-28/
6) 查看 sampling 数据。
hive> select * from student tablesample(bucket 1 out of 2 on id);
tablesample 是抽样语句,语法如下。
tablesample(bucket x out of y)
y 必须是 table 中 BUCKET 总数的倍数或者因子。