Hive0.14 语法

创建数据库

create database mydb;

切换数据库

use mydb;

创建数据库

create database if not exists mydb;

创建内部表表的同时加载数据

create table student_test(id INT, info struct<name:STRING, age:INT>)   ROW FORMAT DELIMITED FIELDS

TERMINATED BY ','  COLLECTION ITEMS TERMINATED BY ':';

创建外部表

create external table xxx location '/dir';

查看表信息

describe t1;

查看表的详细信息

describe extended t1;

删除数据库级联删除数据库中的表

DROP DATABASE [IF EXISTED] mydb [CASCADE];

修改列的名称、类型、位置、注释

ALTER TABLE t3 CHANGE COLUMN old_name new_name String COMMENT '...' AFTER column2;

增加列

ALTER TABLE t3 ADD COLUMNS (gender int);

从本地文件系统加载数据到表中

load data local inpath '/root/inner_table.dat' into table t1;

从hdfs加载数据到表中

load data inpath '/root/inner_table.dat' into table t1;

创建分区表

create table partition_table(rectime string,msisdn string) partitioned by(province string,city string) row format

delimited fields terminated by '\t' stored as TEXTFILE;

加载数据到分区表

load data local inpath 'files/stu' into table partition_table partition(province='beijing',city='chaoyang');

查看分区

show partitions partition_table;

删除分区

alter table partition_table drop partition (daytime='2013-02-04',city='bj')元数据,数据文件删除,但目录

daytime=2013-02-04还在


桶是更为细粒度的数据范围划分,它能使一些特定的查询效率更高,比如对于具有相同的桶划分并且join的列刚好就

是在桶里的连接查询,还有就是示例数据,对于一个庞大的数据集我们经常需要拿出来一小部分作为样例,然后在样

例上验证我们的查询,优化我们的程序。

桶表是对数据进行哈希取值,然后放到不同文件中存储。

创建表

create table bucket_table(id string) clustered by(id) sorted by (id) into 4 buckets;插入时先对id取hash值,然后对4取

模分到四个桶中

加载数据

set hive.enforce.bucketing = true;默认是false,启用桶表必须先设置该变量

insert into table bucket_table select id from stu;   

insert overwrite table bucket_table select id from stu;覆盖原来数据

数据加载到桶表时,会对分桶的字段取hash值,然后与桶的数量取模。把数据放到对应的文件中。


抽样查询

select * from bucket_table tablesample(bucket 1 out of 4 on id);

tablesample是抽样语句,语法:TABLESAMPLE(BUCKET x OUT OF y)

y必须是table总bucket数的倍数或者因子。hive根据y的大小,决定抽样的比例。例如,table总共分了64份,当y=32

时,抽取 (64/32=)2个bucket的数据,当y=128时,抽取(64/128=)1/2个bucket的数据。x表示从哪个bucket开始抽取。

例 如,table总bucket数为32,tablesample(bucket 3 out of 16),表示总共抽取(32/16=)2个bucket的数据,分别为

第3个bucket和第(3+16=)19个bucket的数据。


从文件中装载数据

hive>LOAD DATA [LOCAL] INPATH '...' [OVERWRITE] INTO TABLE t2 [PARTITION (province='beijing')];

通过查询表装载数据

hive>INSERT OVERWRITE TABLE t2 PARTITION (province='beijing') SELECT * FROM xxx WHERE xxx

一次插入多个表

hive>FROM t4

 INSERT OVERWRITE TABLE t1 SELECT ...WHERE...

 INSERT OVERWRITE TABLE t2 PARTITION (...) SELECT ...WHERE...

 INSERT OVERWRITE TABLE t3 PARTITION (...) SELECT ...WHERE...


动态分区装载数据【动态分区列写在select子句最后
hive>set hive.exec.dynamic.partition=true; 启用动态分区
hive>set hive.exec.dynamic.partition.mode=nostrict; 非严格模式
hive>set hive.exec.max.dynamic.partitions.pernode=1000;      最大分区数(目的是限制产生过多文件夹)

hive>INSERT OVERWRITE TABLE t3 PARTITION(province, city)
SELECT t.province, t.city FROM temp t;

如果是严格模式,必须指定一个静态分区,不能全都是动态分区
hive>INSERT OVERWRITE TABLE t3 PARTITION(province='bj', city)
SELECT t.province, t.city FROM temp t WHERE t.province='bj';


导出hive中的数据

可以使用hadoop命令进行文件复制 hdfs dfs -cp source destination


完整建表语句(注意关键字顺序)

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
  [(col_name data_type [COMMENT col_comment], ...)]
    [COMMENT table_comment]
    [PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
    [CLUSTERED BY (col_name, col_name, ...)
    [SORTED BY (col_name [ASC|DESC], ...)] INTO num_buckets BUCKETS]
    [SKEWED BY (col_name, col_name, ...) ON ([(col_value, col_value, ...), ...|col_value, col_value, ...])
    [STORED AS DIRECTORIES]   ]
  [ [ROW FORMAT row_format]
    [STORED AS file_format] | STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]   ]
  [LOCATION hdfs_path]
  [TBLPROPERTIES (property_name=property_value, ...)]     
  [AS select_statement]  (Note: not supported when creating external tables.)


hive处理的文件格式

TextFile: 普通文本文件,默认按该类型存储 不做压缩,磁盘开销大,数据解析开销大

SequenceFile:  Hadoop API提供的一种二进制文件支持 可分割、可压缩 支持三种压缩选择:NONE, RECORD,

BLOCK。 Record压缩率低,一般建议使用BLOCK压缩

RCFile:是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个

记录需要读取多个block。其次,block中数据按列式存储,有利于数据压缩和快速的列存取。

ORC:


textfile 存储空间消耗比较大,并且压缩的text 无法分割和合并 查询的效率最低,可以直接存储,加载数据的速度最高

sequencefile 存储空间消耗最大,压缩的文件可以分割和合并 查询效率高,需要通过text文件转化来加载

rcfile 存储空间最小,查询的效率最高 ,需要通过text文件转化来加载,加载的速度最低


创建表按SequenceFile格式存储,并设置压缩形式,最后从其他表插入数据

create table test2(str STRING) STORED AS SEQUENCEFILE;

hive> set hive.exec.compress.output=true;

hive> set mapred.output.compress=true;

hive> set mapred.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;

hive> set io.seqfile.compression.type=BLOCK;

hive> set io.compression.codecs=com.hadoop.compression.lzo.LzoCodec;

hive> INSERT OVERWRITE TABLE test2 SELECT * FROM test1;


创建ORC格式存储表

hive> create table t1_orc(id int, name string) row format delimited fields terminated by '\t' stored as orc

tblproperties("orc.compress"="ZLIB");

将其他类型的表转成ORC格式表

ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC

设置默认存储格式为ORC

hive> SET hive.default.fileformat=Orc;

hive> insert overwrite table t1_orc select * from t1;


What is a SerDe?

SerDe 是 "Serializer and Deserializer."的缩写

Hive 使用 SerDe和FileFormat进行行内容的读写.

HDFS文件 --> InputFileFormat --> <key, value> --> Deserializer --> 行对象

行对象 --> Serializer --> <key, value> --> OutputFileFormat --> HDFS文件


Hive 使用如下FileFormat 类读写 HDFS files:

TextInputFormat/HiveIgnoreKeyTextOutputFormat: 读写普通HDFS文本文件.

SequenceFileInputFormat/SequenceFileOutputFormat: 读写SequenceFile格式的HDFS文件.


例:

CSV格式的文件也称为逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可

以不是逗号。在本文中的CSV格式的数据就不是简单的逗号分割的),其文件以纯文本形式存储表格数据(数字和文

本)。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字

符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的字段序列。

默认的分隔符是

DEFAULT_ESCAPE_CHARACTER \

DEFAULT_QUOTE_CHARACTER  "     ---如果没有,则不需要指定

DEFAULT_SEPARATOR        ,


CREATE TABLE csv_table(a string, b string) ROW FORMAT SERDE

'org.apache.hadoop.hive.serde2.OpenCSVSerde' WITH SERDEPROPERTIES (   "separatorChar" = "\t",  

"quoteChar"     = "'",   "escapeChar"    = "\\")  STORED AS TEXTFILE;

红色部分为默认,也可以不写。


该类org.apache.hadoop.hive.serde2.OpenCSVSerde即包含了InputFormat和OutputFormat来处理csv文件。



什么时候可以避免执行MapReduce?

select * where语句中只有分区字段

set hive.exec.mode.local.auto=true;

group by语句

having语句

order by、sort by、distribute by、cluster by语句

order by是全局排序、sort by是单reduce排序、distribute by是分区字段;

cluster by是distribute by和sort by的简写


性能调优

set hive.map.aggr=true;

这个设置可以将顶层的聚合操作放在Map阶段执行,从而减轻清洗阶段数据传输和Reduce阶段的执行时间,提升总

体性能。

缺点:该设置会消耗更多的内存。


表连接:

INNER JOIN

表中都有,且两表符合连接条件

LEFT OUTER JOIN

左表中符合where条件出现,右表可以为空

RIGHT OUTER JOIN

右表中符合where条件出现,左表可以为空

FULL OUTER JOIN

LEFT SEMI-JOIN (左半连接)

左表中符合on条件出现,右表不出现

笛卡尔积

是m x n的结果

map-side JOIN


视图的创建

CREATE VIEW v1 AS select * from t1;


lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数

据进行聚合。lateral view首先为原始表的每行调用UDTF,UTDF会把一行拆分成一或者多行,lateral view再把结果组

合,产生一个支持别名表的虚拟表。

SELECT pageid, adid FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid;


自定义函数:

1、UDF函数可以直接应用于select语句,对查询结构做格式化处理后,再输出内容。

2、编写UDF函数的时候需要注意一下几点:

a)自定义UDF需要继承org.apache.hadoop.hive.ql.UDF。

b)需要实现evaluate函数,evaluate函数支持重载。

4、步骤

a)把程序打包放到目标机器上去;

b)进入hive客户端,添加jar包:hive>add jar /run/jar/udf_test.jar;

c)创建临时函数:hive>CREATE TEMPORARY FUNCTION add_example AS 'hive.udf.Add';

d)查询HQL语句:

SELECT add_example(8, 9) FROM scores;

SELECT add_example(scores.math, scores.art) FROM scores;

SELECT add_example(6, 7, 8, 6.8) FROM scores;

e)销毁临时函数:hive> DROP TEMPORARY FUNCTION add_example;

注:UDF只能实现一进一出的操作,如果需要实现多进一出,则需要实现UDAF


使用jdbc访问hive

首先开启hive远程端口

Hive远程服务启动#hive --service hiveserver  -p 10002 >/dev/null  2>/dev/null &

JAVA客户端相关代码

Class.forName("org.apache.hadoop.hive.jdbc.HiveDriver");

Connection con = DriverManager.getConnection("jdbc:hive://192.168.1.102:10000/wlan_dw", "", "");

Statement stmt = con.createStatement();

String querySQL="SELECT * FROM wlan_dw.dim_m order by flux desc limit 10";

ResultSet res = stmt.executeQuery(querySQL); 

while (res.next()) {

System.out.println(res.getString(1) +"\t" +res.getLong(2)+"\t" +res.getLong(3)+"\t" +res.getLong(4)+"\t"

+res.getLong(5));

}

JOIN 优化

1.hive对3个或3个以上的表进行join操作时,如果每个on字句都使用相同的连接键的话,只会产生一个MapReduce

job。

2.hive会假定查询中最后一个表示最大的那个表。在对每行记录进行连接操作时,会将其他表缓存起来,然后扫描最

后那个表进行计算。所以要保证从左到右表的大小是依次增加的。也可以在查询语句中加入 /*+STREAMTABLE(表名

或别名)*/,指定哪张是最大的表。

3.避免笛卡尔积,select * from a join b where ....。在执行where过滤前首先会对a表和b表进行笛卡尔积,导致过程非

常缓慢,在hive中设置hive.mapred.mode=strict可以阻止笛卡尔积。

4.map-side join 如果连接查询中只有一张表是小表,可以将小表中的数据放到内存中,在map端就可以进行连接操作

省略了reduce端的过程。需要设置 hive.auto.convert.join=true 并设置小表的大小hive.mapjoin.smalltable.filesize单位

是字节。或在查询中加入 /*+ MAPJOIN(表名或别名)*/







发布了84 篇原创文章 · 获赞 3 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章