ETL工程师常见面试题1

1.数据你们公司数据量有多大

增量数据10万+  全量数据10亿+

2.数据仓库的架构(数据仓库的分层)分三层

我们将数据模型分为三层:数据运营层( ODS )、数据仓库层(DW)和数据应用层(APP):
ODS层存放的是接入的原始数据,DW层是存放我们要重点设计的数据仓库中间层数据,APP是面向业务定制的应用数据。

一、数据运营层:ODS(Operational Data Store) “面向主题的”数据运营层,也叫ODS层,是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的 ETL 之后,装入本层。本层的数据,总体上大多是按照源头业务系统的分类方式而分类的。
一般来讲,为了考虑后续可能需要追溯数据问题,因此对于这一层就不建议做过多的数据清洗工作,原封不动地接入原始数据即可,至于数据的去噪、去重、异常值处理等过程可以放在后面的DWD层来做。
二、数据仓库层:DW(Data Warehouse) 数据仓库层是我们在做数据仓库时要核心设计的一层,在这里,从 ODS 层中获得的数据按照主题建立各种数据模型。DW层又细分为 DWD(Data Warehouse Detail)层、DWM(Data WareHouse Middle)层和DWS(Data WareHouse Servce)层。
1. 数据明细层:DWD(Data Warehouse Detail)
该层一般保持和ODS层一样的数据粒度,并且提供一定的数据质量保证。同时,为了提高数据明细层的易用性,该层会采用一些维度退化手法,将维度退化至事实表中,减少事实表和维表的关联。
另外,在该层也会做一部分的数据聚合,将相同主题的数据汇集到一张表中,提高数据的可用性,后文会举例说明。
2. 数据中间层:DWM(Data WareHouse Middle)
该层会在DWD层的数据基础上,对数据做轻度的聚合操作,生成一系列的中间表,提升公共指标的复用性,减少重复加工。
直观来讲,就是对通用的核心维度进行聚合操作,算出相应的统计指标。
3. 数据服务层:DWS(Data WareHouse Servce)
又称数据集市或宽表。按照业务划分,如流量、订单、用户等,生成字段比较多的宽表,用于提供后续的业务查询,OLAP分析,数据分发等。
一般来讲,该层的数据表会相对比较少,一张表会涵盖比较多的业务内容,由于其字段较多,因此一般也会称该层的表为宽表。
在实际计算中,如果直接从DWD或者ODS计算出宽表的统计指标,会存在计算量太大并且维度太少的问题,因此一般的做法是,在DWM层先计算出多个小的中间表,然后再拼接成一张DWS的宽表。由于宽和窄的界限不易界定,也可以去掉DWM这一层,只留DWS层,将所有的数据在放在DWS亦可。
三、数据应用层:APP(Application) 在这里,主要是提供给数据产品和数据分析使用的数据,一般会存放在 ES、PostgreSql、Redis等系统中供线上系统使用,也可能会存在 Hive 或者 Druid 中供数据分析和数据挖掘使用。比如我们经常说的报表数据,一般就放在这里。
四、维表层(Dimension) 最后补充一个维表层,维表层主要包含两部分数据:
高基数维度数据:一般是用户资料表、商品资料表类似的资料表。数据量可能是千万级或者上亿级别。
低基数维度数据:一般是配置表,比如枚举值对应的中文含义,或者日期维表。数据量可能是个位数或者几千几万。

  ods:把业务系统的数据抽取到数据仓库里(财务系统 核心业务系统 、客户关系系统 、人力资源管理系统)
  dw:ods层数据清洗转换之后存放到dw层(去除后续不需要的字段 去重 去空格、码值转换 统一字段类型)
  App:dw层的数据根据业务需求的指标进行存储过程的编写,用作后续分析使用(编写分析报告 制作报表)

3.在工作中写过那些表

资产负债表、利润表、现金流量表、固定资产明细表等

4.数据库sql常见优化方法

下面我们就聊一聊sql优化的一些常见方法:

1)尽量不要用select * from table,除非需要返回数据库表的全部字段,否则不要返回用不到的任何字段。因为select * 会导致全表扫描,效率比较低。

2)where子句及order by涉及的列尽量建索引,不一定要全部建索引,依业务情形而定。对于多条where子句都用到的列,建议建索引。索引并不是越多越好,索引固然可以提高相应的select的效率,但同时也降低了insert及update 的效率。

3) 尽量避免在 where 子句中使用 != 或 <> 操作符,否则引擎将会放弃使用索引而进行全表扫描。 对于不等于这种情况,可考虑改为范围查询解决。

4)尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,引擎将放弃使用索引而进行全表扫描,如:

select id from person_info where age=10 or name= '张三';

可以这样查询:

select id from person_info where age = 10
union all
select id from person_info where name= '张三'

5)尽量避免在 where 子句中对字段进行 null 值判断,因为空判断将导致全表扫描,而不是索引扫描。 对于空判断这种情况,可以考虑对这个列创建数据库默认值。如:

//nu11判断将会导致全表扫描
select * from person info where name is null;
//可以考虑在经常需要nul1值判断的列,设为默认值,例如空字符串
select * from person info where name = '';

6)in 和 not in 也要慎用,否则会导致全表扫描,如:

select id from person_info where age in(1,2,3)

对于连续的数值,能用 between 就不要用 in 了:

select id from person_info where age between 1 and 3

很多时候用 exists 代替 in 是一个好的选择:

select age from a where age in(select age from b)

用下面的语句替换:

select age from a where exists(select age from b where b.age=a.age);

7)尽量避免左右模糊查询,这样会导致索引失效,进而全表查询,如:select id from person_info  where name like ‘%abc%’,可以使用右侧模糊查询,这样是可以索引查找的,如:select id from person_info  where name like ‘abc%’;

8)如果在 where 子句中使用参数或对字段进行表达式操作,也会导致全表扫描,如:

select id from person_info  where age/2 = 10

应改为: select id from person_info   where age= 10*2;

9)应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。函数、算术运算或其他表达式运算通常将导致全表扫描, 对于这种情况,可以考虑冗余部分数据到表中。

10)在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

11)update 语句,如果只更改1、2个字段,不要update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

12)对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

13)select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。可以改为select count(id) from table。

14)尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。

15)尽可能的使用varchar代替char,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

sql语句尽量用大写 select句中避免使用* 减少访问数据库的次数 Where条件筛选一般在索引列
带有union、minus、intersect的sql语句都可以用其他方式重写 尽量多使用commit 优化group
by可以通过将不需要的记录在group by之前过滤掉 用where子句替换having子句 用索引提高效率 用>=替代>
避免在索引列上使用not,避免在索引列进行计算

5.说一下表 分区 

表分区是一种数据库管理技术,用于将大表按照一定的规则划分成更小的、更易管理的子集,
每个子集被称为分区。表分区通常能够提高查询性能、简化数据维护和管理,以及改善数据存储的效率。以下是一些表分区的常见概念和用法:

1. **范围分区(Range Partitioning):**
   - 按照列的范围值进行划分。例如,按照日期范围将数据划分为每个月或每年一个分区。

2. **列表分区(List Partitioning):**
   - 按照列的离散值进行划分。例如,按照国家或地区将数据划分为不同的分区。

3. **哈希分区(Hash Partitioning):**
   - 使用哈希函数将数据均匀地分布到多个分区中,通常用于均匀分散数据负载的情况。

4. **散列子分区(Subpartitioning):**
   - 在每个分区内再进行进一步的分区,通常是在范围、列表、或哈希分区的基础上。

5. **复合分区(Composite Partitioning):**
   - 结合多种分区策略,例如先按照范围分区,然后在每个范围内按照列表分区。

6. **分区键(Partition Key):**
   - 用于指定分区的列或列集合。分区键的选择是关键的,它直接影响到数据的分布和查询性能。

7. **分区表维护:**
   - 支持动态增加和删除分区,使得表的维护更加灵活。这对于大型表的数据管理和维护提供了更好的控制。

8. **分区索引(Partitioned Index):**
   - 与分区表一起使用的索引,以提高对分区表的查询性能。

表分区的优势在于可以减少查询时需要扫描的数据量,提高查询效率,并且简化数据的维护和管理。然而,表分区并不是适用于所有情况的解决方案,需要根据具体的业务需求和数据库使用情况来决定是否使用分区表。在使用表分区时,确保选择适当的分区策略和分区键,以充分发挥分区的优势。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值