Hive-学习总结

一.基础操作

1.1变量和属性

hivevar--(0.8以后版本) 用户自定义变量 (读写) ${hivevar:foo} --变量引用和替换

hiveconf --Hive相关的配置属性(读写)

system -- Java定义的配置属性(读写)

env -- Shell环境定义的环境变量(只可读)

在CLI中,可以使用SET命令显示或者修改变量值。

env命名空间可以作为Hive传递变量的一种方式,例如:

$ YEAR = 2012
hive -e "SELECT * FROM t1 WHERE year = ${env:YEAR}"

1.2 开启静默模式

两个用处,1.当我们使用CLI查询数据,不想显示“OK”或者查询时间等,可以使用-S开启静默模式,这样也可以将查询的结果直接输出或者重定向到文件中

hive -S -e "select * from t1" > /data/myquery

2.模糊查找某些属性 

./hive -S -e "set" | grep warehouse
hive.metastore.warehouse.dir=/user/hive/warehouse
hive.warehouse.subdir.inherit.perms=true

1.3执行sql的两种方式

执行sql语句 hive -e "sql"

执行sql脚本 hive -f xxx.hql

通常我们约定使用src(代表源表)作为表名进行测试---源于Hive源码中的单元测试的写法,所以我们做测试前要创建一个src的表,同时必须至少有一行的数据在源表里面。

1.4 hiverc文件

CLI 选项中有 -i 文件名,这个选项允许用户指定一个文件,当CLI启动时,在提示符出现前会先执行这个文件。Hive会自动在HOME目录下寻找.hiverc文件,而且会自动执行这个文件中的命令。该文件中可以设置一些系统的属性或者增加对于Hadoop的分布式内存进行自定义的Hive扩展的Jar包。

1.5在hive中使用hadoop的dfs的命令

用户可以在hive CLi中执行hadoop命令,只需要将hadoop去掉就可以,这种方式实际上比其灯架的bash shell中执行的hadoop dfs更加高效,因为后者每次都会启动一个新的JVM实例,而Hive会在用一个进程中执行这些命令

二.数据类型和文件格式

2.1基本数据类型

TIMYINT  1byte

SMALLINT 2byte

INT 4byte

BIGINT 8vyte

BOOLEAN 布尔类型

FLOAT 单精度浮点数

DOUBLE 双精度浮点数

STRING 字符串,可以指定字符集,可以使用单、双引号

TIMESTAMP(v8.0+)整数、浮点数、字符串都可以,JDBC兼容的java.sql.Timestamp时间格式

BINARY (v8.0+)字节数组

需要注意的是,这些数据类型都是对Java接口的实现,所以具体细节和java中对应的类型都是完全一致的。

另外hive对字符串没有长度的限制,因为相比于其他SQL,hadoop和hive强调优化磁盘的读和写的性能,而不关注限制列的值的长度

新增数据类型TIMESTAMP的值可以时整数,也就是距离Unix新纪元时间的秒数,也可以是浮点数,即距离Unix新纪元的秒数,精确到纳秒(小数点后保留9位),还可以是字符串,即JDBC所约定的时间字符串格式,格式为YYYY-MM-DD hh:mm:ss.fffffffff

BINARY可以在记录中包含任意字节,这样可以防止Hive尝试作为数字,字符串等进行解析

注意:

不同的整型的值作对比,hive会都转成较大的类型再做比较

如果想将字符串类型的列转为数值类型,可以使用cast(s AS INT)

2.2集合数据类型

Hive中的列支持使用struct,map,array集合数据类型

struct -和c语言的struct或者对象类似,都可以通过“点”符号访问元素内容。例如,如果某个列的数据类型是STRUCT(first STRING,last STRING),那么访问第一个元素可以通过字段名.first来引用

struct('lijin','11')

map - 一组键值对的集合,使用数组表示法(['key'])可以访问元素

array - 一组相同类型和名称的变量的集合,可以用过数组元素的标号(['1'])访问元素

相比于传统的数据模型,不支持集合数据类型,因为这样破坏了标准格式,还会增加数据冗余的风险,但是可以提供更高吞吐量的数据,以最小的““头部寻址”来从磁盘上扫描数据相比于根据外键关联进行磁盘间的寻址操作,会提高性能。

2.3文本文件的数据编码

逗号分隔值CSV

制表符分隔值TSV

hive中默认的记录和字段分隔符

\n 对于文本文件来说,每一行都是一条记录,因此换行符可以分割记录

^A 用于分割字段,在CREATE TABLE 语句中可以使用八进制编码\001表示

^B 用于分割ARRAY 、STRACT中的元素,或用于MAP中键-值对之间的分割 \002表示

^C用于MAP中键-值之间的分割\003表示

2.4读时模式

传统数据库是写时模式(schema on write),即在数据写入数据库对模式进行检查

Hive不会再数据加载时进行验证,而是在查询时进行,也就是读时模式(schema on read)。

如果每行记录的字段个数少于对应的模式中定义的字段个数的话,少的部分都是null值

如果某些字段是数值类型的,但是hive读取时存在非数值类型的,将会返回null

三.数据操作

3.1向管理表中装载数据

LOAD DATA LOCAL INPATH "${env:HOME}/california-employees"
OVERWRITE INTO TABLE employee
PARTITION (country = 'US',state = 'CA')

如果分区目录不存在的话,这个命令会创建分目录,然后再将数据拷贝到分区目录下,如果目标表是分区表,那么语句应该省略PARTITION字句。

通常情况下指定的路径应该是一个目录,而不是单个独立的文件,而且文件名保持不变。

LOAD DATA LOCAL copy本地数据到位于分布式文件系统上的目标位置

LOAD DATA 数据在hdfs上,会移动到指定的目录下

OVERWRITE 重写 否则是追加,如果使用OVERWRITE关键字,会将原来的文件覆盖,如果不使用OVERWRITE,如果有同名的文件,会保留之前的文件并且会重命名文件尾“之前的文件名_序列号”(v0.8.0后支持)

3.2通过查询语句向表中插入数据

hive允许用户通过查询语句向目标表中插入数据

INSERT OVEROVERWRITE TABLE employee
PARTITION (COUNTRY = 'US',state = 'OR')
SELECT * FROM staged_employee se
WHERE se.city = 'US' and se.st ='OR'

还可以一次扫描数据,按照多中方式进行划分

FROM staged_employee se
INSERT OVERWRITE TABLE employees
  PARTITION (country = 'US',state = 'OR')
SELECT * WHERE se.city = 'US' and se.state = 'OR'
INSERT OVERWRITE TABLE employees
  PARTITION (country = 'US',state = 'CA')
SELECT * WHERE se.city = 'US' and se.state = 'CA'
...

 

3.3动态分区插入

hive支持动态分区,通过查询的字段的值作为不同的分区,当然可以动态和静态分区混合使用,但是静态分区必须在动态分区之前。动态分区默认没有开启,开启后默认以“strict”模式执行,即至少有一个分区是静态的,有助于阻止因设计错误导致查询产生大量的分区。

hive.exec.dynamic.partition 默认值 false 设置为true,开启动态分区功能
hive.exec.dynamic.partition.mode 默认值 strict 即至少有一个分区是静态的
hive.exec.max.dynamic.partitions.pernode 默认值 100 每个mapper或reducer可以创建的最大动态分区个数。如果每个mapper或reducer创建更多的分区,会报错
hive.exec.max.dynamic.partitions +1000 一个动态分区可以创建的最大分区的个数
hive.exec.max.created.files 100000 全局可以创建的最大文件个数。有一个hadoop计数器会跟踪记录创建了多少个文件。

3.4单个查询语句中创建并加载数据

CREATE TABLE ca_employees AS 
SELECT name,salary,address
FROM employees
WHERE se.state = 'CA'

3.5导出数据

如果文件恰好是用户需要的格式,可以使用hadoop的cp命令进行copy

如果向从表中选取一部分字段,可以使用

INSERT OVERWRITE  LOCAL DIRECTORY "/path"
SELECT
name,salary,address
FROM employee
WHERE se.state = 'CA'

还可以一次读取,按照多种格式导出多份数据

FROM staged_employees se
INSERT OVERWRITE DIRECTORY '/path1'
SELECT * WHERE se.city = 'US' and se.st= 'OR'
INSERT OVERWRITE DIRECTORY '/path2'
SELECT * WHERE se.city = 'US' and se.st= 'CA'
...

 

posted @ 2019-05-16 19:59  行走的灵魂  阅读(1048)  评论(0编辑  收藏  举报