Hive编程指南学习笔记(2)

我们可以使用describe extended financial.employee命令来查看这个表的详细表结构信息(如果当前所处的工作数据库就是financial,那可以不佳finanacial)。

如果使用formatted替代关键字extended的话,那可以得到更多的输出信息。

如果用户只想查看某一列的信息,那么只要在表名后增加这个字段的名称即可。这种情况下,使用extended关键字也不会增加更多的输出信息:

hive> describe financial.employee.salary
salary float employee salary

外部表

下面的语句将创建一个外部表,其可以读取所有位于/data/stocks目录下的以逗号分隔的数据:

create external table if not exists stocks (
exchange  string,
symbol string,
ymd    string,
price_open     float,
price_high     float,
price_low      float,
price_close    float,
volume    int,
price_adj_close     float
)
row format delimited fields terminated by ','
location '/data/stocks';

关键字external告诉hive这个表是外部的,而后面的location子句则用于告诉hive数据位于哪个路径下。

因为表是外部的,所以hive并非认为其完全拥有这份数据。因此,删除该表并不会删除掉这份素和据,不过描述表的元数据信息会被删除掉。

管理表和外部表有一些小小的区别,那就是,有些HiveQL语法结构并不适用于外部表。

用户可以在describe extended tablename语句中的输出中查看到表是否是管理表或外部表。在末尾的详细表信息输出中,对于管理表,用户可以看到如下信息:

... tableType:MANAGED_TABLE)

对于外部表,用户可以查看到如下信息:

... tableType:EXTERNAL_TABLE)

对于管理表,用户还可以对一张存在的表进行表结构复制(而不会复制数据):

create external table if not exists financial.employee1
like financial.employee
location '/path/data'

如果上面的语句省略掉external关键字而且源表是外部表,那么生成的新表也是外部表。如果语句中省略掉external关键字而且源表是管理表,那么新表也是管理表。但是,如果语句中包含有external关键字而且源表是管理表,那么生成的新表将是外部表。即使在这种场景下,location子句同样是可选的。

分区表、管理表

hive中有分区表的概念,我们可以看到分区表有重要的性能优势,而且分区表还可以将数据以一种符合逻辑的方式进行组织。比如分层存储。

我们重新看一下之前那张employee表并假设我们在一个很大的跨国公司工作。HR会经常执行一些带where语句的查询。这样可以将结果限定在某个特定的国家或某个特定的第一级细分(比如中国的省)。为了简单,我们只用到了province(省)。在address字段我们已经重复包含了省信息。这和province分区是不同的。我们可以在字段address中删除province元素。我们先按照country(国家)再按照province(省)来对数据进行分区。

create table if not exists employee (
     name    string,
     age     tinyint,
     salary    float,
     subordinates   array<string>,
     address   struct<city:string,street:string>
)
partitioned by (country string, province string);

分区改变了hive对数据存储的组织方式。如果我们是在financial数据库中创建的这个表,那么对于这个表只会有一个employee目录与之对应:

hdfs://master-server/user/hive/warehouse/financial.db/employee

但是,hive现在将会创建好反映分区结构的子目录。例如:

.../employee/country=CN/provice=SHANNXI

.../employee/country=CN/provice=HEBEI

...

这些是实际的目录名称,省目录下将会包含0个或多个文件。这些文件中存放着那些省份的雇员信息。

分区字段(该例中是country和province)一旦创建好,就表现的和普通字段一样。事实上,除非需要优化查询性能,否则使用这些表的用户不需要关心这些“字段”是否是分区字段。

下面这个查询语句将会查找出在中国河北省的所有雇员:

select * from employee where country = ‘CN‘ and province = ‘HEBEI‘;

需要注意的是,因为country和province的值已经包含在文件目录名称中了,所以也就没必要将这些值存放到它们目录下的文件中了。

对数据进行分区,最重要的原因就是为了更快的查询。在上面那个将结果范围限制在中国河北省的例子中,就进需要扫描一个目录下的内容。如果我们有很多个国家和省份目录,就不用再扫描其他目录下的文件了。

当我们在where子句中增加谓词来按照分区值进行过滤时,这些谓词被称为分区过滤器。

如果表中的数据以及分区个数都非常大,执行包含所有分区的查询会触发一个巨大的mapreduce任务,一个高度建议的安全措施是将hive设置为“strict(严格)”模式。这样如果对分区表进行查询而where子句没有加分区过滤的话,会禁止提交这个任务。用户也可以按照下面的方式将属性设置为"nostrict(非严格)":

hive> set hive.mapred.mode=strict;
...
hive> set hive.mapred.mode=nostrict;

可以通过show partitions命令查看表中存在的所有分区:

hive> show partitions employee;
...
country=CN/provice=SHANNXI
country=CN/provice=HEBEI
...

还可以指定过滤条件:

hive> show partitions employee partition(country='CN',province='HEBEI');
country=CN/provice=HEBEI

使用describe extended employee命令也会显示出分区键:

hive> describe extended employee;
...
partitionKeys:[FieldSchema(name:country, type:string,comment:null),FieldSchema(name:province, type:string,comment:null)],
...

在管理表中用户可以通过载入数据的方式创建分区。如下面的例子中可以从一个本地目录($HOME/hebei-employee)载入数据到表中的时候,将会创建一个CN和HEBEI分区。用户需要为每个分区字段指定一个值:

load data local inpath '$(env:HOME)/hebei-employee' into table employee partition (country = 'CN', province = 'HEBEI');

hive将会创建这个分区对应的目录.../employee/country=CN/provice=HEBEI,而且$HOME/hebei-employee目录下的数据会被拷贝到上述分区目录下。

外部分区表

外部表同样可以使用分区。这种结合给用户提供了一个可以和其他工具共享数据的方式,同时也可以优化查询性能。

因为用户可以自己定义目录结构,因此用户对于目录结构的使用具有了更多的灵活性。我们以日志文件分析为例。日志信息的记录有时间戳、日志级别(ERROR、WARNING等),甚至还有服务器名称和进程ID,然后跟着一个文本信息。

我们可以按照如下方式来定义对应的hive表:

create external table if not exists log_message(
hms int,
serverity string,
server string,
process_id int,
message string
) partitioned by (year int, month int, day int)
row format delimited fields terminated by '\t';

我们将日志数据按照天进行划分,划分数据的尺寸合适,而且按天这个粒度进行查询,速度也够快。之前创建的非分区外部表(stocks)要求使用location子句。对于外部分区表则没有这样的要求。有一个alter table语句可以单独进行增加分区。这个语句需要为每一个分区键指定一个值。本例中,需要为year、month和day这3个分区都指定值。下面的例子演示如何增加一个2012年1月2日的分区:

alter table log_message add partition(year = 2014, month = 11, day = 17)location ‘hdfs://master_server/data/log_message/2014/11/07‘;

hive不关心一个分区对应的分区目录是否存在或者分区目录下是否有文件。如果分区目录不存在或者分区目录下没有文件,则对于这个过滤分区的查询将没有返回结果。

和非分区外部表一样,hive并不控制这些数据。即使表被删除,数据也不会被删除。

可以使用show partitions命令来查看一个外部表的分区:

hive> show partitions log_message;
...
year=2014/month=11/day=16
...

这个输出没有分区数据实际存在的路径。这里有一个路径字段,但它仅仅表示如果表是管理表,它会使用到的hive默认路径。我们可以通过如下方式查看分区数据所在的路径:

hive> describe extended log_message partition (year=2014, month=11, day=17);
...
location:hdfs://master_server/data/log_message/2014/11/17
...

删除表

hive只是和sql中的drop table命令类似的操作:

drop table if exists employee;

修改表

大多数的表属性可以通过alter table语句来进行修改。这种操作会修改元数据,但不会修改数据本身。

1)表重命名

alter table log_message rename to logmsg

该语句将表log_message重命名为logmsg

2)增加、修改和删除表分区

alter table log_message add if not exists
partition(year = 2014, month = 1, day = 1) location '/logs/2014/01/01'
partition(year = 2014, month = 1, day = 2) location '/logs/2014/01/02'
...;

还可以高效的移动位置来修改某个分区的路径:

alter table log_message partition(year = 2014, month = 1, day = 1) set location 'hdfs://master_server/data/log_message/logs/2014/01/01';

用户还可以删除某个分区:

alter table log_message drop if exists partition(year = 2014, month = 1, day = 1);

3)修改列信息

用户可以对某个字段进行重命名,并修改其位置、类型或注释:

alter table log_message
change column hms hours_munites_seconds int
comment 'THe hours , minutes, and seconds part of the timestamp'
after serverity;

即使字段名或字段类型没有改变,用户也需要完全指定旧的字段名,并给出新的字段名及新的字段类型。关键字column和comment子句都是可选的。上面的例子将字段转移到了serverity字段之后。如果用户想将这个字段移动到第一个位置,那么只需要使用first关键字替代after other_column子句即可。

4)增加列

用户可以在分区字段之前增加新的字段到已有的字段之后。

alter table log_message add columns (
app_name string comment 'Application name',
session_id long comment 'The current session id'
);

5)删除或替换列

下面这个例子移除了之前所有的字段并重新指定了新的字段:

alter table log_message replace columns (
hours_mins_secs int comment 'hour, minute, seconds from timestamp',
servertity string comment 'The rest of the message'
);

这个语句实际上重命名了之前的hms字段并且从之前的表定义的模式中移除了字段server和process_id。因为是alter语句,所以只有表的元数据信息改变了。

replace语句只能用于使用了如下2中内置SerDe模块的表:DynamicSerDe或者MetadataTypedColumnsetSerDe。SerDe决定了记录是如何分解成字段的(反序列化过程)以及字段是如何写入到存储中的(序列化过程)。

7)修改表属性

用户可以增加附加的表属性或者修改已经存在的属性,但是无法删除属性。

alter table log_message set tblproperties (
'notes' = 'The process id is no longer captured; this column is always NULL'
);

8)修改存储属性

将一个分区的存储格式修改成sequencefile:

alter table log_message partition(year = 2014, month = 1, day = 1)
set fileformat sequencefilel;

如果表是分区表,那么需要使用partition子句。

转载请注明出处:http://blog.csdn.net/iAm333

时间: 2024-10-27 17:41:29

Hive编程指南学习笔记(2)的相关文章

Hive编程指南学习笔记(1)

hive一次使用命令: $ hive -e "select * from mytable limit 1;" OK name1 1 name2 2 Time taken: 3.935 seconds $ hive -e "select * from mytable limit 1;" > /tmp/myfile $ cat /tmp/myfile OK name1 1 name2 2 Time taken: 3.935 seconds 静默模式: $ hive

Linux Unix shell 编程指南学习笔记(第一部分)

第一章:文件安全与权限: 1.文件和目录的权限 创建文件时系统保存了文件所有相关的信息,包括 文件的位置 . 文件类型 . 文件长度 . 哪位用户拥有该文件,哪些用户可以访问该文件 . i 节点 . 文件的修改时间 . 文件的权限位 . 文件类型: d: 目录 l : 符号链接(指向另一个文件) s: 套接字文件 b: 块设备文件 c: 字符设备文件 p: 命名管道文件 -: 不属于上述类型的文件 文件权限 XXX       XXX        XXX 最左边 XXX : 文件属主 权限位

hive编程指南——读书笔记(无知小点记录)

set hive.metastore.warehouse.dir=/user/myname/hive/warehouse; 用户设定自己的数据仓库目录.不影响其他用户.也在$HOME/.hiverc中设置,则每次启动hive自动加载 hive -(d,ef,H,h,i,p,S,v) 定义变量var,在hql中直接引用${var} set (显示或修改) set; (看所有变量) set env:HOME; set -V; 不加-V打印命名空间 hive --define foo=bar (-d简

Linux Unix shell 编程指南学习笔记(第四部分)

第十六章  shell脚本介绍 此章节内容较为简单,跳过. 第十七章   条件测试 test命令 expr命令 test  格式  test  condition     或者  [ condition ]  (注意: condition两侧有空格) 文件状态测试: - d 目录 : - s 文件长度大于0.非空 : - f 正规文件 - w 可写 : - L 符号连接 : - u 文件有s u i d位设置 - r 可读 : - x 可执行 测试的逻辑操作符: -a   :逻辑与,操作符两边均

Linux Unix shell 编程指南学习笔记(第三部分)

第十三章  登陆环境 登陆系统时,输入用户名和密码后,如果验证通过,则进入登录环境. 登录过程 文件/etc/passwd $HOME.profile 定制$HOME.profile /etc/passwd 文件解析(抽取其中的一行作为示例): 1 2 3 4 5 6 7 root: <span style="white-space:pre"> </span>x: 0: 0: root: <span style="white-space:pre&

Linux Unix shell 编程指南学习笔记(第二部分)

第七章  正则表达式介绍 匹配行首与行尾 匹配数据集 职匹配字母和数字 句点 "." 匹配任意单字符. ^,在行首 匹配字符串或字符序列,如查询当前目录下的所有目录: ls -l | grep "^d" 在行尾以 "$"匹配字符串或字符  , 匹配所有以sh结尾的行: sh$ 匹配所有的空行: ^$ 使用*匹配字符串中单字符或重复序列: skdf*jl 使用 \ 转义特殊字符的含义: 特殊字符:   $  .   ''  '   *  [  ]

JavaScript面向对象编程指南——学习笔记1

第1章 引言 1.1 回顾历史 1.2 变革之风 1.3 分析现状 1.4 展望未来 1.5 面向对象的程序设计 1.5.1 对象(属性和方法的集合) 1.5.2 类 (相似对象的共同特征,如麻雀.老鹰都是鸟类) 1.5.3 封装 (将属性和方法集合起来,也有封闭作用域的概念,如封装一个播放器对象) 1.5.4 聚合 (将几个对象合并成一个对象) 1.5.5 继承 (一个实例对象继承父级对象的一些属性和方法) 1.5.6 多态 (一个对象调用其他对象的方法,call和apply) 1.6 OPP

Linux Unix shell 编程指南学习笔记(第五部分)

第二十五章 深入讨论 << 当shell 看到 << 的时候,它知道下一个词是一个分界符,该分界符后面的内容都被当做输入,直到shell又看到该分界符(位于单独的一行).比如: cat >> tmpfile <<DOC > this is the first line > this is the second line > third > forth >..... >DOC 其中DOC就是分界符,再次在新的行中输入DOC时

Hadoop权威指南学习笔记一

Hadoop权威指南学习笔记一 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习参考,有什么不到之处还望指出,一起学习一起进步. 转载请注明:http://blog.csdn.net/my_acm 1. 数据的增长远远超过了磁盘的读取速度,传统的数据存储方式和分析方式变得不再适用于大数据的处理. Hadoop分为两大核心技术,HDFS(HadoopDistributed File System-分布式hadoop文件处理系统)和MapReduce(分为Map-数据映射等