Hive基础学习

Stella981
• 阅读 767

本节我们主要来学习一些hive的命令操作,同时探究一下Hive,HDFS,MySQL之间的联系,从而更好的理解其内部原理。

常用的基础命令
#此处的命令都是指在hive命令行下执行的命令,所有的命令别忘记以分号结尾。hive> show databases;#查看当前数据库列表hive> create databases dbname;#创建一个名称为dbname的数据库hive> use databasename;#将当前的数据库切换为databasenamehive> show tables;#查看当前数据库中有哪些表hive> desc tbname;#查看表结构,包括字段类型,注释等
Hive的数据类型

Hive基础学习

hive基本数据类型

Hive基础学习

hive集合数据类型

注:图片来自《hive编程指南》
这里先简单了解一下Hive的数据类型,本节我们暂时不会用到太多很复杂的类型。
建表

假设我们现在建立一张student表,它有两个字段,id(int)name(string)

hive> create database learn;#创建数据库learnhive> use learn;#切换到learn数据库hive> create table student(id int, name string);#创建表studenthive> show create table student;#查看建表语句

Hive基础学习

创建表,查看建表语句

我们通过show create table student;命令查看student表建立时一些详细信息。关注一下LOCATION的值为:hdfs://localhost:8020/user/hive/warehouse/learn.db/student,猜测这是一个HDFS的文件路径,我们通过浏览器验证一下:

Hive基础学习

在浏览器中查看student表的location

可以看到,我们建立的student表是HDFS上的一个目录(文件夹),目录的位置就是LOCATION对的值。

将本地文件加载到Hive表

本地文件:当前目录下的student.txt,字段之间用空格分割,

1 zhangsan2 lisi3 wangwu

hive> load data local inpath 'student.txt' into table student;

Hive基础学习

加载本地数据

加载成功之后,我们先来看一下HDFS中student目录,如下图所示,可以看到该目录下出现了一个student文件。

Hive基础学习

查看HDFS中student目录

然后用hive命令查询一下student表。

hive> select * from student;OKNULL    NULLNULL    NULLNULL    NULLTime taken: 0.139 seconds, Fetched: 3 row(s)

可以看到结果虽然是有三行,但全部否是null。如果执行select count(*) from student;也能输出结果为3。

Hive基础学习

查询student表的行数

出现这种情况是,我们建表时没有指定数据列之间的分隔符,hive默认的字段分隔符是\001,即ASCII码的第一个字符Control-A,而我们的文件的分隔符是空格,二者不一致是导致数据不能正确加载的原因。

接下来我们创建一个新的表并指定分隔符为\t,即tab符,然后重新加载以\t分割的本地文件。

hive> create table teacher(id int, name string) row format delimited fields terminated by '\t';#创建teacher表并指定行分隔符为'\t'hive> load data local inpath 'teacher.txt' into table teacher;#实际运行加了overwrite,表示覆盖表中已有的数据,如果不加overwrite就会在已有的数据后直接添加。

Hive基础学习

加载tab符分割的数据

创建teacher表同样在HDFS中建立了相应的目录,load数据同样也将本地的数据加载到了相应的目录中。

Hive基础学习

HDFS中查看teacher目录

将HDFS文件加载到Hive表

我们按照以下的步骤进行操作:

①在本地建立course.txt文件,写入三行内容,字段之间用空格分割。

1    语文2    数学3    体育

②将course.txt上传到HDFS中并检查是否上传成功。

③在hive中建立course表,指定分隔符为tab符

④执行load data inpath '/course.txt' into table course命令,加载HDFS数据到course表中。

⑤查询course表中的数据,验证是否成功加载

⑥查看HDFS中是否依然存在course.txt文件。

Hive基础学习

Hive基础学习

Hive基础学习

从执行的结果我们可以看出,从HDFS中加载数据时,是将HDFS中的文件直接移动到了表对应的HDFS目录中(内部表)。

理解Hive的元数据

Hive环境搭建的时候我们使用MySQL存储了Hive元数据,并且在初始化时生成了很多mysql数据表。那么它们有什么作用呢?我们来看一下TBLS,COLUMNS_V2,SDS三个表的信息,很容易联系到我们前面创建的表。

mysql> use metastore;#切换到我们之前创建的元数据库。mysql> show tables;+---------------------------+| Tables_in_metastore       |+---------------------------+| BUCKETING_COLS            || CDS                       || COLUMNS_V2                || COMPACTION_QUEUE          || COMPLETED_TXN_COMPONENTS  || DATABASE_PARAMS           || DBS                       || DB_PRIVS                  || DELEGATION_TOKENS         || FUNCS                     || FUNC_RU                   || GLOBAL_PRIVS              || HIVE_LOCKS                || IDXS                      || INDEX_PARAMS              || MASTER_KEYS               || NEXT_COMPACTION_QUEUE_ID  || NEXT_LOCK_ID              || NEXT_TXN_ID               || NOTIFICATION_LOG          || NOTIFICATION_SEQUENCE     || NUCLEUS_TABLES            || PARTITIONS                || PARTITION_EVENTS          || PARTITION_KEYS            || PARTITION_KEY_VALS        || PARTITION_PARAMS          || PART_COL_PRIVS            || PART_COL_STATS            || PART_PRIVS                || ROLES                     || ROLE_MAP                  || SDS                       || SD_PARAMS                 || SEQUENCE_TABLE            || SERDES                    || SERDE_PARAMS              || SKEWED_COL_NAMES          || SKEWED_COL_VALUE_LOC_MAP  || SKEWED_STRING_LIST        || SKEWED_STRING_LIST_VALUES || SKEWED_VALUES             || SORT_COLS                 || TABLE_PARAMS              || TAB_COL_STATS             || TBLS                      || TBL_COL_PRIVS             || TBL_PRIVS                 || TXNS                      || TXN_COMPONENTS            || TYPES                     || TYPE_FIELDS               || VERSION                   |+---------------------------+53 rows in set (0.00 sec)

mysql> select * from TBLS;#存放我们已经建立的表,具体字段如图所示mysql> select * from COLUMNS_V2;#存放表的字段,CD_ID是外键mysql> select * from SDS;#存放表的LOCATION和格式信息

Hive基础学习

Hive基础学习

Hive基础学习

注:这个表横向太长了。因此截成了两段,凑合看。感兴趣的可以自己动手试试。

Hive基础学习

TBS存放的是我们已经创建的表,COLUMNS_V2存放了标的字段信息,SDS存放了表的LOCATION和格式信息。其他表的信息我们也可以通过看里面的内容理解其作用请读者自行了解

其他命令

查看某个表的基本信息:

hive> desc student;#查看表的字段及其类型OKid                      intname                    stringTime taken: 0.069 seconds, Fetched: 2 row(s)hive> desc formatted student;#查看表的详细信息,包括字段,位置,类型,存储信息等OK# col_name                data_type               commentid                      intname                    string# Detailed Table InformationDatabase:               learnOwner:                  chenghengchaoCreateTime:             Sat Jun 08 00:31:45 CST 2019LastAccessTime:         UNKNOWNProtect Mode:           NoneRetention:              0Location:               hdfs://localhost:8020/user/hive/warehouse/learn.db/studentTable Type:             MANAGED_TABLETable Parameters:    COLUMN_STATS_ACCURATE   true    numFiles                1    numRows                 0    rawDataSize             0    totalSize               27    transient_lastDdlTime   1559973358# Storage InformationSerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDeInputFormat:            org.apache.hadoop.mapred.TextInputFormatOutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormatCompressed:             NoNum Buckets:            -1Bucket Columns:         []Sort Columns:           []Storage Desc Params:    serialization.format    1Time taken: 0.059 seconds, Fetched: 32 row(s)

在hive命令下直接操作HDFS:

# 在hive下直接操作HDFS,建立data文件夹并上传本地文件到HDFS,命名为a.txt 和b.txthive> dfs -mkdir /data;hive> dfs -put student.txt /data/a.txt;hive> dfs -put student.txt /data/b.txt;

Hive基础学习

表的类型有两种MANAGED_TABLE和EXTERNAL_TABLE。

hive内部表和外部表的区别
       1)创建表时:创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变。
       2)删除表时:在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据

reference:https://blog.csdn.net/u010886217/article/details/83796151

reference:https://www.jianshu.com/p/ac2eca9181be

reference:https://blog.csdn.net/qq\_36743482/article/details/78393678

#创建外部表并指向已有的data目录,如果指定的location不存在则会创建。hive> create external table ext_student(id bigint,name string) row format delimited fields terminated by '\t' location '/data';OKTime taken: 0.064 secondshive> select * from ext_student;OK1   zhangsan2   lisi3   wangwu1   zhangsan2   lisi3   wangwuTime taken: 0.034 seconds, Fetched: 6 row(s)

查询结果显示了6条记录,前3条和后3条是一样的。这是因为/data 下面有两个文件a.txt 和b.txt,每个文件有3行有数据。如果再上传一次teacher文件到/data目录下。在看ext_student中的数据

hive> dfs -put teacher.txt /data/c.txt;hive> select * from ext_student;OK1    zhangsan2    lisi3    wangwu1    zhangsan2    lisi3    wangwu1    赵老师2    王老师3    刘老师4    邓老师Time taken: 0.032 seconds, Fetched: 10 row(s)

可见,指定的location,即/data目录下的三个文件的数据都被加载到了ext_student中。事实上,无论是外部表还是内部表,只要把某个文件放到表的目录下,就会被扫描并被查询出来。查询的执行过程是先通过TBLS表找到student表,然后根据表id到COLUMNS_V2表查找这张表都有哪些字段,然后再根据表id到SDS表中查找应该到HDFS的那个目录下去查找数据。

Hive分区表
hive> create external table players(id bigint,name string) partitioned by (nation string) row format delimited fields terminated by '\t' location '/players';#执行后会在HDFS上创建/players目录,这是一个以nation分区的表OKTime taken: 0.095 secondshive> dfs -put china.txt /players;#将本地的china.txt上传到HDFS的players目录下hive> select * from players;#查询players表,发现结果是空的,但如果从浏览器中查看players牡蛎,发现文件china.txt存在。OKTime taken: 0.041 seconds

查询没有数据的原因,是没有上传文件到指定分区。我们换一种方式。

hive> load data local inpath 'china.txt' into table players partition(nation='China');Loading data to table learn.players partition (nation=China)Partition learn.players{nation=China} stats: [numFiles=1, numRows=0, totalSize=38, rawDataSize=0]OKTime taken: 0.242 secondshive> select * from players;OK1    zhangjike   China2    yijianlian  China3    subingtian  ChinaTime taken: 0.045 seconds, Fetched: 3 row(s)

Hive基础学习

我们上传文件时指定分区,就能查询出结果。此时在HDFS上出现了一个nation=China的目录,china.txt被上传到了改该目录下。

我们试一下手动创建nation=USA目录,并将usa.txt上传到该目录。再查询players

hive> dfs -mkdir /players/nation=USA;hive> dfs -put usa.txt /players/nation=USA;hive> select * from players;OK1    zhangjike   China2    yijianlian  China3    subingtian  ChinaTime taken: 0.042 seconds, Fetched: 3 row(s)

查询的结果没有USA分区的数据,但从浏览器中查看确实已经存在了/players/nation=USA/usa.txt,并且usa.txt是有数据的。这是因为元数据库中没有记录USA这个分区。(看SDS表的话,只有nation=China的记录)。但如果此时使用load命令加载数据,则可以创建nation=USA的分区。在SDS表中也会出现nation=USA。

hive> load data local inpath 'usa.txt' into table players partition(nation='USA');Loading data to table learn.players partition (nation=USA)Partition learn.players{nation=USA} stats: [numFiles=2, numRows=0, totalSize=50, rawDataSize=0]OKhive> select * from players;OK1    zhangjike   China2    yijianlian  China3    subingtian  China1    Curry   USA2    Phelps  USA3    Woods   USA1    Curry   USA2    Phelps  USA3    Woods   USATime taken: 0.037 seconds, Fetched: 9 row(s)

查询的结果中出现了USA分区,但是有重复。这是因为nation=USA目录下有两个相同内容的文件。原因是通过load命令将目录“变”为分区的同时,也加载了相同的一份数据。我们也可以看出:分区一定是一个目录,但目录不一定是分区。而且如果删除了分区,文件夹可以继续存在,如果删除了文件夹,分区也继续存在。

Hive基础学习

我们也可以通过另一种方式修改(增加)分区,如下面命令所示。如果直接运行该命令,会在HDFS上创建目录nation=Other。如果我们先用mkdir创建nation=Other目录,再使用该命令,也可以将目录“变”为分区,此时目录下的文件就会被加载到表中,读者可以自行验证。

hive> alter table players add partition(nation='Other') location '/players/nation=Other';

再总结一下查看和删除分区的命令。

hive> show partitions players;#查看分区OKnation=Chinanation=Othernation=USATime taken: 0.047 seconds, Fetched: 3 row(s)hive> alter table players drop if exists partition (nation='Other');#删除某个分区Dropped the partition nation=OtherOKTime taken: 0.068 seconds

使用了分区之后,最大的好处是能提高查询的速度,同时也对数据进行了更细粒度的划分。可以使用where关键字限制分区。

hive> select * from players where nation = 'China';OK1    zhangjike   China2    yijianlian  China3    subingtian  ChinaTime taken: 0.074 seconds, Fetched: 3 row(s)hive> select * from players where nation = 'USA';OK1    Curry   USA2    Phelps  USA3    Woods   USA1    Curry   USA2    Phelps  USA3    Woods   USATime taken: 0.047 seconds, Fetched: 6 row(s)
总结

本文我们对Hive的一些基础知识进行了学习,包括查看数据库,查看表的基本命令,如何建表并加载数据,hive元数据的存储位置,hive分区表与HDFS的关系等。通过学习我们对Hive底层原理有了更为深刻的认识。

Hive基础学习

Hive基础学习

以清净心看世界;

用欢喜心过生活。

超哥的杂货铺,你值得拥有~

长按二维码关注我们

推荐阅读:

Hadoop基础知识总结

MAC OS搭建Hadoop伪分布式集群

分布式资源调度框架YARN

MacOS 下hive的安装与配置

本文分享自微信公众号 - 超哥的杂货铺(gh_a624b94bfdab)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这