数据开发/数仓工程师上手指南(六)CDM-DWD层搭建规范及流程

news2024/11/15 9:16:06

前言

前言这次想聊点出工作技术方面外的内容,DWD该层在写CDM层的时候就提及很多次了大差不差,近期让我感悟较多的话那是那句宁愿犯错也不愿意什么都不做,说这句话如果能够做到,那么执行力也远超过其他人,能力和远见也会在历练中得到充分的成长。但是这也是要区分领域来说,一般我认为这句话的适用程度在自己的技术工作领域上面,可以去尝试换个技术,换个主题或者是从事新的第二事业,而不是在目前大环境下面去犯错,因为现在给你的容错机会极少,凡事还是要注意量与度。好了废话不多说,现在开始DWD层的数据建模。

明细粒度事实层(DWD)

明细粒度事实层(DWD)在数据仓库中是非常重要的一个层次,其设计与企业的业务过程紧密相关。通过理解DWD层的特点和设计方法,可以更好地支持企业的数据分析需求。

业务过程驱动建模

  • DWD层以具体的业务过程为核心,通过分析业务过程的特点和需求,构建出最细粒度的明细事实表。这种建模方法能够更好地反映实际业务中的数据流动和变化。

宽表化处理

  • 在设计明细粒度事实表时,可以对某些重要的维度属性字段进行适当冗余,即将这些字段直接存储在事实表中。这种处理方式可以加快查询速度,减少关联查询的复杂性。

我们以招标业务案例为例,在招标业务过程中,DWD层建模可以帮助企业深入分析和优化其招标活动:

在一个典型的招标业务过程中,主要步骤包括:

  1. 招标公告发布:企业发布招标公告,邀请供应商参与投标。
  2. 投标文件提交:供应商根据公告要求提交投标文件。
  3. 评标:企业评估投标文件,选择合适的供应商。
  4. 合同签署:与中标供应商签署合同。

1.业务过程驱动建模示例

事实表设计

  • 粒度:每个投标的单独记录
  • 维度:
    • 时间维度:记录投标的时间点(提交日期、评标日期、合同签署日期)
    • 供应商维度:参与投标的供应商信息(供应商ID、供应商名称)
    • 项目维度:涉及的项目信息(项目ID、项目名称)
    • 状态维度:投标状态(已提交、评标中、中标、未中标)

事实表结构

投标ID项目ID供应商ID提交日期评标日期中标日期投标金额状态ID

度量

  • 投标金额:可以汇总统计各项目的总投标金额、各供应商的投标金额等。

2.宽表化处理

宽表化处理示例

在事实表中进行适当的冗余,减少关联查询,提升查询效率。例如,将供应商和项目的一些重要属性直接存储在事实表中。

宽表化处理后的事实表结构

投标ID项目ID项目名称供应商ID供应商名称提交日期评标日期中标日期投标金额状态ID
  • 项目名称供应商名称等重要属性冗余存储在事实表中,以加快查询速度。例如,在查询特定供应商在某个项目中的投标记录时,无需再关联查询项目和供应商维度表。

3.事实表的设计

3.1粒度的定义

  • 粒度表示一条记录在事实表中所表达的业务细节程度。选择合适的粒度是设计事实表的关键,通常可以通过以下两种方式来确定:
    • 维度属性组合:通过多个维度属性的组合来定义粒度。
    • 具体业务含义:直接基于业务过程的需求来定义粒度。

在招标业务中,我们可以通过多个维度属性的组合来定义粒度。例如,每一个投标记录可以由以下几个维度属性组合定义其粒度:

  • 项目ID:标识哪个项目正在招标。
  • 供应商ID:标识哪个供应商提交了投标。
  • 投标日期:标识投标提交的具体时间。

这种粒度定义确保每一条记录都代表一个特定供应商在某一项目中的一次投标行为。

具体业务含义

从业务的角度来看,每个记录代表着一项具体的业务活动——即一个供应商对一个项目的投标。这种业务导向的粒度定义有助于直接反映业务过程中的实际交易活动。

3.2事实的类型

  • 可加性事实:可以在所有相关维度上进行汇总,如销售额、数量等。
  • 半可加性事实:只能在特定维度上汇总,如库存只能在地点或商品维度上汇总。
  • 不可加性事实:如比率型数据,需要通过分解为可加组件进行汇总。

在招标过程中,不同的度量数据可以属于不同的事实类型:

  • 可加性事实
    • 投标金额:可以对不同维度(如时间、项目、供应商)进行汇总以了解总的投标金额。
  • 半可加性事实
    • 投标数量:虽然可以对项目和供应商维度进行汇总,但对时间维度的汇总(例如跨月)可能不总是有意义,因为投标活动可能仅限于特定时间段。
  • 不可加性事实
    • 投标成功率:例如,一个供应商在某项目上的中标率。这些比率不能简单地通过加总来计算,而需要通过分解为可加性组件,如成功和失败的投标次数来推算。

3.3维度退化

维度退化示例

在设计事实表时,一些维度信息可以直接存储在事实表中作为退化维度,以提高查询效率。例如:

  • 项目名称:与项目ID一起存储在事实表中,便于快速查询而不需要关联到项目维度表。
  • 供应商名称:与供应商ID一起存储。

退化维度事实表结构

投标ID项目ID项目名称供应商ID供应商名称投标日期投标金额投标状态

通过这种设计,用户在查询某个供应商的所有投标记录时,可以直接通过退化维度字段快速获取相关信息,而无需对维度表进行复杂的关联查询。这种设计能够显著提高查询性能,尤其在处理大量数据时。

应用场景
  • 快速获取某个供应商在所有项目中的投标金额
  • 统计特定时间段内所有项目的总投标金额和中标率
  • 分析不同项目的竞争情况,通过投标次数和金额来评估市场热度

4.明细粒度事实层(DWD)的类型

在招标业务中,我们可以根据不同的业务需求定义明细粒度事实层(DWD)的类型,以满足对数据分析的不同要求。

4.1. 事务事实表

定义

  • 事务事实表用于描述招标业务过程中的原子事件,记录每次投标活动的详细信息。

示例

在招标业务中,事务事实表可以记录每个供应商对每个项目的每次投标。表结构可能包括以下字段:

投标ID项目ID供应商ID投标日期投标金额投标状态评标日期中标日期

应用场景

  • 分析每个供应商的投标行为,例如某个供应商在过去一段时间内的所有投标记录。
  • 计算每个项目的投标总金额和投标次数。

4.2. 周期快照事实表

定义

  • 周期快照事实表在固定时间间隔内记录招标业务的状态。例如,每月记录一次所有正在进行的招标项目的状态。

示例

在招标业务中,可以每月记录所有项目的投标状态和金额,以监控项目进展和市场动态。表结构可能包括:

月份项目ID总投标金额投标次数中标次数平均投标金额

应用场景

  • 评估每月的招标活动情况,帮助管理层了解市场变化趋势。
  • 分析不同月份的投标活跃度和成功率。

4.3.累积快照事实表

定义

  • 累积快照事实表记录从招标项目开始到结束之间的关键步骤和状态,反映整个项目生命周期的变化。

示例

在招标业务中,可以用累积快照事实表来跟踪每个项目的全过程,包括从招标公告发布到合同签署的各个关键步骤。表结构可能包括:

项目ID公告日期投标开始日期投标结束日期评标日期中标日期合同签署日期投标总金额

应用场景

  • 跟踪每个招标项目的生命周期,识别关键步骤和瓶颈。
  • 统计项目从启动到完成所需的平均时间,以优化招标流程。

明细粒度事实表整体设计流程如下图所示:
在这里插入图片描述
在一致性度量中已定义好了交易业务过程及其度量。明细事实表注意针对业务过程进行模型设计。明细事实表的设计可以分为四个步骤:选择业务过程、确定粒度、选择维度、确定事实(度量)。粒度主要是在维度未展开的情况下记录业务活动的语义描述。在建设明细事实表时,需要选择基于现有的表进行明细层数据的开发,清楚所建表记录存储的是什么粒度的数据。

5.明细粒度事实表设计原则

在招标业务中设计明细粒度事实表时,遵循以下原则可以确保数据模型能够有效支持业务需求并优化数据分析的效率。下面详细说明这些设计原则,并结合招标业务进行解释:

5.1一个明细粒度事实表仅和一个维度关联

理解:每个明细粒度事实表应该聚焦于一个核心业务事件,通常只关联一个关键维度。

在招标业务中的应用:例如,一个投标事务事实表可以仅与项目维度关联,因为每个投标记录主要围绕特定项目展开。其他维度(如供应商、时间)作为辅助维度进行描述。

5.2尽可能包含所有与业务过程相关的事实

理解:事实表应尽量全面地反映业务过程中的所有重要数据,以支持多样化的分析需求。

在招标业务中的应用:投标事务事实表应包括所有与投标相关的度量,如投标金额、投标次数、投标状态等,以便进行全面分析。

5.3只选择与业务过程相关的事实

理解:仅选择那些直接与业务过程相关的度量和属性,避免包含无关的数据。

在招标业务中的应用:事实表中仅保留与投标活动直接相关的事实,如投标金额中标状态,而不是其他不相关的信息,如供应商的财务报表数据。

5.4分解不可加性事实为可加的组件

理解:对于无法直接相加的事实,尝试将其分解为可以汇总的组件,以便更容易进行分析。

在招标业务中的应用:将投标成功率分解为成功投标次数总投标次数,这样可以通过这两个可加性事实计算出成功率。

5.5在选择维度和事实之前必须先声明粒度

理解:明确事实表的粒度以确保数据的唯一性和完整性,防止不同粒度的事实混杂在一起。

在招标业务中的应用:在创建投标事务事实表之前,声明其粒度为“每个供应商对每个项目的单次投标”,确保表内记录的细节程度一致。

5.6在同一个事实表中不能有多种不同粒度的事实

理解:保持事实表的粒度一致,以避免数据混乱和分析错误。

在招标业务中的应用:确保投标事务事实表中所有记录的粒度一致,例如每条记录代表一个具体的投标事件,而不是有些记录代表单个投标,有些代表项目整体。

5.7事实的单位要保持一致

理解:确保事实表中的所有度量使用一致的单位,以避免在数据分析时出现误解或错误。

在招标业务中的应用:确保所有与金额相关的度量(如投标金额、预算金额)使用相同的货币单位。

5.8谨慎处理Null值

理解:处理Null值时需要小心,以避免在数据计算和分析中出现问题。

在招标业务中的应用:在投标事务事实表中,对于可能出现Null值的字段(如评标日期),可以使用默认值或注释进行处理,以确保分析结果的准确性。

5.9使用退化维度提高事实表的易用性

理解:退化维度是直接存储在事实表中的维度信息,可以加快查询速度和简化数据模型。

在招标业务中的应用:将项目名称供应商名称作为退化维度存储在投标事务事实表中,使得在查询时无需频繁关联维度表,提升查询效率。

通过遵循这些设计原则,可以在招标业务中创建一个高效且易用的明细粒度事实表,帮助企业更好地分析和优化其招标活动。

6.DWD表命名规则

模型层次表命名规范实例表明实例表说明
dwddwd_主题域_可选的主题_事实表相关描述_加工频率+抽取方式dwd_par_trader_detail_dfdwd为模型层次、par为主题域名、trader为商户主题名、detail为表描述、d代表加工频率、f代表全量抽取方式

例如: dwd_asale_trd_ordcrt_trip_di(A电商公司航旅机票订单下单事实表,日刷新增量)及dwd_asale_itm_item_df(A电商商品快照事实表,日刷新全量)。

  • 交易商品信息事实表:dwd_asale_trd_itm_di。
  • 交易会员信息事实表:dwd_asale_trd_mbr_di。
  • 交易订单信息事实表:dwd_asale_trd_ord_di。

7.招标业务域订单提交事务事实表设计

7.1确定粒度

  • 粒度:每条记录代表一次订单提交事件
    • 每个订单由特定供应商对特定项目的单次提交构成。

7.2关键维度

  • 时间维度:捕捉订单提交、审核、批准等时间点。
  • 供应商维度:描述订单提交的供应商信息。
  • 项目维度:记录订单所属的项目。
  • 产品维度:包含订单中涉及的产品信息。
  • 状态维度:跟踪订单在流程中的状态(如已提交、已审核、已批准等)

7.3事实

  • 订单金额:订单的总金额。
  • 产品数量:订单中设计的产品数量。
  • 折扣金额:任何适用的折扣金额。
  • 税费:订单中涉及的税费。
  • 订单状态:订单的当前状态。

7.4退化维度

  • 订单ID:用于唯一标识每个订单。
  • 供应商名称:便于快速查询而无需关联供应商维度表。
  • 项目名称:便于快速查询而无需关联项目维度表。

7.5事务事实表结构

订单ID项目ID项目名称供应商ID供应商名称提交日期审核日期批准日期订单金额产品数量折扣金额税费订单状态

设计细节说明:

7.5.1粒度一致性:
  • 每条记录只代表一个具体的订单提交事件,确保粒度的一致性。
7.5.2数据全面性
  • 包含所有与订单提交过程相关的度量(如金额、数量、折扣等),以支持全面的业务分析。
7.5.3退化维度
  • 使用退化维度(订单ID、项目名称、供应商名称)提高查询效率,减少复杂关联。
7.5.4处理NULL值
  • 确保日期字段(如审核日期、批准日期)对未完成的步骤能够正确处理Null值,通过设定默认值或注释来防止数据分析误差。
7.5.5事实单位一致性
  • 确保所有货币相关的事实(如订单金额、折扣金额、税费)适用同一的货币单位。

7.6应用场景

  • 订单提交效率分析:
    • 通过分析提交、审核、和批准日期,评估订单处理的效率和瓶颈。
  • 供应商表现评估:
    • 统计不同供应商的订单提交量和成功率,帮助选着优质供应商。
  • 项目成本管理:
    • 分析每个项目的订单金额和数量,监控项目预算和支出情况。

7.7SQL建表语句

在实现招标业务域的订单提交事务事实表时,我们需要编写SQL建表语句,以及定义数据流向、首日装载和每日装载的流程。

7.7.1SQL建表语句

订单提交事务事实表:

CREATE TABLE order_submission_facts (
    order_id INT PRIMARY KEY,
    project_id INT,
    project_name VARCHAR(255),
    supplier_id INT,
    supplier_name VARCHAR(255),
    submission_date DATE,
    review_date DATE,
    approval_date DATE,
    order_amount DECIMAL(18, 2),
    product_quantity INT,
    discount_amount DECIMAL(18, 2),
    tax_amount DECIMAL(18, 2),
    order_status VARCHAR(50),
    FOREIGN KEY (project_id) REFERENCES projects(project_id),
    FOREIGN KEY (supplier_id) REFERENCES suppliers(supplier_id)
);

7.7.2数据流向

数据流动说明

1.数据源:

  • 原始数据来自业务系统中的订单提交记录、项目管理系统和供应商管理系统。

2.ETL流程:

  • 抽取:从源系统提取订单、项目和供应商相关数据。
  • 转换:
    • 规范化数据格式、项目和供应商相关数据。
    • 计算需要的度量,如折扣和税费。
  • 加载:
    • 将清洗和转换后的数据加载到数据仓库的订单提交事务表中。

数据流向图示例:

[业务系统] --> [ETL工具] --> [数据仓库: order_submission_facts]
7.7.3首日装载

首日装载是指首次将历史数据装载到数据仓库中。

insert overwrite table dwd_order_submission_facts partition (dt)(
	order_id,project_id,project_name,supplier_id,supplier_name,
    submission_date,review_date,approval_date,order_amount,
    product_quantity,discount_amount,tax_amount,order_status
)
SELECT
	o.order_id,
	o.project_id,
	p.project_name,
	o.supplier_id,
	s.supplier_name,
	o.submission_date,
	o.review_date,
	o.approval_date,
	o.order_amount,
	o.product_quantity,
	o.discount_amount,
	o.tax_amount,
	o.order_status
FROM
	source_order o
JOIN
	source_projects p ON o.project_id = p.project_id
JOIN
	source_suppliers s ON o.supplier_id = s.supplier_id
WHERE
	o.submission_date <= CURDATE();
7.7.4每日装载

每日装载是指定期(通常为每日)增量加载新数据。

insert overwrite table dwd_order_submission_facts partition (dt)(
	order_id,project_id,project_name,supplier_id,supplier_name,
    submission_date,review_date,approval_date,order_amount,
    product_quantity,discount_amount,tax_amount,order_status
)
SELECT
	o.order_id,
	o.project_id,
	p.project_name,
	o.supplier_id,
	s.supplier_name,
	o.submission_date,
	o.review_date,
	o.approval_date,
	o.order_amount,
	o.product_quantity,
	o.discount_amount,
	o.tax_amount,
	o.order_status
FROM
	source_order o
JOIN
	source_projects p ON o.project_id = p.project_id
JOIN
	source_suppliers s ON o.supplier_id = s.supplier_id
WHERE
	o.submission_date = CURDATE();

至此我们就完成了DWD表的搭建,以此类推从而搭建所有的DWD层事实表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971145.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《YARN源码分析一》client 任务提交准备阶段

流程 第一步&#xff1a;上传jar 、配置文件、split 文件 提交任务的文件到hdfs 路径&#xff1a;本地配置获取&#xff1a; yarn.app.mapreduce.am.staging-dir &#xff08;默认&#xff1a;/tmp/hadoop-yarn/staging&#xff09; /tmp/hadoop-yarn/staging/$user/.staging…

JAVA项目基于SSM的移动电商管理系统的设计与实现

目录 一、前言 二、技术介绍 三、项目实现流程 四、论文流程参考 五、核心代码截图 专注于大学生实战开发、讲解和毕业答疑等辅导&#xff0c;获取源码后台 一、前言 系统旨在提高电商管理的效率与安全性&#xff0c;满足现代移动电商的复杂需求。系统采用Java作为主要开…

C语言指针的应用场景

改变局部变量的值 当需要根据某些条件来决定是否改变局部变量的值的时候 #include "stdio.h" void fun(int *pt){if(*pt > 90) {*pt 1000;} } int main(void){int a 100;printf("a:%d",a);fun(&a);printf("a:%d",a); }用于操作访问数…

C语言程序设计之文件篇1

程序设计之文件1 问题1_1代码1_1结果1_1 问题1_2代码1_2结果1_2 问题1_3代码1_3结果1_3 问题1_4代码1_4结果1_4 问题1_1 函数 f u n fun fun 的功能是&#xff1a;从键盘输入若干字符串&#xff08;每行不超过 80 80 80 个字符&#xff09;&#xff0c;写入文件 m y f i l e…

jeecguniapp上传附件/图片及预览

一、上传图片 具体页面显示是 注意事项是传递除文件外的参数需要包在formData里 formData:{UUID:that.state.id,type:bill,}, 二、预览图片及附件 重点是附件预览图片预览即图片更换图片path显示 pdf预览代码 同事写的给的笔记及注意事项

云计算赛项学习————OpenStack 平台搭建

PS: 原创作品&#xff0c;严禁用于商业目的。如有任何技术问题&#xff0c;欢迎和我交流&#xff1a;w104118078 &#xff08;微信号&#xff09; 一、基础环境准备 OpenStack云平台搭建需要两个节点&#xff1a;controller&#xff08;控制节点&#xff09;&#xff0c;comp…

getUnlimitedQRCode获取无限制小程序二维码,如何在前端展示

被坑惨了&#xff0c;搞了我好几个小时 nodejs开发服务端&#xff0c;获取微信小程序无限次二维码 getUnlimitedQRCode怎么用的我就不说了&#xff0c;官方文档 小程序官方文档 刚开始出返回的结果是 正确的返回格式应该是 原因是我在请求getUnlimitedQRCode接口时未设置r…

【Android Studio】UI 布局

文章目录 view布局LinearLayout view 在Android开发中&#xff0c;View是一个非常重要的概念&#xff0c;它是所有用户界面组件的基类。View类及其子类构成了Android应用中的用户界面。每个View都占用屏幕上的一个矩形区域&#xff0c;并可以响应用户输入&#xff08;如触摸、按…

UE5 敌人血条

这样处理就完毕&#xff0c;然后 User Widget 尽可能分成多个进行处理

鸿蒙开发入门指南

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 引言 一、鸿蒙系统概述 1.1 简介 1.2 鸿蒙开发的优势 二、鸿蒙开发环境搭建 2.1 安装鸿蒙DevEco Studi…

机器学习中的关键距离度量及其应用

引言 在当今的数据驱动世界中&#xff0c;机器学习算法扮演着至关重要的角色&#xff0c;它们在图像分类、面部识别、在线内容审核、零售目录优化和推荐系统等多个领域发挥着重要作用。这些算法的核心在于它们能够识别和利用数据之间的相似性。而实现这一点的关键&#xff0c;…

在 Hub 上使用 Presidio 进行自动 PII 检测实验

我们在 Hugging Face Hub 上托管的机器学习 (ML) 数据集中发现了一个引人关注的现象: 包含个人未经记录的私密信息。这一现象为机器学习从业者带来了一些特殊挑战。 在本篇博客中&#xff0c;我们将深入探讨含有一种称为个人识别信息 (PII) 的私密信息的各类数据集&#xff0c;…

965不加班还赚钱,金融科技岗真的绝了!

薪资福利好、稳定有前景、大部分965不加班…… 如果你在观望新机会&#xff0c;金融科技岗的这些特质一定非常吸引人。‍‍‍‍‍‍ 特别是在如今的求职环境中&#xff0c;可观的薪资和稳定的环境已经能够打败90%以上的公司了&#xff0c;更别说金融科技岗的工作强度相比互联…

生产计划问题的不同最优化工具软件求解

一、优化求解软件简介 众所周知&#xff0c;常用的优化工具软件有Lingo、Mathcad和MATLAB。 1. LINGO是Linear Interactive and General Optimizer的缩写&#xff0c;即“交互式的线性和通用优化求解器”&#xff0c;由美国LINDO系统公司&#xff08;Lindo System Inc.&…

Photoshop 滤镜使用详解(全集 · 2024版)

Photoshop 内置了约 120 多个滤镜 Fitler。 Ps菜单&#xff1a;滤镜 Fitler 滤镜&#xff0c;根据一定的规律和运算规则&#xff0c;改变像素的排列、组合、RGB 值与分布等&#xff0c;从而实现图像的各种特殊、奇妙的效果。 可将滤镜作用于选区、图层、通道、蒙版和智能对象&a…

采购在供应链管理中有什么作用?8个步骤拆解供应链采购流程!

在当今全球化和竞争激烈的商业环境中&#xff0c;供应链管理的重要性日益凸显。采购作为供应链中的关键环节&#xff0c;不仅关系到企业成本控制和利润空间&#xff0c;更是企业战略实施和市场竞争力的重要体现。本文将深入探讨供应链采购流程的各个方面&#xff0c;从需求识别…

CreateCustomShape函数怎么在C++调用,参数需要用SAFEARRAY

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

关于去中心化自治组织DAO

DAO&#xff08;Decentralized Autonomous Organizations&#xff09;代表了一种变革性的治理和组织管理方法&#xff0c;利用区块链技术创建透明、民主和自我管理的实体。通过自动化决策过程并减少对传统等级结构的依赖&#xff0c;DAO使各种社区团体能够共同管理资源、项目和…

技术分享 | 自动化测试中如何高效定位元素?

在自动化测试中&#xff0c;元素定位是一项非常重要的工作。良好的元素定位可以帮助测试人员处理大量的测试用例&#xff0c;加快测试进度&#xff0c;降低工作负担。但是在实际的测试工作中&#xff0c;我们常常遇到各种各样的定位问题&#xff0c;比如元素定位失败、元素选择…

【数学建模】评价类模型:优劣解距离法

【数学建模】评价类模型&#xff1a;优劣解距离法 目录 【数学建模】评价类模型&#xff1a;优劣解距离法 1&#xff1a;前言 2&#xff1a;算法 1. 将原始矩阵正向化(统一为极大型) 2. 正向矩阵标准化(消除量纲) 3. 计算得分并归一化 3&#xff1a;例题 4&#xff1a…