学习hive
前言:在互联网界,有一群人专门钻研数据库,擅长使用sql语句处理数据,在之前的学习中,我们明确了hdfs在大数据中的地
位,我们处理大数据时,一般使用mapreduce 进行处理,这使得居于数据库的sql语句没有了用武之地,而每次查询hdfs中的
数据,使用mapreduce有比较麻烦,用一句俗话说,懒人推动世界,于是就有了hive
hive
hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
Hive是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
Hive 没有专门的数据格式。 Hive 可以很好的工作在 Thrift 之上,控制分隔符,也允许用户指定数据格式。
hive 储存原理
hive 其实就是对于 hdfs 和 mapreduce 的一个整合,使用简单的sql 的语句,实现比较复杂的mapreduce 的数据筛选
1 我们写入一条sql语句
2 hive 解析 sql 中的关键字
3 将select 等sql 语句优化,形成树结构
4 将 sql 语句编译成逻辑计划
5 将逻辑计划形成相应的物理计划 mapreduce 执行
hive的表
Hive表的类型
hive中有5种表:
- 内部表
数据默认存储在/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;
查看表描述信息:
DESCRIBE [EXTENDED|FORMATTED] table_name
EXTENDED极简的方式显示
FORMATTED格式化方式来显示
DESCRIBE EXTENDED gfstbl;默认就是EXTENDED
DESCRIBE FORMATTED gfstbl;
插入数据的其他方式:
插入数据的方式:
1、insert 新数据
2、load
3、查询其他表数据 insert 到新表中
模板:
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代码的冗余
from day_hour_table
insert into rest
select count(*) ;
- 外部表
数据存储位置由用户自己指定,由HDFS管理,删除外部表时仅仅会删除元数据,存储数据不会受到影响。
建表语句:
create external table wc_external
(word1 STRING,
word2 STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
location '/test/external'; location可加可不加,不加location默认是在hive的工作目录区
- 临时表
在当前会话期间存在,会话结束后自动销毁。
建表语句:
create TEMPORARY table ttabc(id Int,name String) 临时表的声明周期是一次会话
进入hive shell 创建一张表,关闭shell后,表丢失,临时表不支持分区
- 分区表
将数据按照某个字段或者关键字分成多个子目录来存储,防止暴力扫描全表。
静态分区表:
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);
删除Hive分区表中的分区
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"
动态分区表:
动态分区表和静态分区表建表语句相同,插入数据的方式不同
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
动态分区可以根据数据本身的特征自动来划分分区,load data …只是将数据上传到HDFS指定目录,所以我们需要使用from insert的方式插入数据hive才会根据分区设置自动将数据进行分区。
- 分桶表
将数据按照某个字段和桶的数量,对指定字段进行取模运算,拆分成多个小文件来存储,模相同的存储在同一个小文件中,提高join以及抽样的效率。
set hive.enforce.bucketing=true;
分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储
由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中
对于hive中每一个表、分区都可以进一步进行分桶
建表语句
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;
多个分区中的对应的位置的小文件组成一个桶
插入数据:
insert into table psnbucket_partition partition(height) select id, name,
age,height from original;
多个分区中的对应的位置的小文件组成一个桶
hive 的安装
1.上传tar包
2.解压
tar -zxvf hive-1.2.1.tar.gz
3.安装mysql数据库
推荐yum 在线安装(运行脚本安装)
4.配置hive
(a)配置HIVE_HOME环境变量
vi conf/hive-env.sh
配置其中的$hadoop_home
(b)配置元数据库信息
vi hive-site.xml
添加如下内容:
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
<description>password to use against metastore database</description>
</property>
</configuration>
5.安装hive和mysq完成后,将mysql的连接jar包拷贝到$HIVE_HOME/lib目录下
如果出现没有权限的问题,在mysql授权(在安装mysql的机器上执行)
mysql -uroot -p
设置密码
set password=password('root');
#(执行下面的语句 .:所有库下的所有表 %:任何IP地址或主机都可以连接)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
通过mysql -uroot -proot
- Jline包版本不一致的问题,需要拷贝hive的lib目录中jline.2.12.jar的jar包替换掉hadoop中的
6.1、 cp hive/lib/jline-2.12.jar /opt/software/hadoop-2.6.4/share/hadoop/yarn/lib/
6.2、装hive和mysq完成后,将mysql的连接jar包拷贝到$HIVE_HOME/lib目录下