zoukankan      html  css  js  c++  java
  • hive的基本操作

    1、创建表:

    hive>create table pokes(foo int,bar string);

    hive>create table new_tb like pokes; 创建一个一样的表结构

    2、创建分区表:

    Hive>create table logs(ts bigint,line string) partitioned by (dt string,country string);

    3、加载分区表数据:

    hive> load data local inpath '/home/hadoop/input/hive/partitions/file1' into table logs partition (dt='2001-01-01',country='GB');

    4、展示表中有多少分区:

      Hive>show partitions logs;

    5、展示所有表:

      Hive>show tables;

      Hive>show tables ‘.*s’;

    6、显示表的结构信息:

      Hive>describe invites;

    7、更改表的名字:

      Hive>alter table source rename to terget;

    8、添加新一列:

      Hive>alter table invites add columns(new_col2 int comment ‘a comment’);

    9、删除表:

      Hive>drop table records;

      删除表中数据,但要保持表的结构定义:

      Hive>dfs -rmr /usr/hive/warehouse/records;

    10、从本地文件加载数据:

    hive> load data local inpath '/home/hadoop/input/ncdc/micro-tab/sample.txt' overwrite into table records;

    11、显示所有函数

      Hive>show functions;

    12、查看函数用法

      Hive>describe function substr;

    13、查看数组,map,结构

      Hive> select col1[0],col2[‘b’],col3.c from complex;

    14、内连接

      Hive>select sale.*,thing.* from sale join thing on (sale.id=thing.id);

    15、查看hive为某个查询使用多少个mapreduce作业

      Hive>explain select sale.*,thing.* from sale join thing on (sale.id=thing.id);

    16、外连接

      Hive> select sale.*,thing.* from sale left outer join thing on (sale.id=thing.id);

      Hive> select sale.*,thing.* from sale right outer join thing on (sale.id=thing.id);

      Hive> select sale.*,thing.* from sale full outer join thing on (sale.id=thing.id);

    17、in查询:hive不支持,但是可以使用left semi join

      Hive>select * from thing left semi join sale on(sale.id=thing.id);

    18、map连接:hive可以把较小的表放在每个mapper的内存来执行连接操作

      Hive>select /*+mapjoin(thing)*/ sale.*,thing.* from sale join thing on (sale.id=thing.id);

    19、insert overwrite table … select :新表预先存在

      Hive>from record2

          >insert overwrite table stations_by_year select year,count(distinct station)  group by year

          > insert overwrite table records_by_year select year,count(1) group by year

          > insert overwrite table good_records_by_year select year,count(1) where temperature!=999 and (quality=0 or quality=1 or quality=4) group by year;

    20、create table … as select :新表预先不存在

      Hive>create table target as select sol1,col2 from source;

    21、创建视图

      Hive>create view valid_records as select * from records2 where temperature!=999;

    22、查看试图详细信息

      Hive>describe extended valid_records;

        Create Table语句的一些注意项:

        (1)CREATE TABLE创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用IF NOT EXIST选项来忽略这个异常。
       (2)EXTERNAL 关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径( LOCATION ),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
        (3)LIKE允许用户复制现有的表结构,但是不复制数据。
        (4)用户在建表的时候可以自定义SerDe或者使用自带的 SerDe ( Serialize/Deserilize 的简称,目的是用于序列化和反序列化 )。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的SerDe,Hive通过SerDe确定表的具体的列的数据。
        (5)如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用STORED AS SEQUENCE。
        (6)有分区的表可以在创建的时候使用 PARTITIONED B Y语句。一个表可以拥有一个或者多个分区,每一个分区单独存在一个目录下。而且,表和分区都可以对某个列进行CLUSTERED BY操作,将若干个列放入一个桶(bucket)中。也可以利用SORT BY对数据进行排序。这样可以为特定应用提高性能。
        (7)表名和列名不区分大小写,SerDe和属性名区分大小写。表和列的注释是字符串。

        Alter Table语句:主要功能包括Add Partitions, Drop Partitions, Rename Table, Change Column, Add/Replace Columns。

        Create View语句:创建视图。格式CREATE VIEW [IF NOT EXISTS] view_name [ (column_name [COMMENT column_comment], ...) ]

        Show语句:Show tables;  Show partitions; describe查看表结构。

        Load语句:HIVE装载数据时没有做任何转换,加载到表中的数据只是进入相应的配置单元表的位置。Load操作只是单纯的复制/移动操作,将数据文件移动到Hive表对应的位置。

        Insert语句:插入数据。Hive不支持一条一条的用 insert 语句进行插入操作,这个应该是与hive的storage layer是有关系的,因为它的存储层是HDFS,插入一个数据要全表扫描,还不如用整个表的替换来的快些。Hive也不支持update的操作。数据是以load的方式,加载到建立好的表中。数据一旦导入,则不可修改。要么drop掉整个表,要么建立新的表,导入新的数据。

        Drop语句:删除一个内部表的同时会同时删除表的元数据和数据。删除一个外部表,只删除元数据而保留数据。

        Limit子句:可以限制查询的记录数。查询的结果是随机选择的。下面的查询语句从 t1 表中随机查询5条记录,SELECT * FROM t1 LIMIT 5。

        Top K查询:下面的查询语句查询销售记录最大的 5 个销售代表。
    SET mapred.reduce.tasks = 1
    SELECT * FROM sales SORT BY amount DESC LIMIT 5

        正则表达式使用:SELECT语句可以使用正则表达式做列选择,下面的语句查询除了ds和h 之外的所有列:
    SELECT `(ds|hr)?+.+` FROM sales

        SELECT语句:查询数据。

        Group by, Order by, Sort by子句:聚合可进一步分为多个表,甚至发送到 Hadoop 的 DFS 的文件(可以进行操作,然后使用HDFS的utilitites)。可以用hive.map.aggr控制怎么进行汇总。默认为为true,配置单元会做的第一级聚合直接在MAP上的任务。这通常提供更好的效率,但可能需要更多的内存来运行成功。

        Join语句:连接操作。一些注意事项:

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

        (2)Hive 支持多于2个表的连接。

        (3)join 时,每次 map/reduce 任务的逻辑: reducer 会缓存 join 序列中除了最后一个表的所有表的记录, 再通过最后一个表将结果序列化到文件系统。这一实现有助于在reduce端减少内存的使用量。实践中,应该把最大的那个表写在最后(否则会因为缓存浪费大量内存)。

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

        (5)LEFT SEMI JOIN 是 IN/EXISTS 子查询的一种更高效的实现。Hive 当前没有实现 IN/EXISTS 子查询,所以你可以用 LEFT SEMI JOIN 重写你的子查询语句。LEFT SEMI JOIN的限制是, JOIN子句中右边的表只能在ON子句中设置过滤条件,在WHERE子句、SELECT子句或其他地方过滤都不行。

    使用HIVE注意点
        (1)字符集
        Hadoop和Hive都是用UTF-8编码的,所以, 所有中文必须是UTF-8编码, 才能正常使用。
        备注:中文数据load到表里面,,如果字符集不同,很有可能全是乱码需要做转码的,但是hive本身没有函数来做这个。
        (2)压缩
        hive.exec.compress.output 这个参数,默认是false,但是很多时候貌似要单独显式设置一遍,否则会对结果做压缩的,如果你的这个文件后面还要在hadoop下直接操作,那么就不能压缩了。
        (3)count(distinct)
        当前的Hive不支持在一条查询语句中有多Distinct如果要在Hive查询语句中实现多Distinct,需要使用至少n+1条查询语句(n为distinct的数目),前n条查询分别对n个列去重,最后一条查询语句对n个去重之后的列做Join操作,得到最终结果。
        (4)JOIN
        只支持等值连接
        (5)DML操作
        只支持INSERT/LOAD操作,无UPDATE和DELTE
        (6)HAVING
        不支持HAVING操作。如果需要这个功能要嵌套一个子查询用where限制
        (7)子查询
        Hive不支持where子句中的子查询
        (8)Join中处理null值的语义区别
        SQL标准中,任何对null的操作(数值比较,字符串操作等)结果都为null。Hive对null值处理的逻辑和标准基本一致,除了Join时的特殊逻辑。这里的特殊逻辑指的是,Hive的Join中,作为Join key的字段比较,null=null是有意义的,且返回值为true

        (9)分号字符

        分号是SQL语句结束标记,在HiveQL中也是,但是在HiveQL中,对分号的识别没有那么智慧,例如:
    select concat(cookie_id,concat(';',’zoo’)) from c02_clickstat_fatdt1 limit 2;
    FAILED: Parse Error: line 0:-1 cannot recognize input '<EOF>' in function specification
        可以推断,Hive解析语句的时候,只要遇到分号就认为语句结束,而无论是否用引号包含起来。
        解决的办法是,使用分号的八进制的ASCII码进行转义,那么上述语句应写成: 
    select concat(cookie_id,concat('73','zoo')) from c02_clickstat_fatdt1 limit 2;
        为什么是八进制ASCII码?我尝试用十六进制的ASCII码,但Hive会将其视为字符串处理并未转义,好像仅支持八进制,原因不详。这个规则也适用于其他非SELECT语句,如CREATE TABLE中需要定义分隔符,那么对不可见字符做分隔符就需要用八进制的ASCII码来转义。

        (10)Insert

        根据语法Insert必须加“OVERWRITE”关键字,也就是说每一次插入都是一次重写。

     

    其他优化:

    1).Left Semi Join实现in/exists子查询:
    SELECT A.* FROM A LEFT SEMI JOIN B ON(A.KEY = B.KEY AND B.KEY > 100);
    等同于SELECT A.* FROM A WHERE A.KEY IN(SELECT B.KEY FORM B WHERE B.KEY > 100);
    作用:map端用group by减少流入reduce端的数据量

    2).Bucket Map Join:
    set hive.optimize.bucketmapjoin = true;
    和Map join一起工作;
    所有join的表都做列分桶,同时大表桶的数量是小表桶的整数倍;
    做bucket的列必须是join的列;

    SELECT /*+MAPJOIN(a,c)*/ a.*, b.*, c.*
    a join b on a.key = b.key
    join c on a.key=c.key;
    在现实的生产环境中,会有成百上千个buckets;

    3).Skew join:
    join时数据倾斜,造成Reduce端OOM
    set hive.optimize.skewjoin = true;
    set hive.skewjoin.key = 阀值;

    当JOIN得到的map超过阀值时,将内存中的a-k1/b-k1数据分别存入hdfs中,然后遍历完后再对hdfs上的两块数据做Map Join,和其它key一起组成最后结果。

     

    Hive查询进

         通过hive提供的order by子句可以让最终的输出结果整体有序。但是因为Hive是基于hadoop之上的,要生成这种整体有序的结果,就必须强迫Hadoop只利用一个Reduce来完成处理。这种方式的副作用就是回降低效率。如果你不需要最终结果整体有序,你就可以使用sort by子句来进行排序。这种排序操作只保证每个Reduce的输出是有序的。如果你希望某些特定行被同一个Reduce处理,则你可以使用distribute by子句来完成。【Hiveselect top N的问题。】

    Hive> select subject,score,student from score where dt='2012'  orderby subject,socre desc ;

    使用distribute by + sort by。distribute by可以让相同科目的成绩记录发送到同一个reducer,而sort by可以在reducer端对记录做排序。

    Hive> select subject,score,student from score where dt='2012'  distribute by subject sort by subject asc, socre desc

    连接join

    内链接inner join

    外连接left/right/full outer join

    半连接 left semi join

    Map连接(map join):

    当一个表非常小,足以直接装载到内存中去时,可以使用map连接以提高效率,比如:Select /*+mapjoin(teacher) */ a.stuNo,b.teacherNamefrom student a join teacher b on a.classNo = b.classNo;

    以上红色标记部分采用了C的注释风格。当连接时用到不等值判断时,也比较适合Map连接。具体原因需要深入了解Hive和MapReduce的工作原理。

     

     Top N 

    开窗函数:row_number() over(partition by col_a order by col_b) rank

    select product,category,revenue from(

              select product,category,revenue,

              row_number() over(partition by catrgory order by revenue desc)rank

    from mytable)t

    where t.rank<=3;

     

     

  • 相关阅读:
    HBase with MapReduce (MultiTable Read)
    HBase with MapReduce (SummaryToFile)
    HBase with MapReduce (Summary)
    HBase with MapReduce (Read and Write)
    HBase with MapReduce (Only Read)
    Hbase中的BloomFilter(布隆过滤器)
    HBase的快照技术
    How To Use Hbase Bulk Loading
    Cloudera-Manager修改集群的IP
    Java中的HashSet和TreeSet
  • 原文地址:https://www.cnblogs.com/llphhl/p/6610077.html
Copyright © 2011-2022 走看看