HiveQL詳解


Hive 是基於Hadoop 構建的一套數據倉庫分析系統,它提供了豐富的SQL查詢方式來分析存儲在Hadoop 分布式文件系統中的數據,可以將結構化的數據文件映射為一張數據庫表,並提供完整的SQL查詢功能,可以將SQL語句轉換為MapReduce任務進行運行,通過自己的SQL 去查詢分析需要的內容,這套SQL 簡稱Hive SQL,使不熟悉mapreduce 的用戶很方便的利用SQL 語言查詢,匯總,分析數據。而mapreduce開發人員可以把己寫的mapper 和reducer 作為插件來支持Hive 做更復雜的數據分析。

它與關系型數據庫的SQL 略有不同,但支持了絕大多數的語句如DDL、DML 以及常見的聚合函數、連接查詢、條件查詢。HIVE不適合用於聯機,也不提供實時查詢功能。它最適合應用在基於大量不可變數據的批處理作業。如HiveQL不支持更新操作, 也不支持索引和事務, 它的子查詢和join操作也很局限, 這是因其底層依賴於Hadoop雲平台這一特性決定的, 但其有些特點是SQL所無法企及的。

HIVE的特點:可伸縮(在Hadoop的集群上動態的添加設備),可擴展,容錯,輸入格式的松散耦合。

Hive 的官方文檔中對查詢語言有了很詳細的描述,請參考:http://wiki.apache.org/hadoop/Hive/LanguageManual ,本文的內容大部分翻譯自該頁面,期間加入了一些在使用過程中需要注意到的事項。

1. DDL 操作

1.1、建表:

    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';

 

1.2、修改表結構

  • 表添加一列 :
    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]

這個命令可以允許改變列名、數據類型、注釋、列位置或者它們的任意組合

  • 表添加一列 :
  1. hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);
  • 添加一列並增加列字段注釋
  1. hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');
  • 增加/更新列
  1. ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

ADD是代表新增一字段,字段位置在所有列后面(partition列前)

REPLACE則是表示替換表中所有字段。

  • 增加表的元數據信息
  1. ALTER TABLE table_name SET TBLPROPERTIES table_properties table_properties:
  2. :[property_name = property_value…..]

用戶可以用這個命令向表中增加metadata

  • 改變表文件格式與組織
  1. ALTER TABLE table_name SET FILEFORMAT file_format
  2. ?ALTER TABLE table_name CLUSTERED BY(userid) SORTED BY(viewTime) INTO num_buckets BUCKETS

這個命令修改了表的物理存儲屬性

  • 創建/刪除視圖
  1. CREATE VIEW [IF NOT EXISTS] view_name [ (column_name [COMMENT column_comment], ...)
  2. ][COMMENT view_comment][TBLPROPERTIES (property_name = property_value, ...)] AS SELECT
  • 增加視圖

如果沒有提供表名,視圖列的名字將由定義的SELECT表達式自動生成

如果修改基本表的屬性,視圖中不會體現,無效查詢將會失敗

視圖是只讀的,不能用LOAD/INSERT/ALTER

  • 刪除視圖
  1. DROP VIEW view_name
  • 創建數據庫
  1. CREATE DATABASE name
  • 顯示命令
  1. show tables;
  2. ?show databases;
  3. ?show partitions ;
  4. ?show functions
  5. ?describe extended table_name dot col_name

2. DML 操作:元數據存儲

hive不支持用insert語句一條一條的進行插入操作,也不支持update操作。數據是以load的方式加載到建立好的表中。數據一旦導入就不可以修改。

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

  • 向數據表內加載文件
        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 中的文件復制到目標文件系統中。目標文件系統由表的位置屬性決定。被復制的數據文件移動到表的數據對應的位置

3. DQL 操作:數據查詢SQL

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 可以限制查詢的記錄數

  1. SELECT * FROM t1 LIMIT 5
  • 實現Top k 查詢

下面的查詢語句查詢銷售記錄最大的 5 個銷售代表。

  1. SET mapred.reduce.tasks = 1
  2. SELECT * FROM test SORT BY amount DESC LIMIT 5
  3. REGEX Column Specification

SELECT 語句可以使用正則表達式做列選擇,下面的語句查詢除了 ds 和 hr 之外的所有列:

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

4. 從SQL到HiveQL應轉變的習慣(HiveQL與MySql區別)

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;

 

而不是傳統的格式:

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

 

2、分號字符

分號是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;

 

3、IS [NOT] NULL

SQL中null代表空值, 值得警惕的是, 在HiveQL中String類型的字段若是空(empty)字符串, 即長度為0, 那么對它進行IS NULL的判斷結果是False.

4、Hive不支持將數據插入現有的表或分區中,僅支持覆蓋重寫整個表,示例如下:

    INSERT OVERWRITE TABLE t1
    SELECT * FROM t2;

 

5、hive不支持INSERT INTO 表 Values(), UPDATE, DELETE操作
    這樣的話,就不要很復雜的鎖機制來讀寫數據。
    INSERT INTO syntax is only available starting in version 0.8。INSERT INTO就是在表或分區中追加數據。

6、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程序分配行數據

7、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;  
復制代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM