大数据知识点梳理-Hadoop生态之Hive

1.3.1 *描述-下Hive动态分区和分桶使用场景和使用方法?

    1.分区

      按照数据表的某列或某些列分为多个分区,分区从形式上可以理解为文件夹,比如我们要收集某个大型网站的日志数据,一个网站每天的日志数据存在同一张表上,由于每天会生成大量的日志,导致数据表的内容巨大,在查询时进行全表扫描耗费的资源非常多。那其实
这个情况下,我们可以按照日期对数据表进行分区,不同日期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查找。分区是以字段的形式在表结构中存在,通过describe table命令可以查看到字段存在,但是该字 段不存放实际的数据内容,仅仅是分区的表示(伪列)。

      (1) 静态分区
    create table if not exists sopdm.wyp2(id int,name string,tel string)
    partitioned by(age int) row format delimited fields terminated by ,' stored as textfile;
    --overwrite是覆盖,into 是追加
    insert into table sopdm.wyp2 partition(age='25') select id,name,tel from sopdm.wyp;
      (2)动态分区
    --设置为true表示开启动态分区功能(默认为false)
    set hive.exec.dynamic.partition=true;
    -设置为nonstrict,表示允许所有分区都是动态的(默认为strict)
    set hive.exec.dynamic.partition.mode=nonstrict;
    --insert overwrite是覆盖,insert into是追加
    set hive.exec. dynamic.partition.mode=nonstrict;
    insert overwrite table sopdm.wyp2 partition(age) select id,name,tel,age from sopdm.wyp;
      (3)静态分区和动态分区的区别
    静态分区与动态分区的主要区别在于静态分区是手动指定,而动态分区是通过数据来进行判断。详细来说:
    静态分区:
      ➢ 静态分区是 在编译期间指定的指定分区名。
      ➢ 支持load和insert 两种插入方式。
      ➢ 适用于分区数少, 分区名可以明确的数据。
    动态分区:
      ➢ 根据分区 字段的实际值,动态进行分区。
      ➢ 是在sql执行的时候进行分区。
      ➢ 需要先将动态分区 设置打开。
          set hive.exec.dynamic.partition.mode=nonstrict
      ➢ 只能用insert方式。
      ➢ 通过普通表选出的字段包含分区字段,分区字段放置在最后,多个分区字段按照分区顺序放置。

 


    2.分桶

      分桶;是相对分区进行更细粒度的划分。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到
一个文件,取模为2的数据存放到一个文件。
      CREATE TABLE bucketed_ _user (id INT) name STRING) CLUSTERED BY (id) INTO 4 BUCKETS;
      对于每一一个表(table) 或者分区,Hive 可以进一步组 织成桶,也就是说桶是更为细粒度的数据范围划分。Hive 也是针对某- -列进行桶的组织。Hive 采用对列值哈希,然后除以桶|的个数求余的方式决定该条记录存放在哪个桶当中。把表(或者分区)组织成桶( Bucket)
有两个理由: 
    (1)获得更高的查询处理效率
      桶为表加.上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接.两个在(包含连接列的)相同列上划分了桶的表,可以使用Map端连接(Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有-一个相同的列,如果对这两个表都进
行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
    (2)使取样(sampling) 更高效
      在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

【面试指导&技巧】
      一般问到Hive分区,基本上都会问动态分区和静态分区的区别。所以要能够答出他们之间的区别。同时要清晰用法和应用场景。
      另外,需要能够结合项目说,自己在项目中,哪些地方用了动态分区。-般涉及按日期分区的,比较多是动态分区。
【注意】
      对于分桶表,工作中实际应用场景不多,但需要了解其原理(分桶不要求重点掌握)。

 


1.3.2 Hive是怎么集成HBase的?具体讲讲?

1.首先我们需要将HBase的客户端jar拷入Hive lib目录下。
2.修改hive/conf'下的hive site.xml配置文件,在最后添加如下属性。


    hbase.zookeeper.quorum
    hadoop

3.启动Hive,创建表管理表hbase_ table_ 1,指定数据存储在HBase表中。
类似下面的方式:

stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties
("hbase.columns.mapping"=":key,accuracy:total score,accuracy:question_ count,accuracy:accuracy")
tblproperties("hbase.table.name" = "exam:analysis");

4.往Hive表hbase_ table_ 1表中插入数据。

【注意】
      CDH版本不需要额外操作,相同CDH版本下的软件,已经做过整合。

【面试指导&技巧】
      如果使用CDH版本,回答重点放在集成的代码上。相关的代码格式需要掌握,需要能够答出Stored by的类型,HBaseStorageHandler 的类。
      如果使用的Apache版本,还需要能够答出大致的整合步骤。
 


1.3.3 Hive查询的时候on和where有什么区别?为什么?

    左右关联时:
      ➢ 条件不为主表条件时, 放在on和where后面一样。
      ➢ 条件为主表条件时,放在on后面,结果为主表全量,放在where后面为主表条件筛选过后的全量。

    1. select * from a left join b on a.id = b.id and a.dt= 20181115;
    2. select * from a left join b on a.id = b.id and b.dt= :20181115; .
    3. select * from a join b on a.id = b.id and a.dt=20181115;
    4. select * from a left join b on a.id = b.id where a.dt=20181115;

      sql1:如果是leftjoin在on.上写主表a的条件不会生效,全表扫描。
      sql2:如果是left join在on.上写副表b的条件会生效,但是语义与写到where条件不同。
      sq|3:如果是innerjoin在on.上写主表a、副表b的条件都会生效。
      sq|4:建议这么写,大家写sq|大部分的语义都是先过滤数据然后再join,所以在不了解joinon+条件的情况下,条件尽量别写到on后,直接写到where后就ok了。

【面试指导&技巧】
      能够讲出join时,on和where的区别,可以通过举例子的方式进行讲解。on中的条件是在join时执行,where中的条件,是在join结束后对结果进行执行。
 


1.3.4 Hive里面的left join是怎么回事?他是怎么执行的?

      不考虑where条件下,left join会把左表所有数据查询出来,on及其后面的条件仅仅会影响右表的数据(符合就显示,不符合全部为nul)。
      在join阶段, where 子句的条件都不会被使用,仅在join阶段完成以后,where 子句条件才会被使用,它将从匹配阶段产生的数据中检索过滤。
      所以左连接关注的是左边的主表数据,不应该把on后面的从表中的条件加到where后,这样会影响原有主表中的数据。
      where后面:是先连接生成临时查询结果,然后再筛选on后面:先根据条件过滤筛选,再连接生成临时查询结果。
      对于条件在on加个and还是用子查询,查询结果是一模一样的,至于如何使用这个需要分情况,用子查询的话会多-一个maptask,但是如果利用这个子查询能过滤到很多数据的话,用子查询还是比较建议的,因为不会加载太多的数据到内存中,如果过滤数据不多的情况下,建议用on后面加and条件。

【面试指导&技巧】
      需要能够讲出leftjoin的用法以及特点即可。该问题比较基础。

 


1.3.5 *说-下Hive内部表、外部表、分区表?

  1.内部表
    ➢ 与 数据库中的Table在概念上是类似的。
    ➢ 每一个Table在Hive中都有一个相应的目录存储数据。
    ➢ 所有的Table数据(不包括External Table) 都保存在这个目录中。
    ➢ 删除表时, 元数据与数据都会被删除。
  2.外部表
    ➢ 指向已经在 HDFS中存在的数据,可以创建Partition。
    ➢ 它和内部表在元数据的组织上是相同的,而实际数据的存储则有较大的差异。
    ➢ 外部表只有一个过程, 加载数据和创建表同时完成,并不会移动到数据库目录中,只是与外部数据建立-一个连接。当删除一个外 部表时,仅删除连接和元数据。
  3.分区表
    ➢ Partition对应于数据库的Partition列的密集索引。
    ➢ 在Hive中,表中的一个Partition对应于表下的一个目录,所有的Partition 的数据都存储在对应的目录中。

【面试指导&技巧】
      问题比较基础。需要能够答出他们之间的区别。以及相对应的应用场景,以及语法(笔试或者现场写代码)。
 


1.3.6 *Hive和mysql有什么区别,大数据为什么不用mysql做存储和数据处理?

      Hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop分布式文件系统中的数据:可以将结构化的数据文件映射为一-张数据库表,并提供完整的SQL查询功能;可以将SQL语句转换为MapReduce任务运行,通过自己的SQL查询分析需要的内容,这套SQL简称Hive SQL,使不熟悉MapReduce的用户可以很方便地利用SQL语言‘查询、汇总和分析数据。而MapReduce开发人员可以把自己写的mapper和reducer作为插件来支持Hive做更复杂的数据分析。
      它与关系型数据库的SQL略有不同,但支持了绝大多数的语句如DDL、DML以及常见的聚合函数、连接查询、条件查询。它还提供了一系列的工具进行数据提取转化加载,用来存储、查询和分析存储在Hadoop中的大规模数据集,并支持UDF (User-Defined Function)、UDAF(User-Defnes AggregateFunction)和UDTF ( User-Defined Table- Generating Function),也可以实现对map和reduce函数的定制,为数据操作提供了良好的伸缩性和可扩展性。
      Hive不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。Hive 的特点包括:可伸缩(在Hadoop的集群上动态添加设备)、可扩展、容错、输入格式的松散耦合
      Hive构建在基于静态批处理的Hadoop之.上,Hadoop通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,Hive并不能够在大规模数据集.上实现低延迟快速的查询,例如,Hive 在几百MB的数据集上执行查询- -般有分钟级的时间延迟。
      因此,Hive 并不适合那些需要高实性的应用,例如,联机事务处理(OLTP) 。Hive 查询操作过程严格遵守Hadoop MapReduce的作业执行模型, Hive将用户的HiveQL语句通过解释器转换为MapReduce作业提交到Hadoop 集群上,Hadoop 监控作业执行过程,然后返回作业执行结果给用户。Hive 并非为联机事务处理而设计,Hive 并不提供实时的查询和.基于行级的数据更新操作。Hive 的最佳使用场合是大数据集的批处理作业,例如,网络日志分析。


    总结如下:
      ➢ 查询语言不同: Hive是hql语言,mysql是sql语句;
      ➢ 数据存储位 置不同: Hive 是把数据存储在HDFS.上,而mysql数据是存储在自己的系统中;
      ➢ 数据格式: Hive数据格式可以用户自定义,mysq|有自己的系统定义格式;
      ➢ 延迟性: Hive延迟性高,而mysql延迟性低;
      ➢ 数据规模: Hive 存储的数据量超级大,而mysq|只是存储一些少 量的业务数据;
      ➢ 底层执行原理: Hive底层是用的MapReduce, 而mysql是excutor执行器。

【面试指导&技巧】
      能够讲出Hive和MySQL的几点不同,以及相对应的原因。比如讲Hive查询慢,需要讲出Hive为什么会慢,讲Hive支持大数据,需要讲出为什么支持大数据。
 


1.3.7 *Hive如何调优?

    1.设置本地模式。
    2.并行执行。
    3.JVM重用。
    4.严格模式。
    5.合理设置map和reduce的数量。
    6.Fetch抓取。
    7.防止数据倾斜参数的开启,会生成两个MR Job。
    8.explain执行计划,通过执行计划来调节SQL语句。

【面试指导&技巧】
      该处是面试重点,- -般需要能够答出几种调优手段。参考课件内容,需要能讲出具体怎
 


1.3.8 *Hive数据倾斜原因和处理?

  1.产生原因

    (1) key分布不均匀。
    (2)业务数据本身的特性。
    (3)建表时考虑不周。
    (4)某些SQL语句本身就有数据倾斜,例如:
      ➢ 大表join小表,其中小表key集中,分发到某--个或几个Reduce.上的数据远高平均值。
      ➢ 大表join大表,但是分桶的判断字段0值或空值过多,这些空值都由一个reduce处理,非常慢。
      ➢ groupby,groupby维度过小,某值的数量过多,处理某值的reduce非常耗时
      ➢ Count Distinct,某特殊值过多,处理此特殊值的reduce耗时。

  2.解决方案

  【参数调节】
      hive.map.aggr = true
      Map端部分聚合,相当于Combinerhive.groupby.skewindata=true
      有数据倾斜的时候进行负载均衡,当选项设定为true,生成的查询计划会有两个MRJob。第一个MRJob中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupByKey有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce 中(这个过程可以保证相同的Group By Key被分布到同-一个Reduce中),最后完成最终的聚合操作。

【SQL调整】
      ➢ 如何 Join:关于驱动表的选取,选用join key分布最均匀的表作为驱动表,做好列裁剪和filter操作,以达到两表做join的时候,数据量相对变小的效果。
      ➢ 大小表Join:使用map join让小的维度表( 1000条以下的记录条数)先进内存。在map端完成reduce。
      ➢ 大表Join大表:把空值的key变成-一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
      ➢ countdistinct大量相同特殊值,将值为空的情况单独处理,如果是计算countdistinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行groupby,可以先将值为空的记录单独处理,再和其他计算结果进行union。
      ➢ group by维度过小:采用sum() group by的方式来替换count(distinct)完成计算。
      ➢ 特殊情况特殊处理:在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后union回去。

【面试指导&技巧】
      该问题比较常用,大部分都会问到,所以需要重点掌握。需要能够说出产生数据倾斜的几种情况,然后相对应的如何解决。另外,还需要结合自己项目进行去讲:在哪个业务场景下,因为什么原因产生了数据倾斜,最后是如何解决的。需要在理解SQL优化的基础上,讲一下自己用了哪些SQL优化。
 


1.3.9 Hive的自定义函数实现了什么接口什么方法?

      Hive自定义函数包括三种UDF、UDAF、UDTF:
      (1) UDF(User-Defined-Function)- 进一 出, 继承了org.apache.hadoop.hive.ql.exec.UDF类,并覆写了evaluate方法。
      (2) UDAF(User- Defined Aggregation Funcation)聚合函数,多进一出 。如Count/max/min
      (3) UDTF(User-Defined Table-Generating Functions)一进 多出,如lateral view explore)

【面试指导&技巧】
      自定义函数的分类是基础问题,-般深入问的话,会问你写过什么自定义函数?实现什么功能?其中实现了哪些接口和方法?

 


1.3.10使用Hive-sq| 如何查询A表中B表不存在的数据?

      ➢ select distinct A.ID from A where A.ID not in (select ID from B)
      ➢ select * from A where (select count(1) as num from A where A.ID= B.ID)=0

【面试指导&技巧】
      考察SQL能力,这里只是示例,需要平时加强对SQL的练习。
 


1.3.11 *如何控制Hive中Mapper和Reduce的个数?

  1.控制Hive任务中的map数

      通常情况下,作业会通过input的目录产生-一个或者多个map任务。
      主要的决定因素有: input 的文件总个数,input 的文件大小,集群设置的文件块大小(目前为128M,可在Hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改)
      举例:假设input目录下有1个文件a,大小为780M,那么Hadoop会将该文件a分隔成
7个块(6个128m的块和1个12m的块),从而产生7个map数假设input目录下有3个
文件a,b,c,大小分别为10m, 20m, 130m,那么Hadoop会分隔成4个块( 10m,20m,128m,2m),
从而产生4个map数,即,如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成-个块。


      问题1:是不是map数越多越好?
      答案是否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做-一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。


      问题2:是不是保证每个map处理接近128m的文件块,就高枕无忧了?
      答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

 针对上面的两个问题,我们需要采取两种方式来解决:即减少map数和增加map数。
      (1)如何合并小文件,减少map数?
      假设一个SQL任务:

Select count(1) from popt_ tbaccountcopy_ mes where pt =‘2012-07-04’ ;

      该任务的inputdir /group/p_ sdo_ data/p_ _sdo_ data_ _etl/pt/popt_ tbaccountcopy_ mes/pt =2012-07-04共有194个文件,其中很多是远远小于128m的小文件,总大小9G,正常执行会用194个map任务。Map总共消耗的计算资源: SLOTS_ MILIS_ MAPS= 623,020我通过以
      下方法来在map执行前合并小文件,减少map数:

set mapred.max.split size=100000000;
set mapred.min.split.size.per.node=100000000;
set mapred.min.split.size.per.rack=100000000;
set hive.input.format=org.apache.hadoop.hive.qlio.CombineHiveInputFormat;

      再执行上面的语句,用了74个map任务,map消耗的计算资源: SLOTS_ _MILIS_ MAPS=333,500,对于这个简单SQL任务,执行时间上可能差不多,但节省了一半的计算资源。大概解释一下,100000000表示100M,set hive.input.format org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;这个参数表示执行前进行小文件合并,前面三个参数确定合并文件块的大小,大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩
下的) ,进行合并, 最终生成了74个块。

    (2)如何适当的增加map数?
当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,
来使得每个map处理的数据量减少,从而提高任务的执行效率。假设有这样-一个任务: 

Select data_desc,
count(1),
count(distinct id),
sum(case when...),
sum(case when ...), 
sum(...)
from a group by data_desc

      如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,肯定是比较耗时的,这种情况下,我们要考虑将这-个文件合理的拆分成多个,.这样就可以用多个map任务去完成。

set mapred.reduce.tasks=10;
create table a_1 as
select * from a
distribute by rand(123);

      这样会将a表的记录,随机的分散到包含10个文件的a_ 1表中,再用a _1代替上面sql中的a表,则会用10个map任务去完成。每个map任务处理大于12M (几百万记录)的数据,效率肯定会好很多。
      看上去,貌似这两种有些矛盾,一个是要合并小文件,- 一个是要把大文件拆成小文件,这点正是重点需要关注的地方,根据实际情况,控制map数量需要遵循两个原则:使大数据量利用合适的map数;使单个map任务处理合适的数据量。


2.控制Hive任务的reduce数

       Hive自己如何确定reduce数: reduce个数的设定极大影响任务执行效率,不指定reduce
个数的情况下,Hive 会猜测确定一一个 reduce个数,基于以下两个设定:

hive.exec.reducers.bytes.per.reducer ( 每个reduce 任务处理的数据量,默认为.1000^3=1G)
hive. exec.reducers.max (每个任务最大的reduce数,默认为999)

      计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1)。即,如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;如:

select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt;
/group/p_sdo_data/p_sdo_data_et/pt/popt_tbaccountcopy_mes/pt=2012-07-04 总大小为9G多,因此这句有10个reduce

    调整reduce个数方法- :
     调整hive.exec.reducers.bytes.per.reducer参数的值;

set hive.exec.reducers.bytes.per.reducer-00000000; ( 500M)
select pt,count(1) from popt_ _tbaccountcopy_ mes where pt = '2012-07-04' group by pt;
这次有20个reduce


    调整reduce个数方法二:

set mapred.reduce.tasks = 15;
select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by
pt;这次有15个reduce

    reduce个数并不是越多越好。
    同map一样,启动和初始化reduce也会消耗时间和资源;另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,则也会出现小文件过多的问题;

     什么情况下只有一个reduce?
      很多时候你会发现任务中不管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce 任务;其实只有一个reduce 任务的情况,除了数据量小于hive. exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:
      (1)没有group by的汇总。.
      比如把select pt,count(1) from popt _tbaccountcopy_ mes where pt = 2012-07-04' group bypt;写成select count(1) from popt_ tbaccountcopy_ mes where pt = '2012-07-04'; 这点非常常见,希望大家尽量改写。
      (2) Order by。
      (3)有笛卡尔积。.
      通常这些情况下,除了找办法来变通和避免,暂时没有什么好的办法,因为这些操作都是全局的,所以Hadoop不得不用一个reduce去完成;同样的,在设置reduce个数的时候也需要考虑这两个原则:使大数据量利用合适的reduce数;使单个reduce任务处理合适的数据量。
 

【面试指导&技巧】
      此类问题属于比较深一些的问题,但是很多面试中都会问。需要能够答出mapper 和Reducer是通过什么决定的,如果调优时,如何控制。高分面试必备,需要能够理解文档中内容,理解记忆。

 


1.3.12 *请说明Hive中Sort By, Order By, Cluster By, Distrbute By的作用?

   1.order by

      Hive中的orderby跟传统的sql语言中的orderby作用是-样的,会对查询的结果做一次全局排序,所以说,只有Hive 的sql中制定了order by所有的数据都会到同一个reducer进行处理(不管有多少map,也不管文件有多少的block只会启动- - reducer)。但是对于大量数据这将会消耗很长的时间去执行。这里跟传统的sql 还有一点区别:如果指定了hive.mapred.mode=strict (默认值是nonstrict) ,这时就必须指定limit 来限制输出条数,原因是:所有的数据都会在同一个reducer端进行,数据量大的情况下可能不能出结果,那么在这样的严格模式下,必须指定输出的条数。

   2.sort by

     Hive中指定了sort by,那么在每个reducer端都会做排序,也就是说保证了局部有序(每个reducer 出来的数据是有序的,但是不能保证所有的数据是有序的,除非只有一个reducer) ,好处是:执行了局部排序之后可以为接下去的全局排序提高不少的效率(其实就是做一次归并排序就可以做到全局排序了)。

   3.distribute by和sort by一起使用

      ditribute by是控制map的输出在reducer是如何划分的,举个例子,我们有- -张表,mid是指这个store所属的商户,money是这个商户的盈利,name是这个store的名字执行Hive语句: select mid, money, name from store distribute by mid sort by mid asc, money asC。我们所有的mid相同的数据会被送到同-一个reducer去处理,这就是因为指定了distribute bymid,这样的话就可以统计出每个商户中各个商店盈利的排序了(这个肯定是全局有序的,因为相同的商户会放到同一个reducer去处理)。这里需要注意的是distribute by必须要写在sortby之前。

   4.cluster by

      cluster by的功能就是distribute by和sort by相结合,如下2个语句是等价的:
      select mid, money, name from store cluster by mid
      select mid, money, name from store distribute by mid sort by mid
      如果需要获得与3中语句一样的效果:
      select mid, money, name from store cluster by mid sort by money

【注意】
被cluster by指定的列只能是降序,不能指定asc和desc.

【面试指导&技巧】
问题偏基础。需要能够答出四种排序用法的应用场景和区别。

 


1.3.13请说明Hive中split、coalesce 以及collect list函数的用法?

      1.split将字符串转化为数组,即: split('a,b,c,d', ',")==> ["a","b","c","d"]。
      2.coalesce(Tv1, Tv2, ..) 返回参数中的第-一个非空值;如果所有值都为NULL, 那么返.回NULL。假如某个字段默认是null, 你想其返回的不是null,而是比如0或其他值,可以使用这个函数
      SELECT COALESCE(field_ name,0) as value from table;
      3.collect_ list 将分组中的某列转为-一个数组返回,不去重(列转行函数)。
      select collect_ list(id) from table;
      4.collect_ set 也是将分组中的某列转为-一个数组返回,但是去重。

【面试指导&技巧】
      考察Hive中的函数的使用方法。难度不大。需要增加对SQL的练习。另外还有窗口函数,需要加强练习。
 


1.3.14简要描述数据库中的null,说出null 在Hive底层如何存储,并解释select a.* from t1 a left outer join t2 b on a.id=b.id where b.id is null的含义?

      1.null与任何值运算的结果都是null,可以使用isnull、isnotnull函数指定其值为null情况下的取值。
      2.null 在hive 底层默认是用‘\N'来存储的,可以通过alter table test SET SERDEPROPERTIES('serialization.null.format' = 'a');来修改。
      3.查询出t1表中存在但是t2表中不存在的id相对应的t1表的所有字段。

【面试指导&技巧】
      基础问题。考察null 在Hive中的使用。需要能够讲出null 运算结果,查询方式,以及底层存储。

 


1.3.15 *Hive有哪些保存元数据的方式,每个有什么特点。

    ➢ 内嵌模式。内嵌数据库derby, 安装小,基于Java、 JDBC和SQL标准。
    ➢ 本地模式。MySQL数据库,数据存储模式可以自己设置,持久化好,查看方便。
    ➢ 远程模式。 用于非Java客户端访问元数据库,在服务器端启动MetaStoreServer,客户端利用Thrift协议通过MetaStoreServer访问元数据库。它将 Metastore分离出来,成为-一个独立的Hive服务(Metastore 服务还可以部署多个)。这样的模式可以将数据库层完全置于防火墙后,客户就不再需要用户名和密码登录数据库,避免了认证信息的泄漏。

【面试指导&技巧】
      基础问题。考察Hive元数据的保存方式,主要有三种。- -般我们使用的是本地模式。另外需要了解远程模式。需要能够答出远程模式使用的是Thrift协议。

 


1.3.16生产环境中为什么建议使用外部表?

    1.因为外部表不会加载数据到Hive,减少数据传输、数据还能共享。
    2.Hive不会修改数据,所以无需担心数据的损坏
    3.删除表时,只删除表结构、不删除数据。

【面试指导&技巧】
考查外部表的特点。基础问题。
 


—— 加油,阿仔~

 

你可能感兴趣的:(大数据知识点梳理)