hive 概覽及dml語句

Hive Tutorial
數據單元:
分區:
    每個表能夠有一個或多個分區列,用來決定數據如何存儲。分區不只僅是存儲單元,並且容許用戶按照條件組織分類數據,分區鍵列中每個不重複的值定義一個表的分區。分區能夠極大的提升數據分析的速度。一個分區列就是一個僞列,因此分區列名能夠自由設置,分區列的名稱不能夠和表中某一實際列的名稱相同。node


Buckets(Clusters):
    表中或每個分區中的數據能夠被分隔成多個Buckets,分隔方式是依據表中的一些列的hash值,這些列能夠用clustered by指定,這些列中相同的值會被存儲到同一個文件中,而且能夠經過sorted by 設置排序列和排序方式,這樣的文件就稱爲bucket。表級別能夠有bucket,分區下面也能夠有bucket,這個時候分區和表的概念能夠認爲相同。bucket的特色:一個bucket文件中的數據某一列的值相同,而且能夠依據某一列有序,前提是buckets的數目要和clustered by指定的列可能的取值數相同(我的理解)。apache

數據類型:
    (包括各種型的長度,繼承轉化關係以及複雜類型構建)
    https://cwiki.apache.org/confluence/display/Hive/Tutorialjson

內置操做符和內置函數:
    在beeline命令行中查看:
        show functions; 顯示函數列表
        describe function  function_name; 函數的簡單描述
        describe function extended function_name; 函數的詳細描述
    str rlike regexp: Returns true if str matches regexp and false otherwise
    經常使用函數:round floor  ceil rand concat substr upper  lower trim ltrim rtrim regexp_replace size from_unixtime to_date get_json_object 
    內置的聚合函數:
        count(*):返回記錄行總數,包括NULL值
        count(expr): 返回expr不爲null的行總數
        count(distinct expr) 返會expr不爲NULL而且值惟一的行的總數
        avg(col)、avg(distinct col) 
        sum(col)、sum(distinct col)函數

Hive Sql的功能:
    where語句過濾結果
    select選擇特定的列
    表間的鏈接
    對group by分組求值
    把查詢結果存儲到一個表中
    下載hive表中的內容到本地目錄中
    把查詢結果保存到hdfs目錄中
    管理表和分區
    在自定義的MR任務中,插入自定義的腳本oop

加載數據:
    建立一個external表,指向hdfs中一個指定的位置,並提供數據行格式的信息,用戶可使用hdfs的put或copy命令,把文件放到指定的那個位置。
    舉例:
        若是/tmp/pv_2008-06-08.txt包含逗號分隔的行,要加載到page_view表中,能夠依次執行:
        CREATE EXTERNAL TABLE page_view_stg(...)
        ROW FORMAT DELIMITED FIELDS TERMINATED BY '44' LINES TERMINATED BY '12'
        STORED AS TEXTFILE
        LOCATION '/user/data/staging/page_view';性能

        hadoop dfs -put /tmp/pv_2008-06-08.txt /user/data/staging/page_view大數據

        FROM page_view_stg pvs
        INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='US')
        SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip
        WHERE pvs.country = 'US';
    這種方式適合hdfs中已經有的數據,須要使用hive來查詢,所以須要向hive註冊數據的元數據信息。ui

    除此以外,還支持直接從操做系統中加載數據到hive表中:
        LOAD DATA LOCAL INPATH /tmp/pv_2008-06-08_us.txt INTO TABLE page_view PARTITION(date='2008-06-08', country='US')
    inpath參數取值:一個目錄(目錄下的全部文件被加載,不會遞歸子目錄)、一個文件、通配符(僅僅匹配文件名)
    
    從hdfs中的文嘉中加載數據到hive中:
        LOAD DATA INPATH '/user/data/pv_2008-06-08_us.txt' INTO TABLE page_view PARTITION(date='2008-06-08', country='US')url

查詢和插入數據:
簡單查詢:
    INSERT OVERWRITE TABLE user_active 
    SELECT user.*
    FROM user
    WHERE user.active = 1;
    全部的查詢結果都會插入一個指定的表中,select * from users;查詢結果在內部會寫入到一些臨時文件中。
分區查詢:
    查詢時在where子句中,包含建立表時指定的分區字段做爲條件。
鏈接join:
    (left outer、right outer、full outer)
    INSERT OVERWRITE TABLE pv_users
    SELECT pv.*, u.gender, u.age
    FROM user u JOIN page_view pv ON (pv.userid = u.id)
    WHERE pv.date = '2008-03-03';
    檢查一個key在另一個表中是否存在 LEFT SEMI JOIN:
        INSERT OVERWRITE TABLE pv_users
        SELECT u.*
        FROM user u LEFT SEMI JOIN page_view pv ON (pv.userid = u.id)
        WHERE pv.date = '2008-03-03';
    多表鏈接:
        INSERT OVERWRITE TABLE pv_friends
        SELECT pv.*, u.gender, u.age, f.friends
        FROM page_view pv JOIN user u ON (pv.userid = u.id) JOIN friend_list f ON (u.id = f.uid)
        WHERE pv.date = '2008-03-03';
    鏈接時把包含大數據量的表放到右邊,能夠提升性能,僅支持等同鏈接。
聚合查詢:
    INSERT OVERWRITE TABLE pv_gender_sum
    SELECT pv_users.gender, count (DISTINCT pv_users.userid)
    FROM pv_users
    GROUP BY pv_users.gender;spa

    使用多個聚合函數,每個聚合函數中,distinct後指定的列必須相同:
    INSERT OVERWRITE TABLE pv_gender_agg
    SELECT pv_users.gender, count(DISTINCT pv_users.userid), count(*), sum(DISTINCT pv_users.userid)
    FROM pv_users
    GROUP BY pv_users.gender;
多表多文件插入:

FROM pv_users
    INSERT OVERWRITE TABLE pv_gender_sum
    SELECT pv_users.gender, count_distinct(pv_users.userid)
    GROUP BY pv_users.gender    --查詢結果插入到hive表中
 
    INSERT OVERWRITE DIRECTORY '/user/data/tmp/pv_age_sum'
    SELECT pv_users.age, count_distinct(pv_users.userid)
    GROUP BY pv_users.age;  --查詢結果放到hdfs文件系統中

    若是數據要存到多個不一樣的分區:
    multi-insert:
    FROM page_view_stg pvs
    INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='US')
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip WHERE pvs.country = 'US'
    INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='CA')
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip WHERE pvs.country = 'CA'
    INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country='UK')
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip WHERE pvs.country = 'UK';
    這種方式,每次增長一個新的國家,都要修改代碼增長一個insert分支語句,並且由於每個insert可能被看成一個Map/Reduce任務,效率低。

    下面這種方式會根據數據內容自動將數據插入到對應分區中,若是分區不存在會自動建立,並且只有一個MR任務,效率高。
    Dynamic-partition insert:
    FROM page_view_stg pvs
    INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country)
       SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip, pvs.country

    二者的不一樣點:
        country出如今partition中,可是不指定具體值,這代表country是一個動態分區列,dt指定了值,是一個靜態分區列。若是一個列是動態分區列,那麼它的值取自數據。動態分區列要放到partition子句的最後,如PARTITION(dt='2008-06-08',country),由於這個順序代表了分區的層次,這個例子說明country是dt分區下面的子分區。
        select子句中要把動態分區列指定爲查詢列。
總結:
    同一分區下,若是數據相同,會覆蓋分區數據,由於 OVERWRITE TABLE。
    hive分區相似hdfs目錄概念,因此分區名要規範,若有特殊字符會轉換成%dd格式,若是不是string類型,會轉換爲string以後做爲分區名,在hdfs上建立目錄。
    若是輸入列是null或者空字符串,數據會放到一個特殊的分區中,由參數hive.exec.default.partition.name指定,默認值爲HIVE_DEFAULT_PARTITION{}。
    動態建立分區可能短期建立大量分區:
        hive.exec.max.dynamic.partitions.pernode
        默認100,一個mapreduce任務中最多能建立的分區數目
        hive.exec.max.dynamic.partitions
        默認1000,一個dml語句能建立的最大動態分區數目。
        hive.exec.max.created.files
        默認100000,全部的MR任務能夠建立的文件總數
    只指定動態分區列,未指定靜態分區列:
        hive.exec.dynamic.partition.mode=strict
        該模式下,必需要指定一個靜態分區列
        hive.exec.dynamic.partition=true/false
        啓用或禁用動態分區列,默認false

數據保存到本地:
    INSERT OVERWRITE LOCAL DIRECTORY '/tmp/pv_gender_sum'
    SELECT pv_gender_sum.*
    FROM pv_gender_sum;

union all、array、map的操做,見官網。  

相關文章
相關標籤/搜索