hive介绍

1.HIVE结构node

Hive 是创建在 Hadoop 上的数据仓库基础构架。它提供了一系列的工具,能够用来进行数据提取转化加载(ETL),这是一种能够存储、查询和分析存储在 Hadoop 中的大规模数据的机制。Hive 定义了简单的类 SQL 查询语言,称为 QL,它容许熟悉 SQL 的用户查询数据。同时,这个语言也容许熟悉 MapReduce 开发者的开发自定义的 mapper 和 reducer 来处理内建的 mapper 和 reducer 没法完成的复杂的分析工做。
python

1.1HIVE架构mysql

Hive 的结构能够分为如下几部分:正则表达式

wKiom1feBoOCxDOjAAGuzqcaP0U383.png 

  • 用户接口:包括 CLI, Client, WUI sql

  • 元数据存储。一般是存储在关系数据库如 mysql, derby 中 数据库

  • 解释器、编译器、优化器、执行器 express

  • Hadoop:用 HDFS 进行存储,利用 MapReduce 进行计算 apache


  1. 用户接口主要有三个:CLI,Client 和 WUI。其中最经常使用的是 CLI,Cli 启动的时候,会同时启动一个 Hive 副本。Client 是 Hive 的客户端,用户链接至 Hive Server。在启动 Client 模式的时候,须要指出 Hive Server 所在节点,而且在该节点启动 Hive Server。 WUI 是经过浏览器访问 Hive。 浏览器

  2. Hive 将元数据存储在数据库中,如 mysql、derby。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等。 缓存

  3. 解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。 

  4. Hive 的数据存储在 HDFS 中,大部分的查询由 MapReduce 完成(包含 * 的查询,好比 select * from tbl 不会生成 MapRedcue 任务)。

Hive 构建在 Hadoop 之上 

  • HQL 中对查询语句的解释、优化、生成查询计划是由 Hive 完成的 

  • 全部的数据都是存储在 Hadoop 中 

  • 查询计划被转化为 MapReduce 任务,在 Hadoop 中执行(有些查询没有 MR 任务,如:select * from table) 

  • Hadoop和Hive都是用UTF-8编码的


二、HIVE的数据存储

    首先,Hive 没有专门的数据存储格式,也没有为数据创建索引,用户能够很是自由的组织 Hive 中的表,只须要在建立表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就能够解析数据。

其次,Hive 中全部的数据都存储在 HDFS 中,Hive 中包含如下数据模型:Table,External Table,Partition,Bucket。

  1.  Hive 中的 Table 和数据库中的 Table 在概念上是相似的,每个 Table 在 Hive 中都有一个相应的目录存储数据。例如,一个表 htduan,它在 HDFS 中的路径为:/ warehouse /htduan,其中,wh 是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的数据仓库的目录,全部的 Table 数据(不包括 External Table)都保存在这个目录中。 

  2. Partition 对应于数据库中的 Partition 列的密集索引,可是 Hive 中 Partition 的组织方式和数据库中的很不相同。在 Hive 中,表中的一个 Partition 对应于表下的一个目录,全部的 Partition 的数据都存储在对应的目录中。例如:htduan 表中包含 dt 和 city 两个 Partition,则对应于 dt = 20100801, ctry = US 的 HDFS 子目录为:/ warehouse /htduan/dt=20100801/ctry=US;对应于 dt = 20100801, ctry = CA 的 HDFS 子目录为;/ warehouse /htduan/dt=20100801/ctry=CA 

  3. Buckets 对指定列计算 hash,根据 hash 值切分数据,目的是为了并行,每个 Bucket 对应一个文件。将 user 列分散至 32 个 bucket,首先对 user 列的值计算 hash,对应 hash 值为 0 的 HDFS 目录为:/ warehouse /htduan/dt =20100801/ctry=US/part-00000;hash 值为 20 的 HDFS 目录为:/ warehouse /htduan/dt =20100801/ctry=US/part-00020 

  4. External Table 指向已经在 HDFS 中存在的数据,能够建立 Partition。它和 Table 在元数据的组织上是相同的,而实际数据的存储则有较大的差别。 



  • Table 的建立过程和数据加载过程(这两个过程能够在同一个语句中完成),在加载数据的过程当中,实际数据会被移动到数据仓库目录中;以后对数据对访问将会直接在数据仓库目录中完成。删除表时,表中的数据和元数据将会被同时删除。 

  • External Table 只有一个过程,加载数据和建立表同时完成(CREATE EXTERNAL TABLE ……LOCATION),实际数据是存储在 LOCATION 后面指定的 HDFS 路径中,并不会移动到数据仓库目录中。当删除一个 External Table 时,仅删除 

3.HIVE基本操做

 它与关系型数据库的SQL 略有不一样,但支持了绝大多数的语句如DDL、DML 以及常见的聚合函数、链接查询、条件查询。HIVE不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理做业。

 HIVE的特色:可伸缩(在Hadoop的集群上动态的添加设备),可扩展,容错,输入格式的松散耦合。

3.一、DDL 操做


DDL

建表

删除表

修改表结构

建立/删除视图

建立数据库

显示命令

建表:

CREATE [EXTERNAL] TABLE [IF NOT EXISTS] 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] 
  [ROW FORMAT row_format] 
  [STORED AS file_format] 
  [LOCATION hdfs_path]

  • CREATE TABLE 建立一个指定名字的表。若是相同名字的表已经存在,则抛出异常;用户能够用 IF NOT EXIST 选项来忽略这个异常

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

  • LIKE 容许用户复制现有的表结构,可是不复制数据

  • COMMENT能够为表与字段增长描述

 

  • ROW FORMAT

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

            [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

       | SERDE serde_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 。


建立简单表:

hive> CREATE TABLE pokes (foo INT, bar STRING); 


建立外部表:


CREATE EXTERNAL TABLE page_view(viewTime INT, userid BIGINT,

     page_url STRING, referrer_url STRING,

     ip STRING COMMENT 'IP Address of the User',

     country STRING COMMENT 'country of origination')

 COMMENT 'This is the staging page view table'

 ROW FORMAT DELIMITED FIELDS TERMINATED BY '\054'

 STORED AS TEXTFILE

 LOCATION '<hdfs_location>';

建分区表

CREATE TABLE par_table(viewTime INT, userid BIGINT,

     page_url STRING, referrer_url STRING,

     ip STRING COMMENT 'IP Address of the User')

 COMMENT 'This is the page view table'

 PARTITIONED BY(date STRING, pos STRING)

ROW FORMAT DELIMITED ‘\t’

   FIELDS TERMINATED BY '\n'

STORED AS SEQUENCEFILE;

建Bucket表

CREATE TABLE par_table(viewTime INT, userid BIGINT,

     page_url STRING, referrer_url STRING,

     ip STRING COMMENT 'IP Address of the User')

 COMMENT 'This is the page view table'

 PARTITIONED BY(date STRING, pos STRING)

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

 ROW FORMAT DELIMITED ‘\t’

   FIELDS TERMINATED BY '\n'

STORED AS SEQUENCEFILE;



建立表并建立索引字段ds

hive> CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING); 


复制一个空表

CREATE TABLE empty_key_value_store

LIKE key_value_store;



例子

create table user_info (user_id int, cid string, ckid string, username string) 

row format delimited fields terminated by '\t' lines terminated by '\n';

导入数据表的数据格式是:字段之间是tab键分割,行之间是断行。

及要咱们的文件内容格式:

100636  100890  c5c86f4cddc15eb7        yyyvybtvt
100612  100865  97cc70d411c18b6f        gyvcycy
100078  100087  ecd6026a15ffddf5        qa000100


显示全部表:

hive> SHOW TABLES;

按正条件(正则表达式)显示表,

hive> SHOW TABLES '.*s';


修改表结构

增长分区、删除分区

重命名表

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

增长/更新列

增长表的元数据信息



表添加一列 :

hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);

添加一列并增长列字段注释

hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');

更改表名:

hive> ALTER TABLE events RENAME TO 3koobecaf;

删除列:

hive> DROP TABLE pokes;



增长、删除分区

增长

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_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

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

表添加一列 :

hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);

添加一列并增长列字段注释

hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');

增长/更新列

ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)  

    

 ADD是表明新增一字段,字段位置在全部列后面(partition列前)

     REPLACE则是表示替换表中全部字段。

增长表的元数据信息

ALTER TABLE table_name SET TBLPROPERTIES table_properties table_properties:

         :[property_name = property_value…..]

 

用户能够用这个命令向表中增长metadata

改变表文件格式与组织

ALTER TABLE table_name SET FILEFORMAT file_format

ALTER TABLE table_name CLUSTERED BY(userid) SORTED BY(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





2. DML 操做:元数据存储



hive不支持用insert语句一条一条的进行插入操做,也不支持update操做。数据是以load的方式加载到创建好的表中。数据一旦导入就不能够修改。

DML包括:INSERT插入、UPDATE更新、DELETE删除


向数据表内加载文件

将查询结果插入到Hive表中

0.8新特性 insert into


向数据表内加载文件

LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

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

filepath

相对路径,例如:project/data1

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

包含模式的完整 URI,例如:hdfs://namenode:9000/user/hive/project/data1

例如:

hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;




加载本地数据,同时给定分区信息

加载的目标能够是一个表或者分区。若是表包含分区,必须指定每个分区的分区名

filepath 能够引用一个文件(这种状况下,Hive 会将文件移动到表所对应的目录中)或者是一个目录(在这种状况下,Hive 会将目录中的全部文件移动至表所对应的目录中)

LOCAL关键字

指定了LOCAL,即本地

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

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

例如:加载本地数据,同时给定分区信息:

hive> LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');

 没有指定LOCAL

         若是 filepath 指向的是一个完整的 URI,hive 会直接使用这个 URI。 不然

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

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

 

加载DFS数据 ,同时给定分区信息:

hive> LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
The above command will load data from an HDFS file/directory to the table. Note that loading data from HDFS will result in moving the file/directory. As a result, the operation is almost instantaneous.

OVERWRITE

指定了OVERWRITE

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

 

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

 

将查询结果插入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 OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement

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

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

        FROM from_statement

        INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1

     [INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2]

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

INSERT INTO 

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




3. DQL 操做:数据查询SQL


SQL操做

基本的Select 操做

基于Partition的查询

Join

3.1 基本的Select 操做

SELECT [ALL | DISTINCT] select_expr, select_expr, ...

FROM table_reference

[WHERE where_condition]

[GROUP BY col_list [HAVING condition]]

[   CLUSTER BY col_list

  | [DISTRIBUTE BY col_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 只在本机作排序

 

Limit

Limit 能够限制查询的记录数

SELECT * FROM t1 LIMIT 5

实现Top k 查询

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

SET mapred.reduce.tasks = 1 
  SELECT * FROM test SORT BY amount DESC LIMIT 5

REGEX Column Specification

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

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


例如

按先件查询

hive> SELECT a.foo FROM invites a WHERE a.ds='<DATE>';

将查询数据输出至目录:

hive> INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='<DATE>';

将查询结果输出至本地目录:

hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;

选择全部列到本地目录 :

hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(1) FROM invites a WHERE a.ds='<DATE>';
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;

将一个表的统计结果插入另外一个表中:

hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(1) WHERE a.foo > 0 GROUP BY a.bar;
hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(1) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;
JOIN
hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;

将多表数据插入到同一表中:

FROM src
INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;

将文件流直接插入文件:

hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';
This streams the data in the map phase through the script /bin/cat (like hadoop streaming). Similarly - streaming can be used on the reduce side (please see the Hive Tutorial or examples)




3.2 基于Partition的查询

通常 SELECT 查询会扫描整个表,使用 PARTITIONED BY 子句建表,查询就能够利用分区剪枝(input pruning)的特性

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

 

3.3 Join

Syntax

join_table: 
   table_reference JOIN table_factor [join_condition] 
  | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition 
  | table_reference LEFT SEMI JOIN table_reference join_condition 

table_reference: 
    table_factor 
  | join_table 

table_factor: 
    tbl_name [alias] 
  | table_subquery alias 
  | ( table_references ) 

join_condition: 
    ON equality_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 序列中除了最后一个表的全部表的记录,再经过最后一个表将结果序列化到文件系统

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

join 查询时,须要注意几个关键点

只支持等值join

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

SELECT a.* FROM a JOIN b 
    ON (a.id = b.id AND 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) 
  WHERE a.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.key AND 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 SEMI JOIN b on (a.key = b.key)

UNION ALL

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

select_statement UNION ALL select_statement UNION ALL select_statement ...





4.从SQL到HiveQL应转变的习惯


一、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; 

而不是传统的格式:

SELECT t1.a1 as c1, t2.b1 as c2FROM t1, t2 WHERE t1.a2 = t2.b2

二、分号字符

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

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

但HiveQL在解析语句时提示:

        FAILED: Parse Error: line 0:-1 mismatched input '<EOF>' expecting ) in function specification

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

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

 

三、IS [NOT] NULL

SQL中null表明空值, 值得警戒的是, 在HiveQL中String类型的字段如果空(empty)字符串, 即长度为0, 那么对它进行IS NULL的判断结果是False.

四、Hive不支持将数据插入现有的表或分区中,

仅支持覆盖重写整个表,示例以下:

  1. INSERT OVERWRITE TABLE t1  

  2. SELECT * FROM t2;  



四、hive不支持INSERT INTO, UPDATE, DELETE操做

    这样的话,就不要很复杂的锁机制来读写数据。
     INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分区中追加数据。


五、hive支持嵌入mapreduce程序,来处理复杂的逻辑

如:

  1. FROM (  

  2. MAP doctext USING 'python wc_mapper.py' AS (word, cnt)  

  3. FROM docs  

  4. CLUSTER BY word  

  5. ) a  

  6. REDUCE word, cnt USING 'python wc_reduce.py';  


--doctext: 是输入


--word, cnt: 是map程序的输出

--CLUSTER BY: 将wordhash后,又做为reduce程序的输入


而且map程序、reduce程序能够单独使用,如:


  1. FROM (  

  2. FROM session_table  

  3. SELECT sessionid, tstamp, data  

  4. DISTRIBUTE BY sessionid SORT BY tstamp  

  5. ) a  

  6. REDUCE sessionid, tstamp, data USING 'session_reducer.sh';  


--DISTRIBUTE BY: 用于给reduce程序分配数据


六、hive支持将转换后的数据直接写入不一样的表,还能写入分区、hdfs和本地目录。

这样能免除屡次扫描输入表的开销。


  1. FROM t1  

  2.   

  3. INSERT OVERWRITE TABLE t2  

  4. SELECT t3.c2, count(1)  

  5. FROM t3  

  6. WHERE t3.c1 <= 20  

  7. GROUP BY t3.c2  

  8.   

  9. INSERT OVERWRITE DIRECTORY '/output_dir'  

  10. SELECT t3.c2, avg(t3.c1)  

  11. FROM t3  

  12. WHERE t3.c1 > 20 AND t3.c1 <= 30  

  13. GROUP BY t3.c2  

  14.   

  15. INSERT OVERWRITE LOCAL DIRECTORY '/home/dir'  

  16. SELECT t3.c2, sum(t3.c1)  

  17. FROM t3  

  18. WHERE t3.c1 > 30  

  19. GROUP BY t3.c2;  






5.  实际示例

建立一个表

CREATE TABLE u_data (
userid INT,
movieid INT,
rating INT,
unixtime STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '/t'
STORED AS TEXTFILE;


下载示例数据文件,并解压缩
wget 
http://www.grouplens.org/system/files/ml-data.tar__0.gz
tar xvzf ml-data.tar__0.gz

加载数据到表中:

LOAD DATA LOCAL INPATH 'ml-data/u.data'
OVERWRITE INTO TABLE u_data;

统计数据总量:

SELECT COUNT(1) FROM u_data;

如今作一些复杂的数据分析:

建立一个 weekday_mapper.py: 文件,做为数据按周进行分割 
import sys
import datetime

for line in sys.stdin:
line = line.strip()
userid, movieid, rating, unixtime = line.split('/t')

生成数据的周信息

weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '/t'.join([userid, movieid, rating, str(weekday)])

使用映射脚本

//建立表,按分割符分割行中的字段值
CREATE TABLE u_data_new (
userid INT,
movieid INT,
rating INT,
weekday INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '/t';
//将python文件加载到系统
add FILE weekday_mapper.py;

将数据按周进行分割

INSERT OVERWRITE TABLE u_data_new
SELECT
TRANSFORM (userid, movieid, rating, unixtime)
USING 'python weekday_mapper.py'
AS (userid, movieid, rating, weekday)
FROM u_data;

SELECT weekday, COUNT(1)
FROM u_data_new
GROUP BY weekday;

处理Apache Weblog 数据

将WEB日志先用正则表达式进行组合,再按须要的条件进行组合输入到表中
add jar ../build/contrib/hive_contrib.jar;

CREATE TABLE apachelog (host STRING,identity STRING,user STRING,time STRING,request STRING,status STRING,size STRING,referer STRING,agent STRING)ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'WITH SERDEPROPERTIES ("input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|//[[^//]]*//]) ([^ /"]*|/"[^/"]*/") (-|[0-9]*) (-|[0-9]*)(?: ([^ /"]*|/"[^/"]*/") ([^ /"]*|/"[^/"]*/"))?","output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s")STORED AS TEXTFILE;

相关文章
相关标签/搜索