配色: 字号:
part6-hive
2018-06-23 | 阅:  转:  |  分享 
  
HiveHiveHive可以说是HiveQL(SQL)到MapReduce的映射器。从hive执行过程所打印的日志可以发现该条HiveQL
被转化为一个Mapreduce作业执行。并不是所有HQL都会转化为MapReduce任务:Hive>selectfromt
est;这种HQL是不会被hive转化为MapReduce作业执行的,Hive只会将该表所分布在各个DataNode的数据拉到Hi
ve所在节点并一次输出。HiveQL是mapreduce的一个封装Hive架构hive并不是分布式的,它独立于集群之外,可以看做是
一个Hadoop的客户端。访问hive有三种方式:1CLI(命令行模式),HWI(Hive网络界面),ThriftServer(
jdbc/odbc)Driver用来编译,优化、执行sql语句。HiveQL执行本质是mapreduce程序的执行,hive通过与
Yarn通信来初始化mapReduce作业。所以hive并不需要部署在Yarn节点,通常在大型的生产环境集群,hive被独立部署在
集群之外的节点。Metastore是hive的元数据的集群中存放地。Mestastore包括两部分:元数据服务和元数据存储。hiv
e将hdfs上的结构化数据通过元数据映射为一张张表。Metastore的3种安装方式:内嵌模式:元数据库使用的是hive自带的De
rby。缺点:仅支持同时一个用户访问hive。特点:Hive服务与元数据服务位于同一个jvm线程中。本地模式:元数据库使用的是
mysql。缺点:支持同时多个用户访问hive。特点:Hive服务与元数据服务位于同一个jvm线程中。远程模式:特点:hive
服务与元数据服务不在一个进程中。(8)hive不支持事务(OLTP联机事务处理),而支持的是OLAP联机分析处理。但并不支持联机
,所以Hive更适合使用离线计算,对于实时性要求很高的可以选择HBase或Impala。hive与关系型数据库的区别存储位置:h
ive的元数据存储在mysql上,真实数据存储在hdfs。这是因为hive是基于hadoop的。而关系型数据库则是将数据保存在块设
备或者本地文件系统中。数据格式:hive可以自己指定分割符,而关系型数据库则按照一定组织存储。执行:hive中大多数查询的执行是通
过Hadoop提供的MapReduce计算框架来实现锝。而关系型数据库通常有自己的执行引擎。执行延迟:1hive中没有索引因,因
此需要进行全表扫描。这样就会延迟2hive的底层是mr,因为mr的中间数据需要磁盘落地,因此hive也会延迟。可扩展性:关系型数
据库也可以有分布式,目前最先进的Oracle并行数据库在理论上的扩展能力也只有100台左右。而hive是基于Hadoop的,因此H
ive的扩展性Hadoop的扩展性一致。hive的命令行hive-e‘selectfromstudent’;可
以不再hive的命令行界面执行,而直接在linux普通界面执行,仅执行一条语句。hive-S-e‘selectcou
nt()fromtest’;可以省略日志打印。hive-ftest.hql;我们将多条语句写入以hql结
尾的文件中,由该语句来执行。上述三个语句中都执行在普通linux界面上,不用进入hive命令界面。hive的基本数据类型Hive也
是由java编写,所以Hive的基本数据类型都是对java中的接口的实现,这些基本数据类型与java的基本数据类型是一一对应的,如
SMALLINT类型对应java中short类型。复杂数据类型在hive中支持3中复杂的数据类型(集合数据类型):array、m
ap、struct。实际上是调用3个内置函数。Array每个数组元素都有一个编号,编号从0开始。可以通过数组名[元素位置]
应用相应元素StudentArray使用:Student[0]表示student数组中的第一个元素Map可
以通过字段名[‘键’],获取相对应的值DeductionMap(num.100)Dedecution
[num]STRUCT可以通过字段名.属性名来获取相应属性值。AddressSTRUCTe:Int>Address.city表示city的值关于数据库标准格式的优缺点背景:例如在传统数据模型中,struct可能需要
由多个不同的表拼接而成,表间需要适当地使用外键来进行连接。如AddressSTRUCT:Int>其中address是Struct类型。这要是在关系型数据库中,addrss字段会单独在一个表中,而city,tele会
单独在一个表中。然后通过外键与主键的链接进行两张表的关联。(这是关系型数据表设计原则:三大范式规定的。)而在不具有严格的数据标准格
式的hive中,一个struct数据类型就可以将多个表统一实现。需要注意在hive中是没有主外键的概念的。说明:我们从关系型数据库
和非关系型数据库的角度来说明这个问题。大多数的关系型数据库是不支持这些集合数据类型,因为这些数据类型破坏了标准格式。不适用标准格式
的缺点:若破坏了标准格式,会增大数据冗余的风险,进而导致消耗不必要的磁盘空间,还有可能造成数据不一致,因为当数据发生改变时,冗余的
拷贝数据可能无法进行相应的同步。不使用标准格式的优点:在大数据系统中,不遵循标准格式的好处就是可以提供更高吞吐量(输入输出)的数据
,按数据集(如struct)进行封装的话可以通过减少寻址次数来提供查询速度,而如果根据外键关系关联的话则需要进行磁盘见的寻址操作,
这样会有非常高的性能消耗。hive的存储格式Hive支持的文件存储格式有以下几种,并通过Storedas来指定文件的存储格式:
Textfile:就是我们通常所说的文本,是hive默认的存储格式,数据不做压缩,磁盘开销大,数据解析开销大。Sequencef
ile:是hadoop提供的一种二进制格式,具有使用方便、可分割、可压缩的特点。并且安行进行分割。RCfile:是一种行列存储形结
合的存储方式。将数据按行分块,保证同一条记录在一个块上,避免读一条记录需要读取多个块。块上的数据按照列式存储,有利于数据压缩和和快
速的进行列存取。(4)Parquet:按列存储hive的数据格式提到文本文件应该想到常见的两种文件形式:CSV(逗号分隔),TSV
(制表符分隔)在实际应用中,往往对有些分隔符不需要进行分割,但我们在hive中指定了,要按这些符号进行分割。这时候我们就要小心了。
本篇暂时先不考虑这个问题。1)hive建表的完整语句注意:对于hive来说在创建表的时候,我们可以指定分割方式,也可以不指定分割
方式,如直接createtablestudent(nameString,ageInt);这也是可以的。在我们不指定分割方
式的情况下,hive是有默认的处理数据的形式的。在不指定分割方式的情况下,hive默认如下:hive默认列的分割符为按^A。对应的
八进制为\001hive默认集合、数组、键值对的分割符为按^B.对应的八进制为\002hive默认键与值的分割符为^C,对应的八进
制为\003hive默认行分割符为\n且hive仅支持这一种行分割符(这也是为什么我们一般在写建表语句时,不用特意写lines
terminatedby‘\n’同时需要知道按行分割的作用就是告知hive,这一行结束了,在该行按列分割出的字段值可以作为表
的字段值了)hive默认的文件存储格式为Textfile,由于键值对只能用在text文件中,因此我们常使用这个值,同样一般我们不去
写他。注:LinesTerminatedby‘\n’与storedastextfile这两个语句不用与Rowf
ormatdelimited连用,而fieldterminatedby、collectionitemstermina
tedby、mapkeysterminatedby就必须跟Rowformatdelimited使用使用默认分割的文
件实例如下:2)hive中默认的记录和分割符注意:区分键值对之间的分割符与键和值之间的分割符。hive中的数据库Hive中的数据库
本质是一个文件夹,hive中的表是数据库文件目录中的一个个文件夹,hive中的数据是表目录中的文件。对于分区表:存在的形式是一张表
文件夹中包含多个分区,每个分区也是一个目录。对于分桶表:存在的形式是一张表文件目录中包含多个数据文件,多个数据文件就是所谓的多个分
桶,即是对分区的进一步细化。hive数据库的基本操作:创建数据库myhiveCreatedatabasesifnot
existsmyhive;关于是否需要写ifnotexists,是根据需求决定的。一般如果不写,若该数据库之前存在,则会
报错。有些人是需要看到这样的提示的。但对于实时创建数据库的项目来说,使用ifnotexists语句十分有必要。展示数据库
showdatabases;(3)使用正则表达式筛选数据库Showdatabaseslike‘my.’筛选出
名字中头两个字母为my,其他字母任意的数据库(4)使用数据库(本质实现数据库的转换)Usemyhive;修改创建的数
据库的位置createdatabasemyhivelocation‘/my’;上述语句中将所创建的myhive数
据库存放到hdfs://my目录中,需要注意的是通过这种方式改变路径后,数据库myhive目录并不会为我们创建,而是将之后在myh
ive中所创建的表目录都直接放到my中。还需要知道在hive中有一个默认的数据库default,hive对这个目录并没有创建de
fault目录,使用default时,同样所创建的表文件都放在了默认的路径目录中。对于hive的默认存储路径是通过:hive.m
etastore.warehouse.dir这个变量在hive-site.xml文件中配置的,我们配置的是hdfs://user/
hive/warehouse。因此一般在我们不更改存储路径的时候,所创建的数据库都会放到hdfs上的/user/hive/ware
house/数据库名查看数据库路径信息Describedatabasemyhive;展示当前所使用的数据库hive>set
hive.cli.print.current.db=true;该命令用于开启当前数据库显示hive>sethive.cli.
print.current.db=false;该命令用于关闭当前数据库显示删除数据库Dropdatabaseifexis
tsmyhive;hive删除数据库是要求数据库中没有任何文件夹级目录的。因此要想删除该数据库,需要我们先将该数据库清空,然后
再删除。或是通过下面的语句强制删除:Dropdatabaseifexistsmyhivecascade修改数据库的属性
alterdatabasemyhivesetdbproperties(‘edited-by’=’xiaoming’)数据库
的属性或表的属性指的就是创建数据库的人和创建数据库的时间的信息。这个属性需要写成键值对的形式。11、数据定义创建表建表语句Crea
tetableifnotexistsmyhive.student()这个建表语句的优点当前我们即使并不在
myhive数据库中,我们也不用切换到myhive数据库中去建表,只需要通过上面的myhive.student就可以在myhiv
e数据库中创建student表。表的注释Comment‘employeesalary’我们可以给表进行注释,也可以给列进
行注释添加属性Tabproperties(‘creator’=’me’,’created_at’=’2012-01--02’)主要
是按键值对的形式为表增加额外的文档说明。展示表的属性Showtabpropertiesmyhive;表的拷贝Createt
ableifnotexistsmyhive.student2likemyhive.student拷贝表student生
成新表student2,但数据并没有拷贝。表的展示Showtablesinmyhive;即使不在myhive数据库下,也
能通过上述命令展示myhive数据库中的表(7)正则表达式展示表showtables''st.'';由上可知目前1.2.1版本的
hive还不支持in和正则表达式一起使用。(8)描述表的结构(三种方式)Descmyhive.studentDescribe
extendedmyhive.studentDescirbeformattedmyhive.student(9)展示表中某
个列的详细信息(包含相关的列的注释)Describestudent.sno其中student是表,sno是该表中的列。内部表
和外部表的差别若删除内部表,则元数据和存储在hdfs上的真实数据都将被删除。若删除外部表则仅会删除元数据,而不会删除存储在hdfs
上的真实数据。内部表语与外部表在语法上有些不同。外部表用于共享数据。主要是因为:当我们使用loaddatainpath‘/h
ive/xx’intotablestudent向hive表中添加数据后,原来hdfs的/hive/xx路径中的数据就会被剪
切到studenthive表中,也就是说在执行完导入数据后,数据源的数据就消失了。在工作中若使用的是内部表,那么一不小心将该内部
表删除,则会将唯一存储在hive表中的数据也给删除了。这样就很危险。若我们使用外部表,即使删除了该外部表,那么hive表中的真实数
据也不会被删除。注意loaddatalocalinpath‘/hive/xx’intotablestudent
语句在执行的时候,会将本地数据源复制给hive表。Hive的设计本身是用来管理hdfs的相关的目录和文件,但其实并没有完全的控制权
限,因为我们可以通过hdfs相关的shell命令将hive目录中的库,表,数据都进行改动,删除。loaddatainpath
‘/hive/xx’intotablestudent是将hdfs上的数据移动(剪切)到hive中loaddatal
ocalinpath‘/hive/xx’intotablestudent是复制本地数据到hive中外部表的创建关于内部
表与外部表的表复制Createexternaltablestudent1likestudent2注:其中stu
dent2是源表,student1是复制出来的表。则无论student2是内部表还是外部表,复制出来的student1表都是外部
表若我们将external关键子去掉,则:Createtablestudnet1likestudent2若student2
表是内部表则student1是内部表;若student2表示外部表则student是外部表;分区表分区表定义分区的字段不能和定义
表的字段重合若分区包含两个字段,则这两个字段所对应的目录是子目录与父目录的关系对应altertablestudentadd
partition(province=’sichuan’)partition(city=’chengdu’)分区的优点:如果
没有分区,hive将不得不进行全表扫描,hive没有索引,但分区类似于索引的效果。常见的式按照时间或者式修改时间进行分区。在查询h
ive数据时,由于数据量较大,分区多,因此我们不能全查,为了避免失误。我们需要将hive的模式设置为strict模式(hive默认
为strict);具体有两种设置方法:1通过修改hive-site.xml文件的hive.mapred.mode配置项为st
rict.(永久有效)2在hive命令行中:hive>Sethive.mapred.mode=strict;(仅当次有
效)分区表的创建静态分区与动态分区(1)基本概念动态分区:只需指定分区字段,无需指定分区字段的具体值;系统会根据分区字段的不同值
对应的去创建相应的分区,也就是说指定的分区字段有多少不同值,系统就会创建多少个分区。静态分区:不仅需要指定分区字段,还要指定分区字
段的具体值,partition(sex=’boy’)即,分区字段为sex,而其分区值为boy。(2)具体使用:静态分区:动态分区:
Creattablestudent_ptn(xxx)patitionedby(departmentString)row
formatdelematedfiledterminalby“,”注:在动态分区的过程中就没有写altertabl
exxxaddpartition(xx=vvv)因为系统自己判定了。Sethive.exec.dynamic.part
ition=true开启动态分区模式Sethive.exec.dynamic.partition.mode=str
ict设置动态分区模式为strict模式在该模式下,当插入数据时,我们在分区字段中必须加入一个静态分区,上面的age就属于一
个静态分区。系统默认状态为strict。若是nonstrict状态,则只需指定动态分区即可如:Insertintotable
studnet_ptnpartition(department)selectid,name,departmentfrom
student;动态分区表中要求当用insertinto.......select...方式向动态分区表中导入数据时,分区字
段若在select语句中存现,则必须位于select查询部分的最后面(Hive会根据select语句中的最后一个查询字段作为动态分
区的依据,如果指定了n个动态分区字段,hive会将select语句中的最后n个字段作为动态分区的依据)。修改表Altertab
leAltertable仅仅改变表的元数据,而不改变真实数据。表的重命名Altertablestudentrename
topeople增加表的分区Altertablestudnetaddpartition(sex=”boy”)删除分
区Altertablestudentdroppartition(sex=”boy”)修改列信息(列名,列类型,列注释,列位
置)其中columniduidint表示:将原有的id名改为uid名,并将其数据类型改为int。改名的同时必须将数据类
型进行更改,即是与元数据类型相同,那么也得重写。Comment‘thisisadog’更改原来的列注释Afternam
e将原来的id列移动到name列的后面。增加列Altertablestudentaddcolumn(ageint,a
ddString);替换列Altertablestudentreplacecolumn(addstring,tele
int);12数据操作数据操作:数据导入hive,和数据导出hive装载数据:hdfs上数据装载普通表Loaddatai
npath‘/hive/wc’intotablestudentHdfs上数据覆盖装载普通表Loaddatainpath
‘/hive/wc’overwriteintotablestudent本地文件装载到hive上Loaddatal
ocalinpath‘/hive/wc’intotablestudent装载到分区表中Loaddatainpat
h’/hive/wc’intotablestudentpatition(sex=“男”);必须指定分区值通过查询语句向表
中插入数据向普通表中插入数据Insertoverwritetabletestselectfromsource;向
分区表中插入数据Insertoverwritetabletest1patition(part=’a’)selectf
romsource通过一次查询产生多个不相交的输出FromsourceInsertoverwritetabletest
partition(part=‘a’)Selectid,namewhereid>=0andid<100Inser
toverwritetabletestpartition(part=’b’)Selectid,namewhere
id>=100andid<200Insertoverwritetabletestpartition(part=’c’)
Selectid,namewhereid>=200andid<300;这样只通过对source表的一次查询,就将符合
条件的数据插入test表的各个分区。利用动态分区向表中插入数据Insertintotablestudentpartiti
on(age)selectname,agefromstu;这样系统会自动根据age不同值所对应的分区进行数据的插入。导出
数据将hive中的数据导入到hdfs上会本地上。导出到hdfs上:Insertoverwritedirectory‘/use
r/hadoop/r’selectfromstudent;导出到本地上:Insertoverwritelocal
directory‘/home/hadoop/apps’selectfromstudent;通过CTAS加载数据在一
条语句中创建表并加载数据。Createtabletestasselectfromstudent数据查询select
...from语句Hive支持在select语句中使用case...when...then的形式Selectid,N
ame,sex,casewhensex=’M’then‘男’Whensex=’F’then‘女’Else‘无效
数据’ENDFromstudent;或Selectid,name,sex,casesexwhen‘M’then
‘男’When‘F’then‘女’Else‘无效数据’EndFromstudent;(2)wheregro
upby和having语句Groupby通常和聚合函数一起使用,聚合函数也称为分组函数。Hive与oracle的语法规则
相似。聚合函数要想作为sql语句的条件使用,则必须放在having后,即聚合函数若想作为查询条件则只能作为groupby的条件来使
用。Selectnamefromstudentgroupbynamehavingavg(age)=12;在or
acle中聚合函数不能和普通字段共同出现在select后面如selectname,avg(age)fromstudent
这个在oracle就是错的,在hive中也是错的而在mysql中则是对的。在oracle和hive中的groupby后面的字段可以
与聚合函数一起放到select后面selectage,count()fromstudentgroupbyage
;Join目前hive仅支持等值链接例如:表1id列表2id列12342356内连接:selectt1.id
,t2.idfromtable1t1jointable2t2ont1.id=t2.id;左外连:结果集中
会包含左表中的全部记录,而右表的不符合链接条件的记录则用null表示selectt1.id,t2.idfromtable1t1leftouterjointable2t2ont1.id=t2.id右外链:结果集中会包含右表中的全部记录,而左表的不符合链接条件的记录则用null表示Selectt1.id,t2.idfromtable1t1rightouterjointable2t2ont1.id=t2.id全外链接:Selectt1.id,t2.idfromtable1t1fullouterjointable2t2ont1.id=t2.id左半链接:类似于内连接,只是仅仅将左边的记录显示出来。(左半内连)注:在左半链接的时候,select只能查询左半部分,不能查询右半部分Selectt1.idfromtable1t1leftsemijointable2t2ont1.id=t2.id多表join(4)orderby和sortbyOrderby是全局排序、sortby是局部排序。当reducer的个数为1时,两者没有区别。若有2个或2个以上的reducer则。就体现了区别。当reduce的个数为2时:原id列Orderby(全局排序)Sortby(局部排序)173921112379111711239(5)distributeby和clusterbyDistributeby表示仅分桶,clusterby即分桶又局部排序。Clusterby等效于distributeby+sortby分桶hive中分桶等效于mr中的分区。
献花(0)
+1
(本文系实习生101首藏)