HiveQL

HiveQL

一、DDL

1、DDL功能
建表
删除表
修改表结构
创建/删除视图
创建数据库
显示命令
增加分区、删除分区
重命名表
修改列的名字、类型、位置、注释
增加/更新列
增加表的元数据信息

2、建表

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name

  [(col_namedata_type [COMMENT col_comment], ...)]

  [COMMENTtable_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]

  [ROW FORMATrow_format]

  [STORED ASfile_format]

  [LOCATIONhdfs_path]

CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXIST 选项来忽略这个异常

EXTERNAL 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION)

LIKE 允许用户复制现有的表结构,但是不复制数据

COMMENT可以为表与字段增加描述

ROW FORMAT

DELIMITED[FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]

        [MAP KEYSTERMINATED BY char] [LINES TERMINATED BY char]

   | SERDEserde_name [WITH SERDEPROPERTIES (property_name=property_value,property_name=property_value, ...)]

    用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的SerDe,Hive 通过 SerDe 确定表的具体的列的数据。

STORED AS

           SEQUENCEFILE

            |TEXTFILE

            |RCFILE   

            |INPUTFORMAT input_format_classname OUTPUTFORMAT             output_format_classname

       如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCE 。

建立外部表

CREATE EXTERNAL TABLE page_view(viewTime INT, useridBIGINT,

     page_urlSTRING, referrer_url STRING,

     ip STRINGCOMMENT 'IP Address of the User',

     country STRINGCOMMENT 'country of origination')

 COMMENT 'This isthe staging page view table'

 ROW FORMATDELIMITED FIELDS TERMINATED BY '\054'

 STORED AS TEXTFILE

 LOCATION'<hdfs_location>';

建分区表


CREATE TABLE par_table(viewTime INT, userid BIGINT,

     page_urlSTRING, referrer_url STRING,

     ip STRINGCOMMENT 'IP Address of the User')

 COMMENT 'This isthe page view table'

 PARTITIONEDBY(date STRING, pos STRING)

ROW FORMAT DELIMITED ‘\t’

   FIELDSTERMINATED BY '\n'

STORED AS SEQUENCEFILE;

建Bucket表

CREATE TABLE par_table(viewTime INT, userid BIGINT,

     page_urlSTRING, referrer_url STRING,

     ip STRINGCOMMENT 'IP Address of the User')

 COMMENT 'This isthe page view table'

 PARTITIONEDBY(date STRING, pos STRING)

 CLUSTEREDBY(userid) SORTED BY(viewTime) INTO 32 BUCKETS

 ROW FORMAT DELIMITED‘\t’

   FIELDSTERMINATED BY '\n'

STORED AS SEQUENCEFILE;

复制一个空表
CREATE TABLE empty_key_value_store LIKE key_value_store;

删除表
DROP TABLE table_name

增加、删除分区
增加

ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec[ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...

     partition_spec:

  : PARTITION(partition_col = partition_col_value, partition_col = partiton_col_value, ...)

删除
ALTER TABLE table_name DROP partition_spec,partition_spec,...

重命名表
ALTER TABLE table_name RENAME TO new_table_name

修改列的名字、类型、位置、注释
ALTER TABLE table_name CHANGE [COLUMN] col_old_namecol_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

这个命令可以允许改变列名、数据类型、注释、列位置或者它们的任意组合

增加/更新列
ALTER TABLE table_name ADD|REPLACE COLUMNS (col_namedata_type [COMMENT col_comment], ...)
ADD是代表新增一字段,字段位置在所有列后面(partition列前)
     REPLACE则是表示替换表中所有字段。

增加表的元数据信息
ALTER TABLE table_name SET TBLPROPERTIES table_propertiestable_properties:

        :[property_name = property_value…..]

用户可以用这个命令向表中增加metadata
改变表文件格式与组织
ALTER TABLE table_name SET FILEFORMAT file_format;

ALTER TABLE table_name CLUSTERED BY(userid) SORTEDBY(viewTime) INTO num_buckets BUCKETS;

这个命令修改了表的物理存储属性

创建/删除视图
CREATE VIEW [IF NOT EXISTS] view_name [ (column_name[COMMENT column_comment], ...) ][COMMENT view_comment][TBLPROPERTIES(property_name = property_value, ...)] AS SELECT

增加视图
如果没有提供表名,视图列的名字将由定义的SELECT表达式自动生成

如果修改基本表的属性,视图中不会体现,无效查询将会失败

视图是只读的,不能用LOAD/INSERT/ALTER

DROP VIEW view_name
删除视图

创建数据库
CREATE DATABASE name

显示命令
show tables;

show databases;

show partitions ;

show functions

describe extended table_name dot col_name

二、DML

1、DML功能
向数据表内加载文件
将查询结果插入到Hive表中
0.8新特性 insert into

2、向数据表内加载文件
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTOTABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

Load 操作只是单纯的复制/移动操作,将数据文件移动到 Hive 表对应的位置。

filepath

相对路径,例如:project/data1

绝对路径,例如: /user/hive/project/data1

包含模式的完整 URI,例如:

hdfs://namenode:9000/user/hive/project/data1


3、向数据表内加载文件

加载的目标可以是一个表或者分区。如果表包含分区,必须指定每一个分区的分区名

filepath 可以引用一个文件(这种情况下,Hive 会将文件移动到表所对应的目录中)或者是一个目录(在这种情况下,Hive 会将目录中的所有文件移动至表所对应的目录中)


4、LOCAL关键字

指定了LOCAL

load 命令会去查找本地文件系统中的 filepath。如果发现是相对路径,则路径会被解释为相对于当前用户的当前路径。用户也可以为本地文件指定一个完整的 URI,比如:file:///user/hive/project/data1.

load 命令会将 filepath 中的文件复制到目标文件系统中。目标文件系统由表的位置属性决定。被复制的数据文件移动到表的数据对应的位置

没有指定LOCAL

    如果 filepath 指向的是一个完整的 URI,hive 会直接使用这个 URI。 否则

如果没有指定 schema 或者 authority,Hive 会使用在 hadoop 配置文件中定义的 schema 和 authority,fs.default.name指定了 Namenode 的 URI

如果路径不是绝对的,Hive 相对于 /user/ 进行解释。 Hive 会将 filepath 中指定的文件内容移动到 table (或者 partition)所指定的路径中


5、OVERWRITE

指定了OVERWRITE

目标表(或者分区)中的内容(如果有)会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。

如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。

 
6、将查询结果插入Hive表

将查询结果插入Hive表

将查询结果写入HDFS文件系统

基本模式


INSERT OVERWRITE TABLE tablename1 [PARTITION(partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement

多插入模式

 FROM from_statement

INSERT OVERWRITE TABLE tablename1 [PARTITION(partcol1=val1, partcol2=val2 ...)] select_statement1

[INSERT OVERWRITE TABLE tablename2 [PARTITION ...]select_statement2] ...

自动分区模式

 INSERT OVERWRITETABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...)select_statement FROM from_statement


7、将查询结果写入HDFS文件系统

INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ...FROM ...

        FROMfrom_statement

        INSERTOVERWRITE [LOCAL] DIRECTORY directory1 select_statement1

     [INSERTOVERWRITE [LOCAL] DIRECTORY directory2 select_statement2]

数据写入文件系统时进行文本序列化,且每列用^A 来区分,\n换行


8、INSERT INTO

INSERT INTO  TABLEtablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1FROM from_statement

 
三、 HiveQL 查询操作

1、SQL操作
基本的Select 操作

基于Partition的查询

Join

2、基本的Select 操作
SELECT [ALL | DISTINCT] select_expr, select_expr, ...

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list [HAVING condition]]

[   CLUSTER BYcol_list

  | [DISTRIBUTE BYcol_list] [SORT BY| ORDER BY col_list]

]

[LIMIT number]

使用ALL和DISTINCT选项区分对重复记录的处理。默认是ALL,表示查询所有记录。DISTINCT表示去掉重复的记录

Where 条件

类似我们传统SQL的where 条件

目前支持 AND,OR ,0.9版本支持between

IN, NOT IN

不支持EXIST ,NOT EXIST

ORDER BY与SORT BY的不同

ORDER BY 全局排序,只有一个Reduce任务

SORT BY 只在本机做排序

3、Limit
Limit 可以限制查询的记录数

SELECT * FROM t1 LIMIT 5

实现Top k 查询

下面的查询语句查询销售记录最大的 5 个销售代表。

SET mapred.reduce.tasks = 1

  SELECT * FROMtest SORT BY amount DESC LIMIT 5

REGEX Column Specification

SELECT 语句可以使用正则表达式做列选择,下面的语句查询除了 ds 和 hr 之外的所有列:

SELECT `(ds|hr)?+.+` FROM test


基于Partition的查询

一般 SELECT 查询会扫描整个表,使用PARTITIONED BY 子句建表,查询就可以利用分区剪枝(input pruning)的特性

Hive 当前的实现是,只有分区断言出现在离 FROM 子句最近的那个WHERE 子句中,才会启用分区剪枝


4、Join
Syntax

join_table:

   table_referenceJOIN table_factor [join_condition]

  | table_reference{LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition

  | table_referenceLEFT SEMI JOIN table_reference join_condition

  

table_reference:

    table_factor

  | join_table

  

table_factor:

    tbl_name[alias]

  | table_subqueryalias

  | (table_references )

  

join_condition:

    ONequality_expression ( AND equality_expression )*

  

equality_expression:

    expression =expression

Hive 只支持等值连接(equality joins)、外连接(outer joins)和(left semi joins)。Hive 不支持所有非等值的连接,因为非等值连接非常难转化到 map/reduce 任务

 

LEFT,RIGHT和FULL OUTER关键字用于处理join中空记录的情况

LEFT SEMI JOIN 是 IN/EXISTS 子查询的一种更高效的实现

join 时,每次 map/reduce 任务的逻辑是这样的:reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表将结果序列化到文件系统

实践中,应该把最大的那个表写在最后


5、join 查询时,需要注意几个关键点

只支持等值join

SELECT a.* FROM a JOIN b ON (a.id = b.id)

SELECT a.* FROM a JOIN b

    ON (a.id = b.idAND a.department = b.department)

可以 join 多于 2 个表,例如:

 SELECT a.val,b.val, c.val FROM a JOIN b

    ON (a.key =b.key1) JOIN c ON (c.key = b.key2)

如果join中多个表的 join key 是同一个,则 join 会被转化为单个 map/reduce 任务


LEFT,RIGHT和FULL OUTER

例子:SELECT a.val, b.val FROM a LEFT OUTER JOIN b ON (a.key=b.key)

如果你想限制 join 的输出,应该在 WHERE 子句中写过滤条件——或是在 join 子句中写。

容易混淆的问题是表分区的情况

SELECT c.val, d.val FROM c LEFT OUTER JOIN d ON(c.key=d.key)

  WHEREa.ds='2010-07-07' AND b.ds='2010-07-07‘

如果 d 表中找不到对应 c 表的记录,d 表的所有列都会列出 NULL,包括ds 列。也就是说,join 会过滤 d 表中不能找到匹配 c 表 join key 的所有记录。这样的话,LEFT OUTER 就使得查询结果与 WHERE 子句无关

解决办法


SELECT c.val, d.val FROM c LEFT OUTER JOIN d

  ON (c.key=d.keyAND d.ds='2009-07-07' AND c.ds='2009-07-07')

LEFT SEMI JOIN

LEFT SEMI JOIN 的限制是, JOIN 子句中右边的表只能在 ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。

SELECT a.key, a.value

  FROM a

  WHERE a.key in

   (SELECT b.key

    FROM B);

       可以被重写为:

      SELECT a.key,a.val

   FROM a LEFT SEMIJOIN b on (a.key = b.key)


UNION ALL

用来合并多个select的查询结果,需要保证select中字段须一致

select_statement UNION ALL select_statement UNION ALLselect_statement ...

四、 从SQL到HiveQL应该转变的几个习惯

1、Hive不支持等值连接

SQL中对两表内联可以写成:
select * from dual a,dual b where a.key = b.key;

Hive中应为
select * from dual a join dual b on a.key = b.key;

2、分号字符
分号是SQL语句结束标记,在HiveQL中也是,但是在HiveQL中,对分号的识别没有那么智慧,例如:

select concat(key,concat(';',key)) from dual;

但HiveQL在解析语句时提示:
        FAILED:Parse Error: line 0:-1 mismatched input '<EOF>' expecting ) in functionspecification

解决的办法是,使用分号的八进制的ASCII码进行转义,那么上述语句应写成:

select concat(key,concat('\073',key)) from dual;
 

3、IS [NOT]NULL

SQL中null代表空值, 值得警惕的是, 在HiveQL中String类型的字段若是空(empty)字符串, 即长度为0, 那么对它进行ISNULL的判断结果是False。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值