数仓相关
数仓小思考
1.为什么使用关系型存储用户业务数据
RDMS(关系型数据库)是基于OLTP(online transaction process在线事务处理)设计,重事务和在线处理
2.用户行为数据和用户业务数据的区别
用户行为数据侧重于记录事件,用户业务数据侧重记录完整的事实
3.为什么采用json存储用户行为数据
- 用户行为数据低价值密度,记录周期长,结构复杂
- json格式比xml少了标志类信息,占用空间小。比csv等文本文件多了结构信息,方便管理。
4.为什么采用sqoop采集业务数据
sqoop针对关系型数据库RDMS与HDFS之间的数据导入导出,采用批量的方式进行数据传输。
业务场景的需求
5.为什么采用双层flume架构
- 安全性,分割内外网
- 中间加kafka对数据进行削峰,同时也可以对NN的请求进行负载均衡
- 后续实时计算要求必须使用kafka对数据进行分流(使用flume进行分流严重影响程序的健壮性)
- 分层解耦,方便管理
-—————————————————————————————更新—————————————————————————————————————
6.数仓分层每一层用来做什么
- O(original)DS层: 原始数据存储层 原始数据不做处理,保持原貌,直接导入!
分区表,以数据导入的日期作为分区字段- DWD(detail)层: 数据明细存储层
将原始数据展开明细!
展开明细时,通常会进行ETL操作!
将维度表进行维度退化!
将敏感数据脱敏!
分区表,以数据导入的日期作为分区字段- DWS(service)层: 数据服务存储层 为ads层提供数据服务! 将ADS层需要的数据,每天聚合!
分区表,以数据导入的日期作为分区字段- DWT(topic)层: 数据主题存储层 为ads层提供数据服务! 将ADS层需要的数据,累积聚合!
全量表!每天需要更新表中的字段的值!- A(application)DS层: 应用数据存储层 直接对接应用程序!
全量表!将每天统计得到的结果插入到表中即可!
7.维度建模的常见模型及特征
- 星型模型: 维度表直接关联在事实表上,最多只需要join一次就可以查询到想查的维度信息!
- 星座模型: 本质还是星型模型!在这个模型中,有多个事实表,存在多个事实表共用一个维度表的情况!
- 雪花模型: 维度表间接关联在事实表上,可能需要join多次才可以查询到想查的维度信息!
8.什么是范式?不遵循范式会有什么后果?
范式: 在建模时,需要遵循的规范和模式!建模的一种约束!
不遵循范式,会导致建模不严禁,可能会造成数据的冗余,带来额外的存储开销!在更新数据时,可能造成不一致性!第一范式:要求属性不可切割!
第二范式: 要求不能存在部分函数依赖!
第三范式: 不能存在传递函数依赖!
9.事实表与维度表及特征
事实表: 表中记录的是一个事实!
3w + 度量 + 可选维度,表中的字段数量较少!
事实随着时间的推移,会不断增加,表的体量随着时间推移,不断变大!维度表: 表中记录的一般是对事实的描述!
表中的字段数量多,可以从多个角度描述事实!
表中的记录数量少,表的体量随着时间推移,变化不大,相对固定!
10.Sqoop的使用场景是什么?工作原理是什么?
将关系型数据库中的数据导入导出到HDFS! 用于批量离线数据的导入和导出!
原理: 将sqoop命令转换为MR作业,Job只有mapper!
11.使用Sqoop同步数据时,怎样选择同步方式?
数据的同步方式,主要取决于数据量!
数据量大: 只能选择增量同步!
数据量小: 增量 或 全量!
如果数据,有可能被改变,同步时,可以选择同步新增和变化的数据!
12.Flume的使用场景是什么?
用于对日志数据的高效收集,聚合,传输等!一般用于流式数据的作业场景!
13.什么时候需要创建分区表
分区表的目的是为了分散数据,将目录中的数据,在次分散到多个分区目录
- 因此数据量大时可以考虑分区
- 如果在查询时,经常按照某个字段进行过滤,可以将过滤查询的字段作为分区字段,自然要将表改为分区表
14.Spark On Hive 与 Hive On Spark
- SparkSql:spark提供的一个模块,模块支持使用SQL语言及spark提供的DF,DS,API进行数据处理
-Spark On Xxxx 是SparkSql的一个使用场景
- Spark On Hive : spark程序,用了SQL | DF | DS ,处理的数据是用 Hive 管理起来的数据 !
- Spark On Xxxx : spark程序,用了SQL | DF | DS ,处理的数据是用 Xxxx 管理起来的数据 !
- Hive On Spark:使用 Hive 作为分析计算工具,依赖于Spark,配置Hive Job 的执行引擎为Spark
- 类似的还有Hive On MR | tez | Spark
-——————————————————————————————更新2———————————————————————————————————————
15.ODS层表为什么要指定输入格式为com.hadoop.mapred.DeprecatedLzoTextInputFormat
表的输入格式和表中存储数据的格式相关,输入格式的作用是为select语言提供一个输入格式,以便于读取表中的数据!
ODS层表中存储的数据格式为 textfile ,但是使用了lzo压缩,为了可以正常读取和切片数据文件,必须设置为 DeprecatedLzoTextInputFormat!
16.ODS层表能否切片?为什么?
能否切片,主要取决于数据的存储格式!如果数据存储的是textfile,还要进一步判断文件的压缩格式是否支持切片!
- textfile: 一般情况下,可切。
如果采取了压缩,还需要查看压缩格式是否可切!
如果采取了lzo压缩,在切片时,需要有索引文件,才能切片!- sequenceFile: 都可切
- parquet: 都可切
- orc: 都可切
17.什么情况需要把Hive的默认输入格式由CombineHiveInputFormat改为HiveInputFormat
读取的表中,除了数据还有其他文件,不希望其他文件作为数据被读入,就需要设置!
18.ODS层表的建模过程
- 表创建的是external 表
- ods层表的特点是直接将采集的数据导入,不做修改,因此ods层表的字段个数,数量和顺序都需要参考采集数据中字段的数量,个数,顺序,类型!
- ods层数据是每日导入,因此建表使用分区表,指定导入数据的日期作为分区字段
- ods层所有的数据都是 textfile + lzo压缩,
因此指定inputformat为DeprecatedLzoTextInputFormat- 指定表的存储位置为指定的位置
- ods层的业务数据,每个字段都是使用\t分割,使用row format指定每行的分隔符
19.shell中单引号,双引号的作用和使用的注意事项
单引号和双引号都是在需要将一些特殊字符例如空格,作为一个字符串的整体时,使用!
单引号中 不 会 脱 义 , 双 引 号 中 不会脱义,双引号中 不会脱义,双引号中会脱义,会被认为是引用一个变量!注意事项:如果最外层是双引号,那么其中字符串的 都 会 被 脱 义 , 如 果 最 外 层 是 单 引 号 , 都会被脱义,如果最外层是单引号, 都会被脱义,如果最外层是单引号,不会被脱义
20.事实表的分类,每种不同类型事实表的特征和数据的导入方式
事务型事实表: 如果一个事实,一旦发生,不会被修改,那么这个事实的表就是事务型事实表
同步数据时,只需要同步新增的数据!
插入数据: insert overwrite 某个分区
周期型快照事实表: 确定一个事实快照的采样周期,在周期结束时,使用快照的形式,记录事实。
核心:确定采样的周期
插入数据: insert into 某个表
累积型快照事实表: 在事实的生命周期中,只对几个关键的采样点感兴趣,希望以累积的形式呈现事实变化趋势,采取累积型快照事实表!
插入数据时,涉及更新操作: insert overwrite (old + new )
21.简述HiveOnSpark的运行原理
HiveOnMR : MR不支持DAG运算!复杂的hql,可能会被解析为多个job,多个job根据依赖关系依次运行!
HQL -----> YARN上提交一个 JobSet(多个Job)
HiveOnSpark : Spark支持DAG运算!
App: 包含SparkContext的程序,称为app!
Job: 每提交一次行动算子,这个行动算子被初始化为一个Job!Job需要在app中运行!
HQL ------> spark Job
第一次执行一个HQL语句时,会先在集群上提交一个App.这个App就一直在YARN上运行!
Hive客户端,会保持和App的一个连接,称为一个session(回话)!
只要hive客户端不关闭,session一直保持!
Hive客户端,每执行一个HQL,将hql发送给app,app根据HQL对应的模版,运行对应的job!
HiveOnTez: 支持DAG运算!
第一次执行一个HQL语句时,会先在集群上提交一个App.这个App就一直在YARN上运行!
Hive客户端,会保持和App的一个连接,称为一个session(回话)!
区别于spark,这个session会有默认的超时时间(30s),一旦30s不再提交HQL,session关闭,
app也会stop!
-————————————————————————————-更新3————————————————————————————————————————-
22.数仓中向表中导入数据的方式以及区别是什么?
- load加载方式: 不走Job!
如果是本地的文件,上传到表的目录中!
如果是HDFS的文件,移动到表的目录中!
手动上传和load的区别:
如果是全量表,没有任何区别!
如果是分区表,load操作会生成分区的元数据!
如果是手动上传,必须修复表的元数据: msck repair table 表名
- insert插入数据方式: 走Job!
一些特定操作只能使用Insert!
例如: 创建一个分桶表!
表中的数据存储格式不是textfile格式!
23.动态分区和静态分区的使用场景和作用
动态分区和静态分区的作用都是向表的分区中插入数据!
场景: 如果插入的数据都是向同一个分区插入,可以使用静态分区!
如果插入的数据,需要向不同的分区插入,只能使用动态分区!
24.lateral view的作用
如果需要将UDTF函数返回的数据和其他列一起查询,必须使用lateral view
25.如何自定义UDTF?
- 继承GenericUDTF
- 实现Initialize,对函数的入参进行检查,返回函数返回的每行的object inspector
- 通过process()对输入的数据进行处理,调用forward()输出
26.如何创建函数?自己创建的函数和系统函数有什么区别?
永久函数: create [temporary] function 函数名 as ‘函数对应的全类名’
自己创建的函数,属于元数据,有库的范围!如果要跨库调用,必须加库名.函数名!
27.如下命令
hive —hivevar str={“name”:“大郎”,“sex”:“男”,“age”:“25”,“wife”:[{“name”:“小潘”}]}运行的环境中请问如何获取小潘?
select get_json_object('${str}','$.wife[0].name')
-———————————————————————————————更新4————————————————————————————————————
28.什么样的表适合做成拉链表?
缓慢变化的维度表, 需要记录表中每条数据的变化情况
29.累积型快照事实表如何分区?如何导入数据?
按照事实发生的起始时间,进行分区!
步骤: ①查询数据的哪些分区在更新时,会被影响
②查询出受影响分区的数据
③查询出要导入的新的数据
④新老交替
⑤覆盖导入表中
30.ods层的跨天支付问题总结
- 如果需要查询当天支付订单中的订单信息,只需要 ods_payment_info left join ods_order_info(当天)
- 如果需要查询当天支付订单中的订单详情信息,需要 ods_payment_info left join ods_order_detail(当天和前一天分区)
还没有评论,来说两句吧...