5分钟看懂:如何构建一个数据仓库?

本文详细阐述了数仓建设的七个关键步骤:业务流程梳理、领域划分、指标体系构建、实体关系分析、维度标准化、数仓分层设计和模型开发。通过实例和工具展示,帮助读者理解如何从业务出发,实现高效、标准的数仓建设并避免常见问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实用干货来了!

有朋友私信我,说希望了解数仓的整体建设中的细节及模板。那有啥说的,上干货!

数仓全景图镇楼 

00

建设过程

数仓建模的过程分为业务建模、领域建模、逻辑建模和物理建模,但是这  些步骤比较抽象。为了便于落地,我根据自己的经验,总结出上面的七个步骤:梳理业务流程、垂直切分、指标体系梳理、实体关系调研、维度梳理、数仓分层以及物理模型建立。每个步骤不说理论,直接放工具、模板和案例。

01

业务流程

1

找到公司核心业务流程,找到谁,在什么环节,做什么关键动作,得到什么结果。

2

梳理每个业务节点的客户及关注重点,找到数据在哪。

02

分域/主题

3

决定数仓的建设方式,快速交活,就用自下而上的建设。要全面支撑,就顶层规划,分步实施,交活稍微慢点。

4

同时按照业务领域划分主题域。主题域的划分方法有:按业务流划分(推荐)、按需求分、按职责分、按产品功能分等。

03

指标体系

5

指标的意义在于统一语言,统一口径。所以指标的定义必须有严格的标准。否则如无根之水。

指标可分为原子指标、派生指标和衍生指标,其含义及命名规则举例如下:

6

依照指标体系建设标准,开始梳理指标体系。整个体系同样要以业务为核心进行梳理。同时梳理每个业务过程所需的维度。维度就是你观察这个业务的角度,指标就是衡量这个业务结果 好坏的量化结果。

请注意,此时不能被现有数据局限。如果分析出这个业务过程应该有这个指标,但是没有数据,请标注出来,提出收集数据的需求。

04

实体关系

7

每个业务动作都会有数据产生。我们将能够获取到的数据,提取实体,绘制ER图,便于之后的维度建模。

8

同样以业务过程为起点向下梳理,此时的核心是业务表。把每张表中涉及的维度、指标都整理出来。

05

维度整理

9

维度标准化是将各个业务系统中相同的维度进行统一的过程。其字段名称、代码、名字都可能不一样,我们需要完全掌握,并标准化。

维度的标准尽可能参照国家标准、行业标准。例如地区可以参照国家行政区域代码。

另外,有些维度存在层级,如区域的省、市、县。绝大多数业务系统中的级联就是多层级维度。

06

数仓分层

10

数据仓库一般分为4层,名字可能会不一样,但是其目的和建设方法基本一致:

每一层采用的建模方法都不一样,其核心是逐层解耦。越到底层,越接近业务发生的记录,越到上层,越接近业务目标。

11

依托数仓分层的设计理论,根据实际业务场景,我们就可以梳理出整体的数据流向图。这张图会很清晰的告诉所有人,数据从那来,到哪里去,最终提供什么样的服务。

07

模型建立

12

此时才真正进入纯代码阶段。数仓、ETL工具选型;ETL流程开发;cube的建立;任务调度,设定更新方式、更新频率;每日查看日志、监控etl执行情况等等。

前面梳理清楚了,ETL会变的非常清晰

私货

1、数仓建设必须从业务中来,到业务中去;

2、数仓分层的目的是业务解耦;

3、无论哪种建模方式,其核心是业务实体;

4、按领域建设能快速交活,后遗症将会在2年之后爆发,且难以解决;

5、数仓建设应该把75%的时间投入到设计阶段,如果不是,那你就惨了;

6、数仓本身也可以迭代。

7、传统数仓并没有一种叫做“宽表模型”的模型,大数据时代新诞生的名词,因为很多大数据组件join代价极高。实际上是范式退化。

数据湖,比“数据中台”更需要重视的概念|腾研识者

Flink + Iceberg 全场景实时数仓的建设实践

如何理解《2020年大数据白皮书》的大数据技术最新发展趋势?  原创

基于 Flink SQL 构建流批一体的 ETL 数据集成

万字长文解读最新最全的大数据技术体系图谱!

如何更深刻的理解 “Gartner2020年数据与分析技术十大趋势”的内涵?

点击左下角“阅读原文”查看更多精彩文章,公众号推送规则变了,如果您想及时收到推送,麻烦右下角点个在看或者把本号置顶

  

????分享、点赞、在看,给个3连击吧!????

<think>好的,我现在需要帮助用户理解他们之前提供的Spring Task监听器示例。用户明确说他们没看懂这个示例,所以我得仔细分析哪里可能让他们困惑。 首先,用户可能对Spring Task监听器的基本概念不熟悉。他们可能不知道什么是TaskExecutionListener,或者这个监听器在Spring框架中的作用。我需要先解释这个接口的用途,以及它如何与定时任务结合使用。 接下来,用户提供的代码示例中有两个方法:beforeExecute和afterExecute。我需要分别解释这两个方法的作用,以及它们何时被调用。比如,beforeExecute在任务执行前记录开始时间,afterExecute在任务执行后记录结束时间和状态。用户可能对这两个方法的执行时机不太清楚,或者不知道如何在这些方法中处理日志记录。 另外,代码中使用了ScheduledTaskLogRepository,这是一个自动注入的仓库,用于保存日志到数据库。用户可能对Spring Data JPA不太熟悉,或者不知道如何正确配置这个仓库。需要解释@Autowired的作用,以及如何定义这个Repository接口。 示例中的ScheduledTaskLog类可能也是一个疑问点。用户可能不知道这个实体类的结构,或者需要了解其中包含哪些字段,比如任务名称、开始时间、结束时间、是否成功、错误信息等。我应该简要说明这个实体类的设计,帮助用户构建正确的数据模型。 可能用户还会对异常处理部分有疑问,特别是afterExecute方法中的Throwable参数。需要解释如何在任务执行出现异常时捕获错误信息,并记录到日志中。比如,使用throwable == null来判断任务是否成功,以及如何获取堆栈轨迹。 另外,用户可能对如何将监听器注册到Spring容器中感到困惑。虽然示例中用了@Component注解,但可能需要进一步说明Spring的组件扫描机制,以及如何确保监听器被正确识别和启用。 还有,用户可能想知道这个监听器如何与具体的定时任务关联起来。比如,使用@Scheduled注解的任务是否会自动被这个监听器监听,或者是否需要其他配置。需要澄清TaskExecutionListener在Spring Task中的默认行为,以及是否需要额外的配置步骤。 另外,代码中的Task类可能让用户产生混淆,因为Spring的Task接口可能和用户自己的任务定义不同。需要指出这里的Task是Spring框架中的类型,还是用户自定义的类型,或者是否需要特定的实现。 还有,用户可能对日志的存储和查询有疑问,比如如何访问保存的日志数据,或者如何确保日志记录不会影响主任务的性能。可能需要提到异步记录日志的方法,比如使用@Async注解,或者使用消息队列来解耦。 最后,用户可能希望有一个更完整的示例,包括实体类、Repository接口以及定时任务本身的定义。虽然之前的回答已经提供了部分代码,但补充这些部分可能帮助用户更好地理解整个流程。 总结来说,我需要从监听器的基本概念开始,逐步解释代码中的各个部分,包括接口方法、依赖注入、实体模型、异常处理,以及如何将监听器集成到Spring应用中。同时,要使用简单明了的语言,避免过于技术化的术语,确保用户能够一步步理解整个示例的工作原理和实现方式。</think>我将逐步解释Spring Task监听器的实现原理,并提供一个更完整的示例说明: --- ### 一、核心组件解析 #### 1. `TaskExecutionListener` 接口 ```java public interface TaskExecutionListener { // 任务执行前触发 void beforeExecute(Task task); // 任务执行后触发(无论成功失败) void afterExecute(Task task, Throwable throwable); } ``` - **beforeExecute**:在任务开始前记录**开始时间** - **afterExecute**:在任务结束后记录**结束时间**和**执行结果** --- ### 二、完整实现步骤 #### 步骤1:创建日志实体类 ```java @Entity @Table(name = "scheduled_task_log") public class ScheduledTaskLog { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String taskName; // 定时任务名称 @Column(nullable = false) private LocalDateTime startTime; private LocalDateTime endTime; private Boolean success; // 执行结果 private String errorMessage; @Lob // 大文本字段 private String stackTrace; // 省略getter/setter } ``` #### 步骤2:实现监听器(详细注释版) ```java @Component public class ScheduledTaskListener implements TaskExecutionListener { @Autowired private ScheduledTaskLogRepository logRepository; // 任务开始前执行 @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void beforeExecute(Task task) { ScheduledTaskLog log = new ScheduledTaskLog(); log.setTaskName(task.getName()); // 获取任务名称 log.setStartTime(LocalDateTime.now()); logRepository.save(log); // 先保存初始记录 } // 任务结束后执行(包括异常情况) @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void afterExecute(Task task, Throwable throwable) { // 查询最新未完成的日志记录 ScheduledTaskLog log = logRepository.findTopByTaskNameOrderByStartTimeDesc(task.getName()); log.setEndTime(LocalDateTime.now()); log.setSuccess(throwable == null); // 通过异常存在性判断成功 if (throwable != null) { log.setErrorMessage(throwable.getMessage()); log.setStackTrace(StackTraceUtils.getStackTrace(throwable)); } logRepository.save(log); // 更新记录 } } ``` #### 步骤3:定义Repository接口 ```java public interface ScheduledTaskLogRepository extends JpaRepository<ScheduledTaskLog, Long> { @Query("SELECT l FROM ScheduledTaskLog l " + "WHERE l.taskName = :taskName " + "ORDER BY l.startTime DESC") ScheduledTaskLog findTopByTaskNameOrderByStartTimeDesc( @Param("taskName") String taskName); } ``` --- ### 三、配套定时任务示例 ```java @Component public class DemoTask { // 定时任务定义 @Scheduled(cron = "0 0/5 * * * ?") public void reportTask() { System.out.println("每5分钟执行数据报表生成"); // 实际业务逻辑... } @Scheduled(fixedRate = 60000) public void healthCheck() { System.out.println("每分钟执行健康检查"); // 实际业务逻辑... } } ``` --- ### 四、关键问题解答 #### 1. 如何关联任务与监听器? - **自动生效**:Spring会自动为所有`@Scheduled`任务添加已注册的监听器 - **验证方法**:在`beforeExecute`中打印`task.getName()`,观察控制台输出 #### 2. 事务传播设置的作用? ```java @Transactional(propagation = Propagation.REQUIRES_NEW) ``` - 确保日志记录与业务逻辑在**不同事务**中 - 避免业务事务回滚导致日志丢失 #### 3. 异常处理的注意事项 - **堆栈采集**:推荐使用Spring工具类`StackTraceUtils` - **错误信息截断**:建议限制字段长度 ```java log.setErrorMessage(StringUtils.substring(throwable.getMessage(), 0, 200)); ``` --- ### 五、日志查询示例 ```sql -- 查看最近10条失败记录 SELECT task_name, start_time, age(end_time, start_time) as duration, error_message FROM scheduled_task_log WHERE success = false ORDER BY start_time DESC LIMIT 10; ``` --- ### 六、扩展建议 1. **性能监控**:添加`execution_time`字段记录耗时 ```java Duration duration = Duration.between(log.getStartTime(), log.getEndTime()); log.setExecutionTime(duration.toMillis()); ``` 2. **报警机制**:连续失败N次时触发通知 3. **日志优化**:添加索引提升查询效率 ```sql CREATE INDEX idx_task_start ON scheduled_task_log(task_name, start_time); ``` 通过这个监听器实现,您可以完整追踪每个定时任务的执行生命周期。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值