学习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种表:

  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;

查看表描述信息:

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(*) ;
  1. 外部表
    数据存储位置由用户自己指定,由HDFS管理,删除外部表时仅仅会删除元数据,存储数据不会受到影响。

建表语句:

create external table wc_external 
   (word1 STRING, 
   word2 STRING) 
   ROW FORMAT DELIMITED 
   FIELDS TERMINATED BY ' ' 
   location '/test/external'; location可加可不加,不加location默认是在hive的工作目录区
  1. 临时表
    在当前会话期间存在,会话结束后自动销毁。

建表语句:

create TEMPORARY table ttabc(id Int,name String) 临时表的声明周期是一次会话

进入hive shell 创建一张表,关闭shell后,表丢失,临时表不支持分区

  1. 分区表
    将数据按照某个字段或者关键字分成多个子目录来存储,防止暴力扫描全表。

静态分区表:

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才会根据分区设置自动将数据进行分区。

  1. 分桶表
    将数据按照某个字段和桶的数量,对指定字段进行取模运算,拆分成多个小文件来存储,模相同的存储在同一个小文件中,提高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
  1. 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目录下