Hive是由Facebook开发的构建在Hadoop之上的数据仓库平台。
它自己并不存储和处理数据,依赖于HDFS存储数据,依赖MR处理数据。而hive提供了一个相似sql的查询语言HiveQL来进行查询、变换数据等操做。固然HiveQL语句的底层是转换为相应的mapreduce代码进行执行,通常采用批处理的方式对海量数据进行处理。
设计目标就是将hadoop上的数据能够执行SQL操做。
让熟悉SQL编程的开发人员可以轻松的向Hadoop平台上转移。
数据仓库存储的是静态数据,很适合采用MR进行批处理。Hive还提供了一系列对数据进行提取、转换、加载的工具,能够存储、查询和分析存储在HDFS上的数据。html
是分布式的关系型数据库。主要用来并行分布式处理大量数据。hive中的全部查询除了select * from table;
都是须要经过MapReduce的方式来执行的。
因为要走MapReduce(8088mr监控端口号),即便一个只有1行1列的表,若是不是经过select * from table;方式来查询的,可能也须要八、9秒。
但hive比较擅长处理大量数据。当要处理的数据不少,而且Hadoop集群有足够的规模,这时就能体现出它的优点。mysql
一、查询语言
因为 SQL 被普遍的应用在数据仓库中,所以,专门针对 Hive 的特性设计了类 SQL 的查询语言 HQL。熟悉 SQL 开发的开发者能够很方便的使用 Hive 进行开发。
二、数据存储位置
hive的数据都是存储在 HDFS 中的。而mysql数据库则能够将数据保存在本地文件系统中。
三、数据格式
hive 中没有定义专门的数据格式,数据格式能够由用户指定,用户定义数据格式须要指定三个属性:列分隔符(一般为空格、”t”、”x001″)、行分隔符(”n”)以及读取文件数据的方法(Hive 中默认有三个文件格式 TextFile,SequenceFile 以及 RCFile)。因为在加载数据的过程当中,不须要从用户数据格式到 Hive 定义的数据格式的转换,所以,Hive 在加载的过程当中不会对数据自己进行任何修改,而只是将数据内容复制或者移动到相应的 HDFS 目录中。
而在数据库中,不一样的数据库有不一样的存储引擎,定义了本身的数据格式。全部数据都会按照必定的组织存储,所以,数据库加载数据的过程会比较耗时。
四、数据更新
因为 hive 是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。所以,hive 中不支持对数据的改写(hive(0.14) 后支持)和添加
,全部的数据都是在加载的时候中肯定好的。而数据库中的数据一般是须要常常进行修改的,所以能够添加、修改数据。sql
五、索引
由于hive 在加载数据的过程当中不会对数据进行任何处理,甚至不会对数据进行扫描,所以也没有对数据中的某些 Key 创建索引。hive 要访问数据中知足条件的特定值时,须要暴力扫描整个数据,所以访问延迟较高。
不过因为 MapReduce 的引入,hive 能够并行访问数据,所以即便没有索引,对于大数据量的访问,hive 仍然能够体现出优点。
数据库中,一般会针对一个或者几个列创建索引,所以对于少许的特定条件的数据的访问,数据库能够有很高的效率,较低的延迟。因为数据的访问延迟较高,决定了 hive 不适合在线数据查询
。shell
六、执行
hive 中大多数查询的执行是经过 Hadoop 提供的 MapReduce 来实现的(相似 select * from tbl 的查询不须要 MapReduce)。
而数据库一般有本身的执行引擎。数据库
七、执行延迟
以前提到hive 在查询数据的时候,因为没有索引,须要扫描整个表,所以延迟较高。另外 一个致使 hive 执行延迟高的因素是 MapReduce 框架。因为 MapReduce 自己具备较高的延迟,所以在利用 MapReduce 执行 hive 查询时,也会有较高的延迟。
相对的,数据库的执行延迟较低。固然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,hive 的并行计算显然能体现出优点。编程
八、可扩展性
因为 hive 是创建在 Hadoop 之上的,所以 Hive 的可扩展性是和 Hadoop 的可扩展性是 一致的。
而数据库因为 ACID 语义的严格限制,扩展行很是有限。目前最早进的并行数据库 Oracle 在理论上的扩展能力也只有 100 台左右。数组
九、数据规模
因为 Hive 创建在集群上并能够利用 MapReduce 进行并行计算,所以能够支持很大规模的数据.
数据库能够支持的数据规模较小。网络
数据库是面向事务的设计,数据仓库是面向主题设计的。
数据库通常存储在线交易数据,数据仓库存储的通常是历史数据。
数据库设计是尽可能避免冗余,通常采用符合范式的规则来设计,数据仓库在设计是有意引入冗余,采用反范式的方式来设计。
数据库是为捕获数据而设计,数据仓库是为分析数据、用于支持管理决策而设计,它的两个基本的元素是维表和事实表。(维是看问题的角度,好比时间,部门,维表放的就是这些东西的定义,事实表里放着要查询的数据,同时有维的ID)app
一、hive是分布式的关系型数据库,而hbase是分布式的非关系型的。
二、hive是面向行存储的数据库,而hbase是面向列的数据库。
三、hive支持类sql语言,经过数据库的方式来操做hdfs文件系统,为了简化编程,底层计算方式为mapreduce。而hbase的Shell命令是以JRuby为核心编写的,不支持sql。
四、hive自己不存储和计算数据,它彻底依赖于HDFS和MapReduce,hive中的表纯逻辑;而hbase是为查询而生的,它经过组织起节点內全部机器的內存,提供一個超大的內存Hash表,是物理表。
五、hive是高延迟、结构化和面向分析的经常使用于离线分析业务,hbase是低延迟、非结构化和面向编程的,经常使用于在线业务。
6.hive能够认为是map-reduce的一个包装。hive的意义就是把好写的hive的sql转换为复杂难写的map-reduce程序。而hbase能够认为是hdfs的一个包装。他的本质是数据存储,是个NoSql数据库;hbase部署于hdfs之上,而且克服了hdfs在随机读写方面的缺点。框架
含CLI、client、WebUI、JDBC、Thrift Server等,用来实现对Hive的访问。
CLI是Hive自带的命令行界面hive shell;WebUI是Hive的一个简单网页界面经过hive --server hwi
启动后,查看9999端口;JDBC、ODBC以及Thrift Server可向用户提供进行编程的接口,其中Thrift Server是基于Thrift软件框架开发的,提供Hive的RPC通讯接口。
是一个独立的关系型数据库,一般与MySQL数据库链接后建立的一个MySQL实例,也能够是Hive自带的Derby数据库实例。此模块主要保存表模式和其余系统元数据,如表的名称、表的列及其属性、表的分区及其属性、表的属性、表中数据所在位置信息等。
含解析器、编译器、优化器、执行器等,负责把HiveQL语句转换成一系列MR做业,全部命令和查询都会进入驱动模块,经过该模块的解析变异,对计算过程进行优化,而后按照指定的步骤执行。
解析器:将sql字符串转换成抽象语法树AST,通常用第三方工具库如antlr完成。而后对AST进行语法分析,如表是否存在、字段是否存在、sql语义是否有误。
编译器:将AST编译生成逻辑执行计划。
优化器:多逻辑执行计划进行优化;
执行器:把逻辑执行计划转换成能够运行的物理计划,即mapreduce/spark/tez。
有些查询不会走mapreduce,如select * from tbl
http://sishuok.com/forum/blog...
HQL支持基本类型和复杂类型两大类数据类型。
基本类型包括TINYINT(1byte), SMALLINT(2byte), INT(4byte), BIGINT(8byte), FLOAT(4byte), DOUBLE(8byte),DECIMAL(32精度) BOOLEAN(-), STRING(2G)。
复杂类型包括ARRAY(一组有序数组,类型必须一致), MAP(无序键值对,键值内部字段类型必须相同,并且要求key的类型为基本数据类型), STRUCT(一组字段,类型任意)如<a:STRING,B:INT,C:DOUBLE>。
注意是指hql中使用的数据形式,而不是表中序列化存储的格式。
hive 中的文件格式有:
SEQUENCEFILE TEXTFILE -- (Default, depending on hive.default.fileformat configuration) RCFILE -- (Note: Available in Hive 0.6.0 and later) ORC -- (Note: Available in Hive 0.11.0 and later) PARQUET -- (Note: Available in Hive 0.13.0 and later) AVRO -- (Note: Available in Hive 0.14.0 and later) INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
还能够自定经过InputFormat、OutputFormat
采用RCfile的格式读取的数据量(373.94MB)远远小于sequenceFile的读取量(2.59GB)
执行速度前者(68秒)比后者(194秒)快不少。
压缩比:bzip2>gzip>lzo
解压速度:lzo>gzip>bzip2
snappy的执行进度远远高于bz的执行进度。
在hive中使用压缩须要灵活的方式,若是是数据源的话,采用RCFile+bz或RCFile+gz的方式,这样能够很大程度上节省磁盘空间;
而在计算的过程当中,为了避免影响执行的速度,能够浪费一点磁盘空间,建议采用RCFile+snappy的方式,这样能够总体提高hive的执行速度。
至于lzo的方式,也能够在计算过程当中使用,只不过综合考虑(速度和压缩比)仍是考虑snappy适宜。
默认存储在/user/hive/warehouse下,也能够经过location指定,但通常不会指定。
内部表是hive进行管理的,删除表时,会删除表数据以及元数据。
外部表在建立表时能够本身指定目录位置(LOCATION),通常会指定(目录要求先存在)。通常状况下,咱们在建立外部表的时候会将表数据的存储路径定义在hive的数据仓库路径以外。
外部表的数据不是有hive进行管理的,删除表时,只会删除元数据不会删除表数据。
供多个部门使用(包括删除)。
主要做用是查看database、table、function等组件的名称信息,也就是经过show命令咱们能够知道咱们的hive中有那些database;当前database中有那些table。等等。和mysql的show命令类型。show databases ;
数据库show databases like 'db_hive*' ;
show tables ;
show create table 表名;
获得建立该表的语句show partitions 表名 ;
查看表中有多少分区
show functions ;
查看自带函数
主要做用是获取database、table、partition的具体描述信息,包括存储位置、字段类型等信息。desc database db_hive_03 ;
desc database extended db_hive_03 ;
desc student ;
看表结构desc extended student ;
看表完整信息,但比较乱desc formatted student ;
看格式化的信息,经常使用
desc function upper ;
看函数upper的使用说明desc function extended upper ;
看函数的案例演示select id ,upper(name) uname from db_hive.student ;
create database db_hive_01 ;
create database if not exists db_hive_02 ;
标准create database if not exists db_hive_03 location '/user/cyan/hive/warehouse/db_hive_03.db' ;
默认是/user/hive/,没有会自动建立
use db_hive;
当前使用数据库,不然用数据库名.表名
简单如:create table student(id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
制表符分隔各行数据。
复杂一点:
create table IF NOT EXISTS default.log_20150913( ip string COMMENT 'remote ip address' , user string , req_url string COMMENT 'user request url') COMMENT 'BeiFeng Web Access Logs' ROW FORMAT DELIMITED FIELDS TERMINATED BY ' ' STORED AS TEXTFILE ;//以文本文件形式保存,列中的分隔符是空格,行中的分隔符回车 [ROW FORMAT row_format], row_format格式: delimited fields terminated by '\001' collection terminated by '\002' map keys terminated by '\003' lines terminated by '\004' NULL DEFINED AS '\N' [STORED AS file_format] file_format格式: sequencefile textfile(default) rcfile orc parquet avro
create table IF NOT EXISTS default.log_20150913_sa AS select ip,req_url from default.log_20150913 ;
AS sselect来自另一张表(分表),利用其余表的格式like:create table if not exists default.dept_like like default.dept ;
eg:建立员工表
create table IF NOT EXISTS default.emp( empno int, ename string, job string, mgr int,上级 hiredate string,入职时间 sal double, comm double,奖金 deptno int部门 ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
eg:建立部门表
create table IF NOT EXISTS default.dept( deptno int, dname string, loc string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
有时候想把数据细部划分,分各个目录,好比日志文件:
/user/hive/warehouse/log/ /20150911/ 20150911.log /20150912/ 20150912.log
此时建立表时可用partitioned by指定分区依据:
create EXTERNAL table IF NOT EXISTS default.emp_partition( empno int, ename string, job string, mgr int, hiredate string, sal double, comm double, deptno int ) partitioned by (month string,day string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' ;
往分区表导入数据时,须要指定肯定分区的字段值:load data local inpath '/opt/datas/emp.txt' into table default.emp_partition partition (month='201509',day='13') ;
若是建表时指定了数据位置,即加了location '/user/cyan/hive/warehouse/emp_partition';
,则直接把txt数据上传至hdfs的该目录中便可。
从分区表查询数据,也须要指定肯定分区的字段值:select * from emp_partition where month = '201509' and day = '13' ;
除了使用patitioned,还能够手动在表的hdfs目录下建立分区目录达到建分区表的目的:
第一种方式 dfs -mkdir -p /user/hive/warehouse/dept_part/day=20150913 ; dfs -put /opt/datas/dept.txt /user/hive/warehouse/dept_part/day=20150913 ; hive (default)> msck repair table dept_part ;修复后,才能select出数据 第二种方式 dfs -mkdir -p /user/hive/warehouse/dept_part/day=20150914 ; dfs -put /opt/datas/dept.txt /user/hive/warehouse/dept_part/day=20150914 ; alter table dept_part add partition(day='20150914'); show partitions dept_part ; 查看表中有多少分区
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)];
local 本地数据,不加则是hdfs数据
partition (partcol1=val1,...)分区表加载,特殊性,详见分区表的建立。
eg:load data local inpath '/opt/datas/student.txt'into table student ;
加载数据 utf-8格式load data local inpath '/opt/datas/student1.txt' overwrite into table student ;
覆盖原数据,默认是追加
create table default.emp_ci like emp ;
insert into table default.emp_ci select * from default.emp ;
insert overwrite local directory '/opt/datas/hive_exp_emp' select * from default.emp ;
导出数据到本地insert overwrite directory '/user/beifeng/hive/hive_exp_emp' select * from default.emp ;
导出数据到hdfs
insert overwrite local directory '/opt/datas/hive_exp_emp2' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' COLLECTION ITEMS TERMINATED BY '\n' select * from default.emp ;
建立表的时候经过location指定加载数据
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name LIKE existing_table_or_view_name [LOCATION hdfs_path];
将外部数据导入hive表中
create table db_hive.emp like default.emp ; import table db_hive.emp from '/user/beifeng/hive/export/emp_exp';
EXPORT TABLE default.emp TO '/user/beifeng/hive/export/emp_exp' ;
将Hive表中的数据,导出到外部(HDFS)
1.hive shellbin/hive -e "select * from default.emp ;" > /opt/datas/exp_res.txt
2.sqoop
alter table dept_like rename to dept_like_rename ;
改表名
也能够加列名
drop database if exists db_hive_03 ;
非空就不能删drop database db_hive_03 cascade;
非空能删,目录也被删了drop database if exists db_hive_03 ;
清除表里的数据:truncate table db_hive_03 ;
select * from student ;
没有走mapreduceselect id from student ;
走MR
官网LanguageManual中:
[WITH CommonTableExpression (, CommonTableExpression)*] SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list] [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] ] [LIMIT number] select * from emp where GROUP BY LIMIT number
from语句主要是指定从那个数据表中查询数据,有两种使用方式:分别能够在select后和with后&select前使用,语法格式:
[with ...] select ... from ...
[with ...] from ... select ...
示例:select * from students;
from students select *;
hive对子查询的支持有限,只支持嵌套select子句,并且只能在from和with语句块中使用子查询。语法规则以下:.... from (select statement) [[as] tmp_name]....
select * from emp limit 5 ;
select t.empno, t.ename, t.deptno from emp t where t.sal between 800 and 1500 ;
select t.empno, t.ename, t.deptno from emp t where comm is null ;
select count(*) cnt from emp ;
select max(sal) max_sal from emp ;
select sum(sal) from emp ;
select avg(sal) from emp ;
eg:每一个部门的平均工资select t.deptno, avg(t.sal) avg_sal from emp t group by t.deptno ;
eg:每一个部门中每一个岗位的最高薪水select t.deptno, t.job, max(t.sal) avg_sal from emp t group by t.deptno, job ;
eg:每一个部门的平均薪水大于2000的部门select deptno, avg(sal) avg_sal from emp group by deptno having avg_sal > 2000;
=======================================
目前hive不支持in
或not in
中包含查询子句的语法,因此只能经过left join实现。
1.等值jion
join ... onselect e.empno, e.ename, d.deptno, d.dname from emp e join dept d on e.deptno = d.deptno ;
不支持<>等非等值链接方式。
2.左链接
left joinselect e.empno, e.ename, d.deptno, d.dname from emp e left join dept d on e.deptno = d.deptno ;
3.右链接
right joinselect e.empno, e.ename, e.deptno, d.dname from emp e right join dept d on e.deptno = d.deptno ;
4.全链接
full joinselect e.empno, e.ename, e.deptno, d.dname from emp e full join dept d on e.deptno = d.deptno ;
5.半链接(LEFT SEMI JOIN)
是hive特有的,hive中不支持in/exists操做,因此hive提供了一个替代方案。须要注意的是,被链接的表(右表),不能出如今查询列/其余部分(where等)中,只能出如今on字句中(出现也是无效的)。
提出半链接的主要做用实际上是提升查询效率,真正来说的话,hive中可使用其余链接方式来代替半链接,可是就效率而已的话,仍是半链接比较高效。
语法格式:table_reference LEFT SEMI JOIN table_factor join_condition;
6.多表链接
多表链接的时候,通常先进行left semi join,而后再进行join, 再进行外链接。(减小数据量)。
补充:
join过滤条件,能够将where的过滤条件移动到join的过滤条件中去,这样能够减小网络数据量。
join执行顺序都是从左到右,无论是那种join方式,那么通常将大的表放到右边
,这样能够节省内存&减小网络传输。
若是全部被链接的表都是小表,那么可使用mapjoin,将须要链接的表数据所有读入mapper端内存中。也就是说你使用mapjoin的前提就是你的链接数据比较小,mapjoin须要和其余join方式一块儿使用,通常状况下使用mapjoin的时候,推荐使用内链接。语法格式为:select /*+ MAPJOIN(table_ref1) */ ... from table_ref join table_ref1 on ....;
mapjoin只适合链接表是小表的状况,是一种空间换时间的解决方案。
对全局数据的一个排序,仅仅只有1个reduceselect * from emp order by empno desc ;
降序
对每个reduce内部数据进行排序的,全局结果集来讲不是排序
`set mapreduce.job.reduces= 3;
select * from emp sort by empno asc ;
insert overwrite local directory '/opt/datas/sortby-res' select * from emp sort by empno asc ;`
分区partition,相似于MapReduce中分区partition,对数据进行分区,结合sort by进行使用(分区再排序)insert overwrite local directory '/opt/datas/distby-res' select * from emp distribute by deptno sort by empno asc ;
注意事项:distribute by
必需要在sort by
前面。
当distribute by和sort by 字段相同时,可使用cluster by ;insert overwrite local directory '/opt/datas/cluster-res' select * from emp cluster by empno ;
1.应尽可能避免在where 子句中对字段进行null 值判断,不然将致使引擎放弃使用索引而进行全表扫描
2.应尽可能避免在 where 子句中使用!=或<>操做符,不然将引擎放弃使用索引而进行全表扫
3.描应尽可能避免在 where 子句中使用or 来链接条件,不然将致使引擎放弃使用索引而进行全表扫描
4.in 和 not in,用具体的字段列表代替,不要返回用不到的任何字段。in 也要慎用,不然会致使全表扫描
5.避免使用模糊查询
6.任何地方都不要使用select* from t;
dfs -rm -R /user/hive/warehouse/….;
删除dfs -ls / ;
查看hdfs文件系统!ls /opt/datas ;
查看本地文件系统