Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。
Hive是建立在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 HQL,它允许熟悉 SQL 的用户查询数据。同时,这个语言也允许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 无法完成的复杂的分析工作。
其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
内部表和外部表的结构、创建方式与数据库中的表类似, 但是内部表与外部表还是有所区别的:在导入数据到外部表,数据并没有移动到自己的数据仓库目录下(如果指定了location的话),也就是说外部表中的数据并不是由它自己来管理的!而内部表则不一样;在删除内部表的时候,Hive将会把属于表的元数据和数据全部删掉;而删除外部表的时候,Hive仅仅删除外部表的元数据,数据是不会删除的!在创建内部表或外部表时加上location 的效果是一样的,只不过表目录的位置不同而已,加上partition用法也一样,只不过表目录下会有分区目录而已,load data local inpath直接把本地文件系统的数据上传到hdfs上,有location上传到location指定的位置上,没有的话上传到hive默认配置的数据仓库中。
相比之下外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。
内部表的创建方式:
1)CREATE TABLE TableA (id INT, ……);
2)CREATE TABLE TableB like TableA ;只是创建表结构
3)CREATE TABLE TableB AS SELECT id,…… FROM TableA; 会创建相应的表结构,并且插入数据
内部表的插入数据:
1)INSERT 新数据:INSERT INTO TABLE TableA (id, ……) VALUES (INT, ……)
2)LOAD 方式:LOAD DATA LOCAL INPATH ‘文件路径’ INTO TABLE TableA;
3)查询其他表数据 INSERT 到新表中:
INSERT INTO TABLE TableB [PARTITION (partcol1=val1, partcol2=val2 …)] SELECT statement1 FROM TableA;
外部表的创建方式:
1)CREATE EXTERNAL TABLE TableA (id INT, ……);
临时表只对当前会话有效,会话关闭后,表自动删除。如果创建的临时表表名已存在,那么当前会话引用到该表名时实际用的是临时表,只有drop或rename临时表才能使用原始表。
不支持分区字段和创建索引
临时表的创建方式:
1)CREATE TEMPORARY TABLE TableA …
为什么需要分区表:首先可以防止暴力扫描全表,其次可以提高查询效率;
静态单分区表:
1)CREATE TABLE TableA (id INT, ……) PARTITIONED BY (dt String)ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’;
加载数据:
1)INSERT 单条插入的方式往分区表中插入数据:
INSERT INTO TableA PARTITION (dt = “9-26”) VALUES (1,“anb”);
2)LOAD 批量插入的方式往分区表中插入数据:
LOAD DATA LOCAL INPATH “/root/ceshi” INTO TABLE TableA PARTITION (dt=“9-27”);
删除Hive分区表中的分区:
ALTER TABLE TableA DROP PARTITION (dt=“9-27”);
静态多分区表:
1)CREATE TABLE TableA (id INT, content String) PARTITIONED BY (dt INT,hour INT) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’ ;
加载数据:
1)INSERT单条插入的方式往分区表中插入数据:
INSERT INTO TableA PARTITION (dt=9,hour=1) VALUES (1,“a2 bc”);
INSERT INTO TableA PARTITION (dt=9,hour=2) VALUES (3,“a2 bc”);
INSERT INTO TableA PARTITION (dt=8,hour=1) VALUES (3,“a2 bc”);
INSERT INTO TableA PARTITION (dt=8,hour=2) VALUES (3,“a2 bc”);
2)LOAD批量插入的方式往分区表中插入数据:
LOAD DATA LOCAL INPATH “/root/ceshi” INTO TABLE TableA PARTITION (dt=10,hour=10);
删除Hive分区表中的分区
ALTER TABLE day_table DROP PARTITION (dt=10,hour=10);
静态分区表一个文件数据只能导入到某一个分区中,并且分区是用户指定的,这种方式不够灵活,业务场景比较局限;
动态分区与静态分区创建表的语句是一模一样的
采用 FROM INSERT的方式插入数据
FROM TableA
INSERT INTO TableB PARTITION(sex,age)
SELECT id,……;
查看分区数
SHOW PARTITIONS TableB ;
分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储。由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。对于hive中每一个表、分区都可以进一步进行分桶
原始表:
CREATE TABLE Original( id INT, ……) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
加载数据至原始表中:
LOAD DATA LOCAL INPATH “/root/bucketData” INTO TableA;
分桶表:
CREATE TABLE TableA( id INT, ……)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
插入数据:
INSERT INTO TableA PSNBUCKET SELECT id, …… FROM Original;
每一个小文件对应一个桶
抽样:
SELECT * FROM PSNBUCKET TableA (bucket 1 out of 4 on age);
分桶表+分区表:
CREATE TABLE TableB ( id INT, ……)
PARTITIONED BY(height DOUBLE)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’;
插入数据:
INSERT INTO TABLE TableB PARTITION(height) SELECT id,…… FROM Original;
多个分区中的对应的位置的小文件组成一个桶
抽样:
SELECT * FROM PSNBUCKET TableB (bucket 1 out of 4 on age);
可以将一条SQL(数据表)与视图对应映射,每次查询这个视图就是执行了SQL语句;
视图不支持物化视图,只能查询,不能做加载数据操作 load data into。视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询。view定义中若包含了ORDER BY/LIMIT语句,当查询视图时也进行ORDER BY/LIMIT语句操作,view当中定义的优先级更高。view支持迭代视图。一旦创建成功,无法修改。
创建视图语句:
CREATE VIEW IF NOT EXISTS view1 AS SELECT * FROM TableA ORDER BY id;
创建视图的时候不会启动MR任务,但是在查询视图的时候会启动MR任务,因为视图的创建,只是保存一份元数据,查询视图时才执行对应的子查询。
索引类似目录,用于优化查询性能,若使用SELECT * FROM TABLE WHERE id = 10;假设这个表的数据非常大,那么查询的性能会很低。
创建索引库,用于存放索引
CREATE INDEX IndexA ON TABLE psnbucket_partition(age)
AS ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’ with deferred rebuild
in table t2_index_table;
索引库中只是保存一些元数据,比如 对哪个字段创建索引,对哪个表创建索引等
ALERT index IndexA ON psnbucket_partition REBUILD;
这一步是真正的创建索引信息,并且存储到索引库中,若数据库有新增数据,也可以使用以上语句重建索引
查询索引:
SHOW INDEX ON psnbucket_partition;
删除索引
DROP INDEX IndexA ON psnbucket_partition;
删除索引的同时 索引库也会被删除
这种方式是最简单的存储方式,只需要在hive-site.xml做如下配置便可
将hive/lib目录下的jline jar包拷贝到hadoop的yarn lib下
注:使用derby存储方式时,运行hive会在当前目录生成一个derby文件和一个metastore_db目录。这种存储方式的弊端是在同一个目录下同时只能有一个hive客户端能使用数据库,否则会提示如下错误
[html] view plaincopyprint?
hive> show tables;
FAILED: Error in metadata: javax.jdo.JDOFatalDataStoreException: Failed to start database ‘metastore_db’, see the next exception for details.
NestedThrowables:
java.sql.SQLException: Failed to start database ‘metastore_db’, see the next exception for details.
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask
hive> show tables;
FAILED: Error in metadata: javax.jdo.JDOFatalDataStoreException: Failed to start database ‘metastore_db’, see the next exception for details.
NestedThrowables:
java.sql.SQLException: Failed to start database ‘metastore_db’, see the next exception for details.
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask
这种存储方式需要在本地运行一个mysql服务器,并作如下配置(下面两种使用mysql的方式,需要将mysql的jar包拷贝到$HIVE_HOME/lib目录下)。
注意一个坑:权限,虽然hive用户对hive_meta数据库是由操作权限的,但是这个数据库如果不存在,hive用户也是没有权限创建这个数据库,所以需要提前创建好hive_remote数据库
附:
安装mysql
Yum install mysql-server -y
修改mysql权限:
GRANT ALL PRIVILEGES ON . TO ‘root’@’%’ IDENTIFIED BY ‘123’ WITH GRANT OPTION;
flush privileges;
删除多余会对权限造成影响的数据
刷新权限
添加用户:
CREATE USER ‘hive’@’%’ IDENTIFIED BY ‘123’;
授权用户:
grant all privileges on hive_meta.* to hive@"%" identified by ‘123’;
flush privileges;
设置开机启动
chkconfig mysqld on
[ERROR] Terminal initialization failed; falling back to unsupported
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected
at jline.TerminalFactory.create(TerminalFactory.java:101)
错误的原因: Hadoop jline版本和hive的jline不一致
拷贝
Remote分开,将hive-site.xml配置文件拆为如下两部分
1)服务端配置文件
2)客户端配置文件
启动hive服务端程序:hive --service metastore
客户端直接使用hive命令即可
root@my188:~$ hive
Hive history file=/tmp/root/hive_job_log_root_201301301416_955801255.txt
hive> show tables;
OK
test_hive
Time taken: 0.736 seconds
hive>
客户端启动的时候要注意:
[ERROR] Terminal initialization failed; falling back to unsupported
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected
at jline.TerminalFactory.create(TerminalFactory.java:101)
错误的原因: Hadoop jline版本和hive的jline不一致