一起学Hive-2

hive环境配置好了, 那我们就开始玩hive吧.

Hive的数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
基本数据类型
tinyint, smallint, int, bigint: 整数类型
float, double: 浮点数类型
boolean: 布尔类型
string: 字符串类型, 也可以使用varchar(64)

hive> create table person(pid int, pname string, married boolean, salary double);
OK
Time taken: 1.245 seconds
hive> desc person;
OK
pid int
pname string
married boolean
salary double
Time taken: 0.45 seconds, Fetched: 4 row(s)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
复杂数据类型:
Array: 数组; 由一系列相同数据类型的数据组成
Map: 集合类型, 包含key-value, 可以通过key来获取value
Struct: 结构类型, 类似c语言.可以包含不同的数据元素, 通过点语法获取都元素值.

hive> create table student(sid int, sname string, grade array<float>);
OK
Time taken: 1.789 seconds
hive> desc student;
OK
sid int
sname string
grade array<float>
Time taken: 0.291 seconds, Fetched: 3 row(s)
插入数据: {1, 'dottie', [90, 70, 80]}

hive> create table student_1(sid int, sname string, sgrade map<string, float>);
OK
Time taken: 0.265 seconds
hive> desc student_1
> ;
OK
sid int
sname string
sgrade map<string,float>
Time taken: 0.253 seconds, Fetched: 3 row(s)
插入数据: {1, 'dottie', <"语文", 90>}


hive>create table student_2(sid int, sname string, grades array<map<string, float>>);
OK
Time taken: 0.087 seconds
hive> desc student_2;
OK
sid int
sname string
grades array<map<string,float>>
Time taken: 0.146 seconds, Fetched: 3 row(s)
插入数据: {1, 'dottie', [<'语文', 90>, <'数学', 80>]}


hive> create table student_3(sid int, info struct <name:string, age:int, sex:string>);
OK
Time taken: 0.149 seconds
hive> desc student_3;
OK
sid int
info struct<name:string,age:int,sex:string>
Time taken: 0.142 seconds, Fetched: 2 row(s)
插入数据: {1, {"dottie", 23, '女'}}
1
2
3
4
时间类型: Date和Timestamp
Date: yyyy-MM-DD
Timestamp: 一串数字表示时间(跟时区没有区别)
两种类型可以相互转换, 这里不过多介绍

Hive数据存储

1
2
3
Hive的数据都是保存在HDFS上的.
具体的可以访问hdfs的web ui界面, 导航栏上的utilities中的browse file system.
hive的数据就保存在 /user/hive/warehouse下面. 我们可以下载下来查看.

Table内部表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
create table t1(tid int, tname string, age int);
默认这张表存储在hdfs上的/user/hive/warehouse目录下;

也可以在创建表的时候指定表创建后数据放在hdfs上那个目录下;
create table t2(tid int, tname string, age int) location '/mytable/hive/t2';
这样表在创建后就会放在hdfs上的/mytable/hive/t2这个位置.

还可以在创建表的时候指定分割符:
create table t3(tid int, tname string, age int) row format delimited fields terminated by ',';
表中数据在存储的时候, 指定分割符,根据逗号分割, 默认是按照制表符.

当然也可以在创建表的数据初始化表中的数据
create table t4 as select * from otherTable;

create table t5 row format delimited fileds terminated by ',' as select * from otherTable;
指定表中数据存储的时候数据之间的分割符.

给表中的字段添加一个新的字段
alter table t1 add columns(english int);

删除一张表: drop table t1;

Partition分区表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
概念:
如果一个学生表中(性别有男和女), 假设我们要查询所有男生或者女生, 那么就要进行全表扫描. 效率就会很低.
这个时候, 我们就可以将该表进行分区, 分成两个区, 一个男生区, 一个女生区, 那么每次在查询就可以在指定分区中查找即可. 提高效率, 这个就是分区表.

create table t1(tid int, tname string) partitioned by(gender string) row format delimited fields terminated by ',';
创建一张表, 并且指定按那个字段进行分区, 还指定了分割符.

hive> desc pratition_table;
OK
tid int
tname string
gender string

# Partition Information
# col_name data_type comment

gender string
Time taken: 0.198 seconds, Fetched: 8 row(s)

可以从大的学生表中进行分区,
insert into table pratition_table partition(gender='M') select id, name from student where gender = 'M';

insert into table pratition_table partition(gender='F') select id, name from student where gender = 'F';
这样就会创建两张表了.(男生和女生)

分区是很有用的, 当我们数据量很大的时候, 我们就可以使用分区表, 然后在对分区表进行查询, 这样就可以提高我们的查询效率了.

我们可以通过查询计划来查看我们的hql语句的执行的效率.
explain select * from student where gender = 'M';
explain select * from partion_table where gender = 'M';
比较这两个hql的执行输出. 可以看见第二条hql的执行计划步骤少了很多. 所以分区表可以提高效率.

External Table外部表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
指向已经在hdfs中存在的数据, 可以创建分区表
外部表只是一个过程, 并不会操作内部表,(并不会跟数据仓库有数据交流), 删除外部表仅仅是删除一个链接.

1. 现在hdfs上创建一个student目录
hdfs dfs -mkdir /student
2. 在本机上创建三张表 student01.txt, student01.txt, student01.txt
里面放上点数据 如:
dottie,22
daejong,23
3. 然后将这三张表上传到hdfs的student目录下.
4. 在hive下创建一个外部表:
create external table extern_student(sid int, sname string, age int) row format delimited fields terminated by ',' location '/student';

hive> create external table extern_student(sname string, age int) row format delimited fields terminated by ',' location '/student';
OK
Time taken: 0.246 seconds
hive> select * from extern_student;
OK
Tom 23
dottie 22
daejong 23
china 100
jiangsu 89
Time taken: 0.386 seconds, Fetched: 5 row(s)

这样创建了一张外部表, 并且初始化了表中数据.

如果我们删除hdfs上的student03.txt
hdfs dfs -rm /student/student03.txt
那么外部表表中的数据也会删除掉student03.txt中的数据.
hive> select * from extern_student;
OK
Tom 23
dottie 22
daejong 23
Time taken: 0.145 seconds, Fetched: 3 row(s)`

Bucket Table表

1
2
3
4
5
6
7
8
9
10
11
12
13
经过hash取值, 然后数据打散掉, 最后存在文件中. 将相同的hash值放到一个桶中, 然后提高查询效率.
create table bucket_table(sid int, sname string, age int) clustered by(sname) into 3 buckets;
这里指明根据sname来进行hash运算. 然后将运算的结果放到3个桶里面.

hive> create table bucket_table(sid int, sname string, age int) clustered by(sname) into 3 buckets;
OK
Time taken: 0.104 seconds
hive> desc bucket_table;
OK
sid int
sname string
age int
Time taken: 0.135 seconds, Fetched: 3 row(s)

视图

1
2
3
4
5
6
7
8
9
10
11
12
视图是一个虚表, 他是一个逻辑概念的表. 可以跨越多张表.
操作视图跟操作真实的表是完全一样的.
视图依赖已经建立的表. 已经建立的表称为基表.
视图可以简化复杂的查询.

create view view_info
as
select aa.name, aa.age, bb.girlFriend
from table1 aa, table2 bb
where aa.id = bb.bid;

视图可以简化查询 和 隐藏一些基表中的信息, 只暴露一些信息给查询的用户.