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

     

     

  • 相关阅读:
    NHibernate官方文档中文版--拦截器和事件(Interceptors and events)
    NHibernate官方文档中文版——批量插入(Batch inserts)
    NHibernate官方文档中文版-框架架构(Architecture)
    NHibernate官方文档中文版--ISessionFactory的配置(ISessionFactory Configuration)
    ConcurrentDictionary的key判断存在的两种方式,用错了慢100倍
    树莓派3B+,我要跑.NET Core
    C# .NET Framework4.0环境下使用async/await语法,以及其中的需要注意的地方。
    C# 利用结构体对固定格式数据进行解析
    简单工厂模式
    正则表达式替换指定格式内容,实现类似String的Format方法(用扩展方法)
  • 原文地址:https://www.cnblogs.com/llphhl/p/6610077.html
Copyright © 2020-2023  润新知