面试准备 -- 大数据Hive相关

1、拉链表 好文

  • 需要查看一件事物从开始到现在的全部状态,比如用户从注册到今天改了几次手机号?

  • 实际应用场景:1、用户数据量很大 2、某些字段经常被更新,其他字段基本不变 3、需求存在查看历史快照

举例:会员订单表:量很大,里面大部分信息不变化,但是会员有效时间会变,需求是:用户想查看自己买了多久的会员,历史订单也需要展示

  • 拉链表设计:一般以天级粒度进行维护,一天修改三次以最后一次状态为准。所以里面很重要的两个column:start_date、end_date

  • 拉链表 和 流水表区别
    拉链表相当于某一天结束的快照,而流水表会将用户的每一条变动都记录下。
    所以,要查询某一天的历史快照,
    select * from user where t_start_date <= '2017-01-02' and t_end_date >= '2017-01-02'

start_date会将0102这一天的历史数据都查出来,end_date会将 0101 - 0101这样的数据过滤掉。

  • UDF、UDAF、UDTF

UDF:一对一
UDAF:多对一(用户自定义 聚合 函数)
UDTF:一对多(用户自定义 表格 函数)

Reference

UDF 继承 + 覆写

// 输入Text  输入Text
将敏感信息隐藏,比如电话号码 11位,取前三位 + 后四位
Text(text1.toString().substring(0, 3) + "...")

// 直接继承 org.apache.hadoop.hive.ql.exec.UDF 这个类
覆写 evaluate 函数

// 创建临时函数
create temporary function string_udf as 'jar包'

UDTF
一行转多行,一般不都是explode + lateral view

1、继承 org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
2、在initialize 定义好输出字段名 和 输出格式
定义第一列名、第一列什么类型,第二列...
3、process 处理这一行,一般split,然后生成数组
4、数组交给forward(数组就相当于一列一列)

UDAF
多行转一行,不常写但是面试常问。。。
可以顺手考察Map、Reduce过程
讲的比较好


  • Hive建模
    1、ODS层:这一层一般都保持原貌,不做修改
    数据采取压缩(采取snappy,速度快,压缩率居中),但是不能切分

已经压缩的格式文件是否可以再分割:可以分割的格式允许单一文件由多个Mapper程序处理,可以更好的并行化。比如说,一个300M的压缩文件上传到hdfs后,会被分成3个block,如果该压缩文件不支持切分的话,那么只会产生一个maptask,这个maptask将会处理全部的3个block。
参考

2、存储格式一般都为ORC(optimized row columnar) 按行分块、按列存储
3、


  • Sqoop
    主要研究:hive → mysql
    1、导出数据存在乱码,排除出应该是ads使用orc格式存储(使用的压缩是snappy)
    -- 还有gzip 这种压缩率很高,但解压、压缩时间过长

2、Sqoop 导出到mysql,null问题
Hive用‘\N’完成存储,mysql则用‘null’,所以需要添加 --input-null-non-string‘\N’ 代表Hive底层‘\N’字符放到数据库中,都是null。
如果不写,只有遇到‘null’和空字符,写到mysql才是null,‘\N’则认为是一个有效字符。

3、导出存在数据一致性问题
因为sqoop依赖mr进行数据导入,所以可能存在个别mr失败,从而导致部分数据load到数据库,开启--staging-table,就可以通过建临时表汇总mr总数据,进而一个transaction load到mysql里面

------------恢复内容结束------------
------------恢复内容开始------------
1、拉链表 好文

  • 需要查看一件事物从开始到现在的全部状态,比如用户从注册到今天改了几次手机号?

  • 实际应用场景:1、用户数据量很大 2、某些字段经常被更新,其他字段基本不变 3、需求存在查看历史快照

举例:会员订单表:量很大,里面大部分信息不变化,但是会员有效时间会变,需求是:用户想查看自己买了多久的会员,历史订单也需要展示

  • 拉链表设计:一般以天级粒度进行维护,一天修改三次以最后一次状态为准。所以里面很重要的两个column:start_date、end_date

  • 拉链表 和 流水表区别
    拉链表相当于某一天结束的快照,而流水表会将用户的每一条变动都记录下。
    所以,要查询某一天的历史快照,
    select * from user where t_start_date <= '2017-01-02' and t_end_date >= '2017-01-02'

start_date会将0102这一天的历史数据都查出来,end_date会将 0101 - 0101这样的数据过滤掉。

  • UDF、UDAF、UDTF

UDF:一对一
UDAF:多对一(用户自定义 聚合 函数)
UDTF:一对多(用户自定义 表格 函数)

Reference

UDF 继承 + 覆写

// 输入Text  输入Text
将敏感信息隐藏,比如电话号码 11位,取前三位 + 后四位
Text(text1.toString().substring(0, 3) + "...")

// 直接继承 org.apache.hadoop.hive.ql.exec.UDF 这个类
覆写 evaluate 函数

// 创建临时函数
create temporary function string_udf as 'jar包'

UDTF
一行转多行,一般不都是explode + lateral view

1、继承 org.apache.hadoop.hive.ql.udf.generic.GenericUDTF
2、在initialize 定义好输出字段名 和 输出格式
定义第一列名、第一列什么类型,第二列...
3、process 处理这一行,一般split,然后生成数组
4、数组交给forward(数组就相当于一列一列)

UDAF
多行转一行,不常写但是面试常问。。。
可以顺手考察Map、Reduce过程
讲的比较好


  • Hive建模
    1、ODS层:这一层一般都保持原貌,不做修改
    数据采取压缩(采取snappy,速度快,压缩率居中),但是不能切分

已经压缩的格式文件是否可以再分割:可以分割的格式允许单一文件由多个Mapper程序处理,可以更好的并行化。比如说,一个300M的压缩文件上传到hdfs后,会被分成3个block,如果该压缩文件不支持切分的话,那么只会产生一个maptask,这个maptask将会处理全部的3个block。
参考

2、存储格式一般都为ORC(optimized row columnar) 按行分块、按列存储
3、


  • Sqoop
    主要研究:hive → mysql
    1、导出数据存在乱码,排除出应该是ads使用orc格式存储(使用的压缩是snappy)
    -- 还有gzip 这种压缩率很高,但解压、压缩时间过长

2、Sqoop 导出到mysql,null问题
Hive用‘\N’完成存储,mysql则用‘null’,所以需要添加 --input-null-non-string‘\N’ 代表Hive底层‘\N’字符放到数据库中,都是null。
如果不写,只有遇到‘null’和空字符,写到mysql才是null,‘\N’则认为是一个有效字符。

3、导出存在数据一致性问题
因为sqoop依赖mr进行数据导入,所以可能存在个别mr失败,从而导致部分数据load到数据库,开启--staging-table,就可以通过建临时表汇总mr总数据,进而一个transaction load到mysql里面

posted @ 2022-07-12 22:02  spongie  阅读(29)  评论(0编辑  收藏  举报