Hadoop学习笔记(三):Hive简介

定义

      Hive是一个构建在Hadoop上的数据仓库框架。可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。(来自百度百科~~)

metastore

      metastore是Hive元数据的集中存放地,metastore包括两部分:服务和后台数据的存储。默认情况下,元数据存储在Derby数据库实例中。由于是本地数据库且不支持并发访问,故多作为练手使用。还一种使用其他数据库的方式称为“Local metastore”,支持并发访问,但metestore服务仍然和hive服务运行在同一个进程中,故称之为本地metastore。还有第三种方式:“Remote metastore”,metastore无武器和hive服务运行在不同的进程内,可以提供更好的可管理性和安全性。(怎么配Local metastore和Remte metastore先不搞了,先拿默认方式练手为主~)

和传统数据库的比较

      最本质的一点,hive依赖于hdfs和MapReduce!

      在传统数据库里,表的模式是在数据加载时强制确定的(写时模式,schema on write),而hive对数据的验证却在查询时进行(读时模式,schema on read);读时模式有利于数据加载,基本上就是纯粹的复制粘贴,且更加灵活,可以以各种不同模式来分析数据。写时模式有利于提升查询性能,因为可以建索引,压缩数据等。

      hive不支持更新,事务和索引。(暂时不支持吧,将来谁也说不准~)hive是用来以MR的方式操作HDFS数据的,在这种环境下,全表扫描(full-table scan)是常态操作,而表更新则是通过吧数据变换后放入新表实现。事务方面hive并没有对表的并发访问做什么处理,需要应用程序端自己在应用层实现。(比如类似spring事务)

HiveQL

      不完全支持SQL-92标准,支持数值型,布尔型,字符串类型等原子类型;数组,映射,结构等复杂类型。

      TINYINT,SMALLINT,INT,BUGINT分别对应于java中的byte,short,int,long。

      FLOAT,DOUBLE直接对应float,double(废话~)

      STRING对应于string,而没有其他数据库中的 varchar,varchar2,char等类型。hive的STRING类似于其他数据库中的VARCHAR,但是不能声明最长字符数,理论上STRING最长为2G。

  数据类型转换:

      任何类型都可以隐式转换为一个范围更广的类型,所有整数类型,float,string(这个有点奇怪)都可以隐式转换为double,tinyint,smallint,int都可以隐式转换为float,double最大,不能隐式转换为任何类型。

      可以使用cast执行显式转换,如果转换失败则返回空值null。

  复杂类型:

      Hive有3中复杂类型:ARRAY,MAP和STRUCT;ARRAY,MAP和java中的类似;struct是一种记录类型,封装了一个命名的字段集合。复杂数据类型允许任意层次的嵌套。

  操作:

      “||” 不是字符串连接操作符,而是 “或”操作符,concat函数用来作为连接操作

  表:

       Hive表格逻辑上由存储的数据和描述表格中数据形式的相关元数据组成。数据存放在hdfs中,元数据(metastore)存放在关系数据库中。

       Hive中的表分为托管表(managed table)和外部表(external table)两种。托管表是默认情况,托管表会将数据移入Hive的仓库目录(warehouse directory);外部表则直接到外部目录访问数据。

       相应的,如果是托管表,LOAD操作将会复制数据到仓库目录,DROP操作将会删除表数据和表的元数据,而外部表则需要在CREATE操作时指定外部数据路径,在DROP操作时,只删除元数据而不碰外部数据。外部表使用EXTERNAL关键字创建。

       普遍的用法是把存放在hdfs中的初始数据集用作外部表使,用Hive转换后的数据存入托管表;反过来——外部表可以用作将托管表中的数据导出到HDFS以供其他应用程序使用。

分区和桶

       分区的好处是对于同一分区内的数据进行查询的时候将会非常高效,比如按年份分区,查某一年的数据只需要到这个分区中检索就行了。分区是在创建表的时候用 PARTITIONED BY 子句定义的。

CREATE TABLE LOGS(ts BEGINT,line STRING)

PARTITIONED BY (dt STRING,country STRING);

       在LOAD数据的时候则需要指定分区值:

       LOAD DATA LOCAL INPUT 'input/hive/partitions/file1'

       INTO TABLE logs

       PARTITION (dt='2001-1-1',country='GB');

 

       在文件系统中,分区只是表目录下嵌套的子目录。如按分区检索数据其实就是按文件系统目录检索数据了。

       SHOW PARTITIONS logs; 命令会返回当前表中所有分区信息。PARTITIONED BY 子句中的列是表中正式的列,称为分区列。但是数据文件并不包含这些列,因为在目录中包含了。可以像普通列一样使用分区列(partition column)。

select ts,dt,line
  from logs
 where country='GB'

 

       桶可以获得更高的查询处理效率;桶可以使取样操作更高效。使用CLUSTERED BY 子句来制定划分桶所用的列和要划分的桶的个数。

create table bucketed_records(year int,temperature STRING,quality STRING,station STRING)
clustered by (year) sorted by (year ASC) into 4 buckets;

 

 insert overwrite table bucketed_records
 select * from records;

        桶对应于MR的输出文件分区:一个作业产生的桶(输出文件)和reduce任务个数相同。由于我本地只有一个伪分布环境,只能一个reduce,所以只得到一个桶,一个桶~

        桶文件中包含在这个桶中的记录信息,划分桶的规则是:Hive对值进行哈希并将结果除以桶的个数取余数,这样任何一个桶里都会有一个随机的用户集合。

        TABLESAMPLE 子句对表进行取样,这个子句会将查询限定在表的一部分桶内,而不是使用整个表:

 select * from bucketed_records
tablesample(bucket 1 out of 4 on year);

 

存储格式

       Hive从两个维度对表的存储进行管理:“行格式”(row format)和“文件格式”(file format)。行格式指行和一行中的字段如何存储,行格式由SerDe定义(Serializer-Deserializer)

       默认格式为分割的文本,每行存储一个数据行。

   二进制存储格式:顺序文件和RCFile

       Hadoop的顺序文件格式是一种针对顺序和记录的通用二进制格式。在Hive中,可以在CREATE TABLE 中通过声明STORED AS SEQUENCEFILE来使用顺序文件。使用顺序文件一个主要的优点是支持可分割的压缩(splittable)。顺序文件时面相行的,这意味着同一行中的字段作为一个顺序文件记录存储在一起。

       RCFile按列记录文件,RCFile把表分成行分片(row split),在每一个分片中先存所有行的第一列,再存第二列,以此类推。通过声明STRED AS RCFILE来使用RCFile存储格式。

       面向行的存储格式对于那些只访问表中一小部分行的查询比较有效;面相列的存储格式适合同事处理一列中很多列的情况。

 

导入数据

       CREATE TABLE ... AS SELECT

       INSERT OVERWRITE TABLE 

       LOAD DATA

       三种格式,load data 和 insert overwrite table 上面都有示例了,ctas练手一个吧,还有插入partition的示例,多表插入

create table test_records(year int,temperature STRING,quality STRING,station STRING)
as select * from records;
insert overwrite table target
partition (dt='xxx')
select col1,col2
  from source;
insert overwrite table target
partition (dt)
select col1,col2,dt
from source;
from souce
insert overwrite table table1
select col1,col2
insert voerwrite table tablw2
select col3,col4 ...;

CTAS操作是原子的,如果SELECT查询由于某种原因失败,是不会创建新表的。

表的操作

   该语句可以将更新元数据并且将表目录移动到新名称所对应的目录下:
alter table source rename to target;
   添加一个新列:
alter table target add columns (col3 string);

      drop表就跟其他sql一致了, 如果是外部表,则只删除元数据,外部数据不会受到影响。


查询数据

   排序和聚集:

      Hive的Order By子句对数据进行排序,但是Order By是通过只用一个Reducer来做到这一点的。对于大规模的数据集,效率非常低下。

      在很多情况下,并不需要结果是全局排序。此时,可以使用Hive的非标准的扩展SORT BY。

        SORT BY:为每个reducer产生一个排序文件;

        DISTRIBUTE BY X:确保X列相同的数据在同一个reduce分区中;

select year,temperature from records
distribute by year
sort by temperature desc;

   内连接:

      Hive 不支持 where sales.id=things.id  这样的连接操作!

select * from sales.*,things.*

from sales join things on (sales.id = things.id);

   

   三种外连接:(左外,右外,全外)

select * from sales.*.things.*

from sales left outer jion things on (sales.id=things.id);

select * from sales.*.things.*

from sales right outer jion things on (sales.id=things.id);

select * from sales.*.things.*

from sales full outer jion things on (sales.id=things.id);

    半连接:

        Hive不支持IN操作,但是可以使用left semi join 达到相同的效果:(sales表不能再select 后面出现,感觉类似exist了)

select * from things left semi join sales on (sales.id=things.id);

    指定map连接:

       如果有一个连接表小到足以放入内存,Hive就可以把较小的表放入每个mapper的内存来执行连接操作。在Hive中需要使用注释来指定map连接:

select /*+  MAPJOIN(things) */ sales.*,things.*

from sales join things on (sales.id=things.id);

 

    子查询:

        Hive只支持子查询出现在From子句中

select col1,col2

from (select * from records where ... ) a

 

    视图:貌似和其他数据库中视图没啥区别,只是保存元数据,而不执行查询,不物化数据。

    使用外部脚本:

        使用Hadoop Streaming,TRANSFORM,MAP,REDUCE子句可以在Hive中调用外部脚本

ADD FILE /test.py;

SELECT TRANSFORM(COL1,COL2,COL3)

FROM TABLE

USING 'test.py'

AS COL1,COL2;

--TRANSFORM(COL1,COL2,COL3) 表示查询本身将把col1,col2,col3作为以制表符分割的行的形式流式传递给脚本test.py

 

 FROM (

    FROM table

      MAP col1,col2,col3

      USING 'testmap.py'

      AS col1,col2) map_output

REDUCE col1,col2

USING 'testreduce.py' AS col1,col2;

 

用户自定义函数 (user-defined function,UDF)

      Hive有三种UDF:普通UDF,用户定义聚集函数UDAF,用户定义表生成函数UDTF。

            UDF用户操作单个数据行,产生一个数据行作为输出,就像普通函数返回一个返回值;

            UDAF接受多个输入数据行,产生一个输出数据行,聚集函数好像都如此;

            UDTF作用于单个数据行,产生多个数据行(一个表)作为输出。

     (不想写了~ 这几个鸟函数决定使用到了再来研究了!!!)OVER

 

时间: 2024-08-01 08:35:49

Hadoop学习笔记(三):Hive简介的相关文章

hadoop学习笔记--10.hive安装与配置

一.hive安装 1.环境要求 1. Java 1.7或以上 2. Hadoop 2.x (preferred), 1.x (not supported by Hive 2.0.0 onward). 2.安装配置 Hive没有才有hadoop.HBase或者是Zookeeper的主从架构,所以只用在所需要的机器上安装即可. 1. 解压 tar -zxvf apache-hive-0.13.1-bin.tar.gz 把解压的文件夹移到自己需要的存放的目录. 2. 配置环境 sudo vi /etc

Hadoop学习笔记之:Hadoop的两个部分

本文大部分内容都是从官网Hadoop上来的.其中有一篇介绍HDFS的pdf文档,里面对Hadoop介绍的比较全面了.我的这一个系列的Hadoop学习笔记也是从这里一步一步进行下来的,同时又参考了网上的很多文章,对学习Hadoop中遇到的问题进行了归纳总结. 言归正传,先说一下Hadoop的来龙去脉.谈到Hadoop就不得不提到Lucene和Nutch.首先,Lucene并不是一个应用程序,而是提供了一个纯Java的高性能全文索引引擎工具包,它可以方便的嵌入到各种实际应用中实现全文搜索/索引功能.

VSTO学习笔记(三) 开发Office 2010 64位COM加载项

原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(Automation Executables) 2.Office加载项(COM or Excel Add-In) 3.Office文档代码或模板(Code Behind an Office Document or Template) 4.Office 智能标签(Smart Tags) 本次我们将学习使

Hadoop学习笔记一 简要介绍

这里先大致介绍一下Hadoop. 本文大部分内容都是从官网Hadoop上来的.其中有一篇介绍HDFS的pdf文档,里面对Hadoop介绍的比较全面了.我的这一个系列的Hadoop学习笔记也是从这里一步一步进行下来的,同时又参考了网上的很多文章,对学习Hadoop中遇到的问题进行了归纳总结. 言归正传,先说一下Hadoop的来龙去脉.谈到Hadoop就不得不提到Lucene和Nutch.首先,Lucene并不是一个应用程序,而是提供了一个纯Java的高性能全文索引引擎工具包,它可以方便的嵌入到各种

kvm虚拟化学习笔记(三)之windows kvm虚拟机安装

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1290191 KVM虚拟化学习笔记系列文章列表 ---------------------------------------- kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51cto.com/703525/1288795 kvm虚拟化学习笔记(二)之linux kvm虚拟机安装 h

Bootstrap3学习笔记(三)之表格_javascript技巧

在上篇文章给大家介绍了 BootStrap3学习笔记(一)之网格系统       Bootstrap3学习笔记(二)之排版 只需要在table标签上使用.table类,就可以使用bootstrap默认的表格样式 如果需要行背景有交替变化,可以这样设定: 复制代码 代码如下: <table class="table table-striped"> 如果需要边框,可以这样设定: 复制代码 代码如下: <table class="table table-borde

JavaScript学习笔记(三):JavaScript也有入口Main函数_javascript技巧

在C和Java中,都有一个程序的入口函数或方法,即main函数或main方法.而在JavaScript中,程序是从JS源文件的头部开始运行的.但是某种意义上,我们仍然可以虚构出一个main函数来作为程序的起点,这样一来不仅可以跟其他语言统一了,而且说不定你会对JS有更深的理解. 1. 实际的入口 当把一个JavaScript文件交给JS引擎执行时,JS引擎就是从上到下逐条执行每条语句的,直到执行完所有代码. 2. 作用域链.全局作用域和全局对象 我们知道,JS中的每个函数在执行时都会产生一个新的

DB2 UDB V8.1管理学习笔记(三)_DB2

正在看的db2教程是:DB2 UDB V8.1管理学习笔记(三).强制断开已有连接,停止实例并删除.  $ db2idrop -f instance_name 用于在UNIX下迁移实例. $ db2imigr instance_name 更新实例,用于实例获得一些新的产品选项或修订包的访问权. $ db2iupdt instance_name 获取当前所处的实例. $ db2 get instance 当更新实例级别或数据库级别的参数后,有些可以立即生效,有些需要重新启动实例才可生效.immed

Hadoop学习笔记二 安装部署

硬件环境 共有3台机器,均使用的FC5系统,Java使用的是jdk1.6.0.IP配置如下: dbrg-1:202.197.18.72 dbrg-2:202.197.18.73 dbrg-3:202.197.18.74 这里有一点需要强调的就是,务必要确保每台机器的主机名和IP地址之间能正确解析. 一个很简单的测试办法就是ping一下主机名,比如在dbrg-1上ping dbrg-2,如果能ping通就OK!若不能正确解析,可以修改/etc/hosts文件,如果该台机器作Namenode用,则需

Hadoop学习笔记(一):MapReduce的输入格式

    Hadoop学习有一段时间了,但是缺乏练手的项目,老是学了又忘.想想该整理一个学习笔记啥的,这年头打字比写字方便.果断开博客,咩哈哈~~     开场白结束(木有文艺细胞)     默认的MapReduce作业 import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.Path; import org.apache.h