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的操做,见官网。  

相关文章
相关标签/搜索