Hive概述
- Hive简介:
Hive是一种构建数据仓库的工具。
Hive内部也是有表的概念,Hive把数据存储到HDFS上。
它的元数据存到了本地的轻量级的Derby数据库中。元数据包括行的分隔符、字段分隔符、字段的类型、字段的名称。
Hive依赖于HDFS和MapReduce,可以看成是分布式的大表。也可以使用SQL语句处理数据。 - Hive原理:
1.客户端传一条SQL语句给Hive(Hive支持所有的SQL语句)
2.Hive对SQL进行解析,优化,策略选择器,消耗模型,把一个个的SQL解析成一个个MapReduce。(解析器,编译器,优化器)
3.MR处理HDFS上的数据。
Hive提供了thrift server服务,用户可以通过JDBC连接thrift server服务,thrift server连接Hive工具,然后将在客户端写好的SQL语句传给Hive
Hive还提供了metastore服务,metaStore,默认存储在 derby 数据库中,但是derby数据库不能支持我们开启多个窗口,所以我们会将metaStore存放到MySql中; - Hive表的类型:
1.内部表
数据默认存储在/user/hive/warehouse,由hive自身管理,删除内部表会同时删除存储数据和元数据。
建表语句:
①
create table t1(
id INT,
name STRING,
age INT,
gfs ARRAY<STRING>,
address MAP<STRING,STRING>,
info STRUCT<country:String,province:String,shi:String> )
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n'
LOCATION "/test";//可以设置源数据的位置,若不设置默认就在Hive的工作目录区
②
create table gfstbl1 like gfstbl;//只是创建表结构
③
create table gfstbl2 AS SELECT id,name,gfs,address from gfstbl; //会创建相应的表结构,并且插入数据,相当于完整的赋值
加载数据:
load data local inpath '/root/gfs.txt' into table gfstbl;
插入数据的其他方式:
①
INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)]
select_statement1 FROM from_statement;
②
FROM from_statement
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)
[IF NOT EXISTS]] select_statement1
③
insert into rest select count(*) from table;
注:from提前 可以减少SQL代码的冗余
2.外部表
数据存储位置由用户自己指定,由HDFS管理,删除外部表时仅仅会删除元数据,存储数据不会受到影响。
建表语句:
create external table wc_external (
word1 STRING,
word2 STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ' '
location '/test/external'; //location可加可不加,不加location默认是在hive的工作目录区
3.临时表
在当前会话期间存在,会话结束后自动销毁。
建表语句:
create TEMPORARY table ttabc(id Int,name String) //临时表的生命周期是一次会话
//进入hive shell 创建一张表,关闭shell后,表丢失,临时表不支持分区
4.分区表
将数据按照某个字段或者关键字分成多个子目录来存储,防止暴力扫描全表。
静态分区表:
create table day_hour_table (id int, content string) partitioned by (dt int,hour int)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
加载数据:
-- insert单条插入的方式往分区表中插入数据:
insert into day_hour_table partition(dt=9,hour=1) values(1,"a2 bc");
insert into day_hour_table partition(dt=9,hour=2) values(3,"a2 bc");
insert into day_hour_table partition(dt=8,hour=1) values(3,"a2 bc");
insert into day_hour_table partition(dt=8,hour=2) values(3,"a2 bc");
-- load批量插入的方式往分区表中插入数据:
load data local inpath "/root/ceshi" into table day_table partition (dt=10,hour=10);
删除分区:
ALTER TABLE day_table DROP PARTITION (dt=10,hour=10);
创建\添加分区:
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location']
[, PARTITION partition_spec [LOCATION 'location'], ...];
partition_spec: : (partition_column = partition_col_value, partition_column = partition_col_value, ...)
-- 创建一个空分区:
ALTER TABLE day_hour_table ADD PARTITION (dt=10000, hour=2000);
-- 然后将数据上传到空分区对应的目录下,分区表中就会显示数据 HDFS dfs -put ........
-- 创建一个空分区并且将空分区指向数据位置:
ALTER TABLE day_hour_table ADD PARTITION (dt=10000, hour=2000) location "/test"
动态分区表:
动态分区表和静态分区表建表语句相同,插入数据的方式不同,动态分区可以根据数据本身的特征自动来划分分区,load data …只是将数据上传到HDFS指定目录,所以我们需要使用from insert的方式插入数据hive才会根据分区设置自动将数据进行分区。
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
分桶表:
将数据按照某个字段和桶的数量,对指定字段进行取模运算,拆分成多个小文件来存储,模相同的存储在同一个小文件中,提高join以及抽样的效率。分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储,由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中,对于hive中每一个表、分区都可以进一步进行分桶。
//set hive.enforce.bucketing=true;
CREATE TABLE psnbucket( id INT, name STRING, age INT)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
插入数据:
insert into table psnbucket select id, name, age from original;
抽样:
select * from psnbucket tablesample(bucket 1 out of 4 on age);
分桶表+分区表:
CREATE TABLE psnbucket_partition(
id INT,
name STRING,
age INT)
PARTITIONED BY(height DOUBLE)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
插入数据:
insert into table psnbucket_partition partition(height) select id, name,
age,height from original;
注:多个分区中的对应的位置的小文件组成一个桶