《hive编程指南》读书笔记

hive

一般数据库是写时模式,写入时对数据合法性进行检查,而hive是读时模式,读取数据时进行数据合法性检查

create database可以加comment子句,describe database时会显示comment

而create database时的with dbproperties(’key1’ = ‘val1’,’key2=’val2’)keyiyong describe database extended tablename 显示。

分区表

partitiioned by(col1 format, col2 format)

储存时会按照col1=xxx,col2=xxx设置子目录

摄者strict(严格)模式则可以指定hive查询时一定要进行分区过滤(也就是where)

设置方法:hive> set hive.mapred.mode=strict

分区外部表可以用alter table 。。。 add partition()来添加新的分区,同时不同分区可以在不同的路径下

装载数据

load data local。。。 将本地数据拷贝到hive

动态分区插入

1
2
3
4
5
6
INSERT overwrite TABLE employees
partition (country, STATE)
SELECT ...,
se.cnty,
se.st
FROM stated_employees se;

这里最后两列就是动态分区的两列。load以后将会出现100个分区

也可以用动态静态混合模式,即

1
2
3
4
5
6
7
INSERT overwrite TABLE employees
partition (country="US", STATE)
SELECT ...,
se.cnty,
se.st
FROM stated_employees se
where cnty= 'US';

导出数据

用insert。。。directory。。。子句可以将数据导出到本地

1
2
3
from table_name tb_alias
insert overwrite directory '/tmp/local_dir'
select * where ....

本地模式

hive对于select * from table,或者where中全是分区列则使用本地模式

可以设置hive。exec.mode.local.auto=true来让hive尝试用本地模式完成更多任务

where查询

like谓词: x%表示以x开头的string,%x为以x结尾,%x%表示含有x。_表示匹配单个字符

A rlike/regexp B: B为一个jdk格式的正则表达式。

float比较时注意进度问题 p98

Having语句

和group by一起使用,做过滤。

1
2
3
select year, avg(price) from stocks
group by year
having avg(price) > 50;

having选出了group by后平均价格大于50的结果

left semi-join

select s.a, s.b from stocks s left semi join another_table t on s.a=t.a;

这个是搜左边的表满足右边某些条件的语句,其中select和where不能用到右边的表。因为对于左边的记录,搜到一条和右边匹配的就会退出,所以效率比inner join高。

mapside join

set hive.auto.convert.join=true,则hive会将小表自动mapside join。
大小默认是hive.mapjoin.smalltable.filesize=25000000

order by、sort by、 distribute by, cluster by

ordre by,全局有序,一个reduce
sort by,每个reduce内部有序
distribute by,影响hive如何将数据分发到reduce,默认是按照key的hashcode,用了这个可以按照指定列划分

9.4 同一份数据多种处理

hive每次运行都会扫描全表,因此如果要select两份不同的数据,用select。。。from。。。的方法需要扫描两次表。

但是用from table balabal的方式可以只扫描一次:

1
2
3
from table
insert overwrite table select * where condition1
insert overwrite table select * where condition2

这样只扫描一次就可以得到两个表

命令行参数

  • -f filename: filename里面储存了sql语句。执行该sql
  • -d,-define : 执行$HIVE_HOME/bin/hive -d k1=v1 表示,定义了一个变量k1,值为v1,进入Hive交互Shell之后,可以使用${k1}来引用该变量,比如:hive> select ‘${k1}’ from t_lxw1234 limit 1;
  • –hivevar :用法同-d和—define
  • -hiveconf 定义property或者变量,比如
1
2
3
$ hive -hiveconf dt=2015-01-01
hive > insert overwrite table tableA
> select * from tableB where date='${hiveconf:dt}';

HIVE比较重要的优化是分区和分桶

函数

udtf 可以支持返回一行多列 p185

udf可以使用distributed cache,主要用到了LookupService类 p189

13.12 以函数的方式使用注解
https://hive.apache.org/javadocs/r2.0.0/api/org/apache/hadoop/hive/ql/udf/UDFType.html

1
2
3
4
5
public @interface UDFType {
boolean deterministic() default true;
boolean stateful() default false;
boolean distinctLike() default false;
}

用法,在函数注解中加入@UDFType(deterministic = false)这种.

  • deterministic:定数性,指的是这个函数的运行结果是不是确定的。如果是,则对于没参数的函数只执行一遍。有参数的不确定是不是同样参数只执行一遍。对于类似rand()这样的函数就要设为false
  • stateful: 让udf有状态,最简单的例子就是在每行计算他和他之前的累加和。
  • distincLike: 这个标记通常出现在聚合函数中,在做聚合时,如果碰到两个相同的值,我们只取其中一个不影响最后的聚合结果,那么distinctLike为真,否则为假。
  • impliesOrder: Using in analytical functions to specify that UDF implies an ordering(没懂干嘛用的)

宏命令:

1
2
hive> CREATE TEMPORARY MACRO SIGMOD(x double) 1.0 / (1.0 + EXP(-x));
hive> SELECT SIGMOID(2) FROM src LIMIT 1;

hive streaming

利用map(),reduce(),transform()编程。比如

1
2
3
hive> SELECT TRANSFORM (a,b)
> USING '/bin/cat' AS newA, newB
> FROM table_name;

p195
使用分布式缓存

1
2
3
4
hive > ADD FILE ${env:HOVE}/my.sh;
Added....
hive > SELECT TRANSFORM(col1) USING 'my.sh' as convert FRO< a;

p210
利用SerDe可以在inputFormat读取一行数据后调用SerDe.deserialize()进行处理。Create table时加上ROW FORMAT SERDE。可以在对数据序列化或者反序列化时进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
CREATE EXTERNAL TABLE message (
msg_id BIGINT,
tstamp STRING,
text STRING
)
ROW FORMAT SERDE "org.apache.hadoop.hive.contrib.serde2.JsonSerde"
WITH SERDEPROPERTIES (
"msg_id" = "$.id",
"tstamp"="$.created_at",
"text"="$.text"
)
LOCATION '/data/messages';

储存过程

P226

  • inputFormat:如何将给定路径下的文件分割成多分
  • recordReader: 提供如何从每个划分中读取数据
  • outputFormat: 获取一个job的输出,然后将其输入到一个实体中。

hiveStoragteHandler可以用来连接Nosql储存的接口。但是由于服务器的socket连接,访问效率会比较慢。

利用StorageHandler可以连接hbase:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
create 'hzq_test','grade', 'course'
put 'hzq_test','Tom','grade:','5'
put 'hzq_test','Tom','course:math','97'
put 'hzq_test','Tom','course:art','87'
put 'hzq_test','Jim','grade','4'
put 'hzq_test','Jim','course:math','89'
put 'hzq_test','Jim','course:art','80'
CREATE EXTERNAL TABLE hzq_test(
key string,
grade map<string,int> ,//column family必须要是map
math string,
art string)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,grade:,course:math,course:art")
TBLPROPERTIES("hbase.table.name" = "hzq_test");

安全

p234

权限管理有user,group和role三个级别。user和group是和posix是一样的,而role是hive自己定的。
首先需要开启设定:

1
2
3
4
5
6
7
8
<property>
<name>hive.security.authorization.enabled</name>
<value>true</value>
</property>
<property>(给表拥有者设定权限,否则没法操作)
<name>hive.security.authorization.createtable.owner.grants</name>
<value>all</value>
</property>

1
2
3
4
5
6
7
8
9
10
11
12
> set system:user.name;
system:user.name= user1
//role
> GRANT CREATE ON DATABASE default TO USER user1;
//group
> GRANT SELECT ON TABLE talbe1 TO GROUP user1;
//role
> CREATE ROLE role1;
> GRANT ROLE role1 ON user1;
> GRANT SELECT ON TABLE table1 to role1;
名称 描述
ALL 赋予所有权限
ALERT 修改表的权限
CREATE 创建表
DROP 删除表或者表分区
INDEX 创建索引
LOCK 开启并发后锁定和解锁权限
SELECT 查询
SHOW_DATABASE 查看所有数据库
UPDATE 向表中插入或者加载数据的权限(比如load命令)

授权同样可以基于分区进行p238

可以设置为用户自动授权

1
2
3
4
<property>
<name>hive.security.authorization.createtable.owner.grants</name>
<value>select,drop</value>
</property>

p241

通过配置zookeeper,hive可以对表进行锁操作。默认的,hive会对特定查询加锁。可以通过SHOW LOCKS查看。另外也可以显示的加解锁:LOCK TABLE people EXCLUSIVE; UNLOCK TABLE people;


本文采用创作共用保留署名-非商业-禁止演绎4.0国际许可证,欢迎转载,但转载请注明来自http://thousandhu.github.io,并保持转载后文章内容的完整。本人保留所有版权相关权利。

本文链接:http://thousandhu.github.io/2016/03/04/《hive编程指南》读书笔记/