以下所建立的表都是在mydb数据库创建的(在Hive的命令行下,直接use mydb;然后进行如下操作就可以)。
1.Hive建表
建表的完整语法如下:
CREATE TABLE IF NOT EXISTS t2(id int,name string,age int)
COMMENT 'xx' //注释
ROW FORMAT DELIMITED //行分隔符
FIELDS TERMINATED BY ',' //字段分隔符,这里使用的是逗号可以根据自己的需要自行进行修改
STORED AS TEXTFILE ; //以文本方式进行存储,可以根据自己的需要进行修改
有关Hive建表的描述,可参考如下的博文:
https://blog.csdn.net/qq_36743482/article/details/78383964
https://www.imooc.com/article/9265
如果创建外部表就在CREATE后面加上external 就可以。
我们来通过完整的方式来创建我们的表t2
CREATE TABLE IF NOT EXISTS t2(id int,name string,age int)
COMMENT 'xx'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE ;
表建完之后,之前我们用的是insert into的方式,但是只是为了熟悉Hive,知道Hive提供了类Sql的查询语言,但是在加载数据到Hive表的用法中,并不常用,因为数据量实在庞大,我们不可能一条一条的插入,所以使用的如下的两种方式:
$hive>load data local inpath '/home/zpx/customers.txt' into table t2 ; //local上传文件
$hive>load data inpath '/user/zpx/customers.txt' [overwrite] into table t2 ; //分布式文件系统上移动文件
其中第一种是在将本地的文件上传到我们建好的表t2,第二种是将Hadoop的分布式文件系统HDFS上的文件移动到t2,为什么是移动呢,因为我们使用的是管理表,并不是外部表,也就说明了在删除管理表的时候,数据也跟着删除。
customers.txt:
1,zpx,22
2,zpx1,22
3,zpx2,23
4,zpx3,24
5,zpx4,25
6,zpx5,26
注意看,文件直接被保存到了我们建好的表t2中,并且是.txt文件,因为我们在建表的过程中,已经声明了按照文件的格式保存,并且字段之间按照逗号分割,而且还声明了行分隔符,这样,Hive就按照我们的声明,解析我们load的文件,存储到表的各个字段中。也就是使我们可以用类似于SQL的查询语言HQL来进行操作数据,简单,方便。说白了,我们就可以不使用MapReduce,而使用Hive来操作数据(大多数工程师,用户都熟悉SQL)。
在大数据时代,如果我们把所有的数据都如上所示存放在表中,那我们在查询的过程中可能要面临巨大的时间消耗。比如:想查询最新的的一条日志记录,那我们要查询大量的数据,花费非常大的时间才能获取的到。有没有比较好的方法,能快速的定位到我们所需的数据呢?Hive提供了几种方式,其中比较重要的是分区表,桶表。
2.建分区表
数据分区的一般概念存在已久。其中可以有多种形式,但是通常的使用分区来水平分散压力,将数据从物理上转移到和使用最频繁的用户更近的地方,以及实现其他目的。Hive中有分区表的概念。我们可以看到分区表具有重要的性能,而且分区表还可以将数据以一种符合逻辑的方式进行组织,比如分层存储。Hive的分区表,是把数据放在满足条件的分区目录下,例如:2018年的日志,放在year=2018的分区目录下,2017年的日志放在year=2017的分区目录下,这样我们在查找数据的时候只要:selece * from logs where year=2018就直接能够查到复合条件的数据,不用去查全部的数据获取满足条件的了。为我们节省了大量的时间成本。
语法如下:
CREATE TABLE t3(id int,name string,age int)
PARTITIONED BY (Year INT, Month INT) //按照年月进行分区
ROW FORMAT DELIMITED //行分隔符
FIELDS TERMINATED BY ',' ; //字段分隔符,这里使用的是逗号可以根据自己的需要自行进行修改
//显式表的分区信息
$hive>SHOW PARTITIONS t3;
//添加分区,创建目录
$hive>alter table t3 add partition (year=2014, month=12);
我们创建了一个分区表并且添加了一个分区,那分区表是在哪里了,结构是什么样子呢?我们来查看一下:
注意看,分区表依然是存储在Hadoop的分布式文件系统HDFS上的目录(具体为什么存放的是在这个目录,以及为什么Hive创建完数据库,表之后会在这个目录下,上一篇已经讨论过)。可以看到分区表依然是一个目录。
加载数据到分区表:
//再创建一个分区
hive>alter table t3 add partition (year=2014, month=11);
//加载数据到分区表(使用的是本地文件上传的方式)
hive>load data local inpath '/home/zpx/customers.txt' into table t3 partition(year=2014,month=11);
//查询分区表(查询的是当前分区表下的所有分区)
hive>select * from t3;
//查询分区表某个固定分区
hive>select * from t3 where year=2014 and month =11;
我们看到在查询的时候,多了两个字段,分别是year=2014,month=11,在创建表的时候我们没有创建这两个字段啊,那是因为Hive自动的帮我们把分区字段映射成了表字段。我们不需要在创建分区表的时候把PARTITIONED BY (Year INT, Month INT)中的字段再添加到CREATE TABLE t3(id int,name string,age int) 里面去了。这样的查询,就不用扫描所有的数据了,只要扫描我们需要的分区下的数据就行了,速度快,时间成本低。分区表,是Hive优化手段之一,从目录的层面控制搜索数据的范围。
3.建桶表
Hive中的桶表有点像Java中HashMap,将数据散列到不同的地方(俗话中说的桶),这样做,在查找数据的时候就可以跨越多个桶,直接查找复合条件的数据了。速度快,时间成本低。Hive中的桶表默认使用的机制也是hash。
//创建桶表
$hive>CREATE TABLE t4(id int,name string,age int)
CLUSTERED BY (id) INTO 3 BUCKETS //创建3个通桶表,按照字段id进行分桶
ROW FORMAT DELIMITED //行分隔符
FIELDS TERMINATED BY ',' ; //字段分隔符
//加载数据不会进行分桶操作(注意:load的这种方式,数据不会进行分桶,是一个完整的数据文件)
$hive>load data local inpath '/home/centos/customers.txt' into table t4 ;
//查询t3表数据插入到t4中。
$hive>insert into t4 select id,name,age from t3 ;
我们在来查看一下分桶表的在分布式文件系统HDFS上的结构,看是什么,是目录还是文件呢?
注意看,是3个文件,而不是目录,这一点是与分区表的结构是不同的,一定要区分开来
//查询分桶表(直接定位到id=2所在的那个桶,不需要查找所有的桶,过滤掉了剩下的桶里的数据)
hive>select * from t4 where id =2;
4.Hive建视图
与Mysql一样,Hive也可以建立视图,是一张虚表,方便我们进行操作
//创建视图
$hive>create view v1 as select a.id aid,a.name ,b.id bid , b.order from customers a left outer join default.tt b on a.id = b.cid ;
//查看视图
$hive>show tables ;
$hive>select * from v1 ;
也可以在Mysql的hive数据库tbls中查看元数据,具体在上篇介绍过