跳转至

Data Flow Analysis Methods

导言

分析数据平台、训练平台、日志系统或指标系统时,常见错误不是“不会画图”,而是用一张图回答了它不擅长的问题。DFD 解释数据经过哪里,IPO 解释一个处理如何变换,数据血缘解释结果从何而来,ER 模型解释事实如何持久化,领域模型解释业务规则由谁维护。本文用同一个训练与指标示例拆解五种方法,并给出组合顺序、优劣边界和落地检查表。

先按问题选择镜片

假设一个训练平台完成如下工作:数据集注册表给出 dataset@v17,训练作业生成 model@v42,评估作业把预测结果聚合成 metric@v5,指标系统再把结果展示给用户。面对这条链路,至少有五类不同问题:

  1. 走向:数据穿过哪些系统边界,在哪些存储落地?
  2. 变换:评估作业具体接收什么,经过哪些步骤,产出什么?
  3. 来路metric@v5 是由哪个代码版本、运行实例和上游数据生成的?
  4. 结构:数据集、训练运行、模型和指标之间是什么基数关系?
  5. 语义:训练运行在什么条件下允许启动,谁维护状态转换和一致性?

小黑转动五镜片观察轮,从走向、变换、来路、结构和语义观察同一个数据系统

自绘认知锚点:同一个数据系统需要五种互补视角,小黑通过手摇观察轮切换问题,而不是寻找一张“万能图”。

它们不是性能优化算法

这五种方法改变的是认知边界、设计质量和可追溯性,不会直接降低训练显存、查询延迟或存储成本。若要报告效果,应测量建模覆盖率、需求歧义数、根因定位时间、变更影响漏报率、约束缺陷数等指标,不能把“图画出来了”推导成吞吐提升。

DFD 数据流图

机制与对象

问题快照:平台通常先按服务、数据库和消息队列罗列组件,结果是“有什么”很清楚,“什么数据为何经过这里”却不清楚。安全评审、接口改造和故障排查都容易遗漏隐含的数据通路。

一句话直觉:DFD(Data Flow Diagram,数据流图)把系统看成一组接收、变换、保存和发送数据的节点,只追踪数据,不追踪线程调用顺序。

英国政府的数据流图指南采用 Gane-Sarson 记法,把 DFD 的核心元素概括为外部实体、过程、数据存储和数据流;SAP PowerDesigner 文档进一步说明,数据存储响应读写请求但不会自行发起动作,过程可以向下分解为子图。12

三层边界需要分清:

  • 概念:用数据流回答系统边界与职责问题。
  • 可复用机制:先画上下文图,再分解过程;父图与子图的输入输出要保持平衡。
  • 具体落地:训练平台把数据集注册表视为外部实体或上游系统,把训练、评估视为过程,把模型仓和指标仓视为数据存储;这只是本文示例,不是 DFD 的唯一实现。
对象 标识 生产者 结构 消费者 生命周期
系统边界 boundary 范围定义 Boundary[inside, outside] 上下文图、平衡规则 随系统范围版本化
外部实体 external_entities 边界访谈 Set[Entity] 数据流端点 随系统边界版本化
过程 processes 功能分解 Set[Process] 子过程、数据流 随设计版本存在
数据存储 stores 状态盘点 Set[Store] 读写数据流 随存储设计存在
数据流 flows 接口与事件盘点 List[(source, target, payload)] 过程或存储 随接口契约版本化
上下文图/子图 context_diagram / child_diagram connect Graph[Node, Flow] 评审、平衡校验 随 DFD 版本存在
平衡规则 balance_rules DFD 校验器 Set[Constraint] 父子图校验 建模与评审阶段

伪代码与五视图

下面的伪代码描述“如何构造和校验一张 DFD”,而不是平台运行时代码。每个数据流至少一端必须是过程;外部实体和数据存储不能绕过过程直接互连。

function build_dfd(scope, interviews, interface_catalog, storage_catalog):
    boundary = define_system_boundary(scope)
    external_entities = collect_external_sources_and_sinks(interviews, boundary)
    top_process = create_process(name=scope.name, level=0)
    context_flows = name_payloads_crossing_boundary(interface_catalog)
    context_diagram = connect(external_entities, top_process, context_flows)

    processes = decompose_top_process(interviews, interface_catalog)
    stores = identify_persistent_state(storage_catalog)
    flows = map_payloads_between(external_entities, processes, stores)

    for flow in flows:
        assert flow.payload_name is not empty
        assert flow.source is a process or flow.target is a process
        assert not (flow.source is a store and flow.target is a store)
        assert not (flow.source is an external_entity and flow.target is an external_entity)

    child_diagram = connect(external_entities, processes, stores, flows)
    assert external_inputs(child_diagram) == external_inputs(context_diagram)
    assert external_outputs(child_diagram) == external_outputs(context_diagram)
    return version(boundary, context_diagram, child_diagram)

DFD 数据流图的前后对比、因果逻辑、建模流程、组件时序和对象数据流五视图

自绘五视图:重点看 A 的边界变化、B 的因果链、C 的分解与平衡校验、D 的组件交互,以及 E 中注册表—训练—模型仓—评估—指标仓的数据通路。

适用性与边界

  • 适合:跨系统接口盘点、隐私与信任边界分析、数据平台总体设计、训练链路和日志采集链路梳理。
  • 优势:能快速暴露孤立过程、未命名载荷、重复落地、跨边界复制和无人负责的存储。
  • 劣势:不擅长字段级模式、业务对象行为和运行历史;图层级过深时维护成本迅速上升。
  • 实现归属:架构师或平台 Owner 维护上下文图,组件 Owner 维护分解图,数据治理团队维护流名称和分类。
  • 迁移成本:新组件至少要补边界、输入输出、存储读写和父子图平衡;若接口目录长期失真,DFD 也会失真。
  • 效果契约:目标是减少未建模数据通路和边界歧义;代价是持续同步接口、存储与实际部署。应以抽样流量、接口清单和安全审计核验覆盖率。

IPO 分析

机制与对象

问题快照:DFD 能说“预测结果进入评估作业”,却未必说清评估作业如何对齐样本、过滤无效值、聚合指标,以及校验失败时输出什么。

一句话直觉:IPO(Input-Process-Output,输入—处理—输出)把一个处理单元压缩成“吃什么、怎么变、吐出什么”的最小契约。

IPO 是系统分析和程序设计中的基础模式:过程从用户或其他来源接收输入,执行计算,再返回输出。3 它不是完整架构方法,价值在于把复杂链路中的一个过程变成可测试、可验收的单元。

对象 标识 生产者 结构 消费者 生命周期
输入 inputs 调用方/上游 List[TypedInput] 处理步骤 一次执行
前置条件 preconditions 契约设计 Set[Predicate] 校验器 契约版本期
处理步骤 steps 过程 Owner OrderedList[Operation] 下一步骤 一次执行
对齐样本 aligned inner_join Table[prediction, label] 有效样本过滤 当前执行内临时对象
有效样本 valid filter Table[valid rows] 覆盖率、分组 当前执行内临时对象
覆盖率 coverage count(valid) / count(labels) Float[0,1] 最低覆盖校验 校验完成后可释放
分组统计 grouped / metric_points group_by / reduce Map[dimension, aggregate] 质量校验、输出 当前执行后转为结果
质量报告 quality_report validate_ranges Report[issues] 返回值、监控 随结果持久化
输出 outputs 最后步骤 Result[value, report] 下游/调用方 一次执行或持久化
失败输出 rejection 校验步骤 Error[code, reason] 调用方/监控 一次执行

伪代码与五视图

function evaluate_model(predictions, labels, metric_config):
    assert predictions.schema == metric_config.prediction_schema
    assert labels.schema == metric_config.label_schema

    aligned = inner_join(predictions, labels, key="sample_id")
    valid = filter(aligned, metric_config.valid_sample_predicate)
    coverage = count(valid) / max(count(labels), 1)

    if coverage < metric_config.minimum_coverage:
        rejection = Error(code="LOW_COVERAGE", reason=coverage)
        return Result(status="REJECTED", value=null, report=rejection)

    grouped = group_by(valid, metric_config.dimensions)
    metric_points = reduce(grouped, metric_config.aggregation)
    quality_report = validate_ranges(metric_points, metric_config.valid_ranges)

    if quality_report.has_error:
        return Result(status="REJECTED", value=null, report=quality_report)

    return Result(status="ACCEPTED", value=metric_points, report=quality_report)

IPO 分析的前后对比、因果逻辑、建模流程、组件时序和对象数据流五视图

自绘五视图:E 图把输入对象、对齐、聚合、质量校验和最终结果逐一展开;D 图同时保留成功写入与拒绝返回的生命周期。

适用性与边界

  • 适合:ETL 算子、日志解析器、指标计算器、训练数据校验器、模型评估步骤和 API 契约。
  • 优势:简单、低门槛,容易转成单元测试、数据契约和验收条件。
  • 劣势:很容易把缓存、重试、状态更新和副作用藏进“处理”黑盒;也看不到全局依赖与版本历史。
  • 实现归属:单个过程的开发 Owner 负责输入、步骤、输出和错误语义;调用方负责确认输出是否可消费。
  • 迁移成本:新后端必须重新核验类型、排序、空值、幂等、错误输出和副作用,不能只替换中间计算函数。
  • 效果契约:目标是缩小过程契约的歧义面;代价是显式维护错误分支和边界条件。应通过契约测试与异常样本回放验证。

数据血缘

机制与对象

问题快照:看到 metric@v5 并不代表知道它如何产生。若没有运行实例、上游版本和代码版本,结果只能“看起来合理”,无法重现或进行可靠的影响分析。

一句话直觉:数据血缘把每次运行留下的“使用了谁、生成了谁”串成可查询的家谱。

OpenLineage 的对象模型以 DatasetJobRun 为核心:RunEvent 记录作业运行状态及其输入输出数据集,设计态的 JobEventDatasetEvent 则不绑定某次运行。4 W3C PROV 提供更一般的 EntityActivityAgentusedwasGeneratedBywasDerivedFrom 等关系,可用于表达来源链与责任。5

对象 标识 生产者 结构 消费者 生命周期
数据集/产物 dataset 数据源或作业 (namespace, name, version) 作业、查询 跨运行持久化
作业定义 job 代码/编排定义 (namespace, name, code_version) 运行实例 随定义版本存在
运行实例 run 编排器 (run_id, state, time) 血缘后端 单次执行后持久化
运行事件 run_event 作业或集成器 START/COMPLETE/FAIL 采集 API 追加写入
Facet 元数据 facets 插件/作业 Map[type, payload] 治理与调试 随事件或对象版本化
生成/使用边 lineage_edges 血缘后端 Graph[Dataset ↔ Run/Job] 上下游查询 持续累积

伪代码与五视图

function execute_training_with_lineage(job, run_id, input_datasets, config):
    start_event = RunEvent(
        state="START",
        run_id=run_id,
        job=job,
        inputs=input_datasets,
        outputs=[],
        facets={"config_hash": hash(config), "code_version": job.code_version}
    )
    emit(start_event)

    result = train(input_datasets, config)

    if result.failed:
        fail_event = RunEvent(
            state="FAIL",
            run_id=run_id,
            job=job,
            inputs=input_datasets,
            outputs=[],
            facets={"error": result.error, "code_version": job.code_version}
        )
        emit(fail_event)
        return Failure(result.error)

    output_datasets = register_versions(result.model, result.checkpoint)
    complete_event = RunEvent(
        state="COMPLETE",
        run_id=run_id,
        job=job,
        inputs=input_datasets,
        outputs=output_datasets,
        facets={"code_version": job.code_version, "schema": result.schema}
    )
    emit(complete_event)
    return Success(output_datasets)

function upstream_of(target_dataset):
    return breadth_first_search(lineage_graph, target_dataset, edge="generated_from")

数据血缘的前后对比、因果逻辑、建模流程、组件时序和对象数据流五视图

自绘五视图:注意 D 图区分作业执行与血缘事件,E 图区分 Dataset/Artifact 数据对象和 Job + Run 处理对象。

适用性与边界

  • 适合:数据平台表级/列级依赖、训练数据到模型的来源追踪、指标定义变更影响分析、日志加工链回溯。
  • 优势:支持根因定位、下游影响评估、审计、复现和废弃资产识别。
  • 劣势采集缺口会产生“假完整”;同名异物、异名同物和版本粒度不一致会污染整张图。
  • 实现归属:平台团队维护事件协议与后端,作业/连接器 Owner 负责发出完整事件,治理团队维护命名与身份规则。
  • 迁移成本:新引擎要适配作业、运行、输入输出和失败事件;只解析静态 SQL 不能证明某次运行实际读写了什么。
  • 效果契约:目标是提高可追溯覆盖率并缩短根因定位时间;代价是事件写入、身份解析、图存储和数据保留成本。应抽样对比运行日志、存储审计与血缘图。

训练平台已有成熟的同类对象模型。TensorFlow ML Metadata(MLMD)记录 ArtifactExecutionEvent 和上下文,可回答“模型使用了哪个数据集、哪次运行产生模型、使用了什么超参数”等问题。8

ER 模型

机制与对象

问题快照:直接从查询需求创建表,容易把“对象身份”“关系事实”和“展示字段”混在一起,最后通过重复列、自由文本或隐含约定维护基数。

一句话直觉:ER(Entity-Relationship,实体—关系)模型先描述现实世界中有哪些可区分对象、它们有哪些属性、如何关联,再决定如何映射到数据库。

Chen 1976 原始论文把 ER 模型作为统一多种数据视图的概念模型,强调实体、实体集、关系、关系集、属性、值和值集,并用图形记法支持数据库设计。6 现代实践常进一步明确主键、外键、弱实体和 1:11:NM:N 基数。

对象 标识 生产者 结构 消费者 生命周期
实体类型 entity_types 业务事实盘点 Set[EntityType] 关系、逻辑模式 概念模式版本期
属性 attributes 数据定义 (name, value_domain, nullable) 实体或关系 概念/逻辑模式版本期
keys 身份规则 CandidateKey / PrimaryKey 唯一性约束 逻辑模式版本期
关系类型 relationships 事实分析 Relation[roles] 实体类型 概念模式版本期
基数 cardinalities 业务规则 0..1 / 1 / 0..N / 1..N 完整性校验 规则版本期
关联实体 associative_entity 多对多关系或带属性关系 EntityType[relation facts] 逻辑模式映射 概念/逻辑模式版本期
逻辑模式 logical_schema ER 映射 Tables + FK + Constraints 数据库实现 部署版本期

伪代码与五视图

function build_er_model(domain_statements):
    candidate_nouns = extract_business_nouns(domain_statements)
    entity_types = identify_objects_with_stable_identity(candidate_nouns)

    for entity in entity_types:
        entity.attributes = define_atomic_attributes(entity, domain_statements)
        entity.candidate_keys = discover_candidate_keys(entity)
        entity.primary_key = choose_stable_key(entity.candidate_keys)
        assert entity.primary_key is not mutable_business_description

    relationships = identify_business_facts_between(entity_types, domain_statements)
    for relationship in relationships:
        relationship.roles = name_participant_roles(relationship)
        relationship.cardinality = determine_min_max_cardinality(relationship)
        if relationship.has_attributes or relationship.is_many_to_many:
            relationship.associative_entity = materialize_associative_entity(relationship)

    logical_schema = map_entities_and_relationships(entity_types, relationships)
    assert every_foreign_key_targets_candidate_key(logical_schema)
    assert declared_cardinalities_have_enforcement_plan(logical_schema)
    return version(entity_types, relationships, logical_schema)

ER 模型的前后对比、因果逻辑、建模流程、组件时序和对象数据流五视图

自绘五视图:E 图用 Dataset—used_by—TrainingRun—produces—Model 展示关系实例与持久化关联;它不是领域对象的行为调用图。

下面补充两张 Chen 论文原图。第一张说明 ER 处在多个逻辑视图与存储结构层次之间;第二张展示实体、关系、角色、基数和弱实体如何共同描述制造企业。

Chen 1976 Figure 1:不同逻辑视图层次与 ER、关系、网络和实体集模型之间的关系

来自 Chen 1976 Figure 1。它支持“ER 模型连接语义视图与逻辑结构”的方法定位,不证明 ER 在所有数据库设计任务中更优。

Chen 1976 Figure 11:制造企业实体关系图的完整案例

来自 Chen 1976 Figure 11。它是表示能力的原始案例证据,展示多元关系、基数和弱实体;论文没有提供性能基准,因此不能据此推导查询速度或开发效率。

适用性与边界

  • 适合:元数据目录、训练运行/模型注册表、日志索引模式、指标定义与维度表、交易型数据库概念设计。
  • 优势:实体身份、关系角色、键和基数清晰,便于讨论完整性与逻辑模式映射。
  • 劣势:复杂状态机、跨对象策略、时序和副作用表达能力弱;ER 图也不等于已经完成物理分区、索引和查询优化。
  • 实现归属:数据建模者维护概念/逻辑模式,数据库 Owner 负责物理实现,业务专家确认实体与基数含义。
  • 迁移成本:新存储引擎要重新映射键、关系、事务与约束能力,但不应改变业务事实的语义。
  • 效果契约:目标是减少结构重复、孤儿关系和完整性歧义;代价是前期建模与迁移治理。应通过约束测试、孤儿记录扫描和基数异常监控验证。

领域模型

机制与对象

问题快照:当“训练能否启动”“模型能否发布”“指标是否有效”等规则散落在 SQL、API Handler 和定时任务里时,ER 图能描述表关系,却说不出谁有权改变状态、必须同时满足哪些条件。

一句话直觉:领域模型把业务中的对象、行为和不变量放在一起,让规则由最了解自身状态的对象守护。

Martin Fowler 把 Domain Model 定义为同时包含行为和数据的领域对象模型;每个对象代表业务中有意义的个体,并通过对象网络承载复杂业务逻辑。7

三层边界是:

  • 概念:以统一语言描述业务能力和规则。
  • 可复用机制:实体维护身份,值对象表达不可变概念,聚合维护一致性边界,领域服务处理不自然属于单一对象的规则,领域事件表达已经发生的业务事实。
  • 具体落地:本文让 TrainingRun 聚合维护状态跃迁,DatasetSnapshot 值对象固定数据版本,策略服务检查配额与合规;具体类名不是领域模型的通用标准。
对象 标识 生产者 结构 消费者 生命周期
命令 StartTraining 应用服务 (run_id, dataset_snapshot, config) 聚合根 单次调用
值对象 DatasetSnapshot 数据集注册表 (dataset_id, version, schema_hash) TrainingRun 不可变、可跨运行引用
聚合根 TrainingRun 领域层 (id, state, snapshot, events) 仓储、应用服务 跨请求持久化
不变量 invariants 领域规则 Set[Predicate] 聚合行为 规则版本期
领域服务 TrainingPolicy 领域层 allow(run, quota, compliance) 聚合/应用服务 请求期或无状态
策略判定 decision TrainingPolicy.allow Allowed / Rejected(reason) 应用服务 单次请求
领域事件 TrainingStarted 聚合行为 (run_id, dataset_version, time) 事件处理器/血缘采集 追加持久化

伪代码与五视图

function handle_start_training(command, run_repository, policy_service, event_bus):
    snapshot = DatasetSnapshot(
        dataset_id=command.dataset_id,
        version=command.dataset_version,
        schema_hash=command.schema_hash
    )

    run = run_repository.get(command.run_id)
    assert run.state == "CREATED"
    assert run.dataset_snapshot == snapshot

    decision = policy_service.allow(
        run=run,
        quota=command.quota,
        compliance_context=command.compliance_context
    )
    if not decision.allowed:
        return Rejected(reason=decision.reason)

    event = run.start(started_at=command.request_time)
    assert run.state == "RUNNING"
    run_repository.save(run)
    event_bus.publish(event)
    return Accepted(run_id=run.id, state=run.state)

领域模型的前后对比、因果逻辑、建模流程、组件时序和对象数据流五视图

自绘五视图:E 图显示命令经过聚合行为和不变量校验后改变持久状态并产生领域事件;ER 模型只会描述这些对象如何存储。

适用性与边界

  • 适合:训练生命周期、数据产品发布、指标定义审批、日志保留与脱敏策略等规则复杂且持续演化的领域。
  • 优势:统一业务语言,把状态转换和不变量集中到明确所有者,降低规则散落带来的不一致。
  • 劣势:成本最高;简单 CRUD 或纯搬运链路使用复杂聚合会造成过度设计。对象模型与数据库模式不一致时还需要映射层。
  • 实现归属:领域专家与领域开发共同维护语言和规则,应用服务负责编排,仓储负责持久化,基础设施层不能绕过聚合直接改状态。
  • 迁移成本:新模型、后端或流程若改变业务概念、聚合边界或不变量,需要重新设计;仅替换数据库通常只改仓储适配。
  • 效果契约:目标是减少非法状态和重复规则;代价是建模、测试、映射和团队学习成本。应通过状态机测试、属性测试和生产非法跃迁监控验证。

异同与优劣

共同点

五种方法都在做同一件基础工作:把隐含假设变成可审查对象。它们都依赖稳定命名、明确边界、版本管理和实际系统校验;任何一张图若长期不与代码、事件、数据库和运行记录对照,都会退化成过期文档。

不同点不在“图长什么样”,而在主要观察维度

  • DFD 的主轴是空间与边界
  • IPO 的主轴是局部变换
  • 数据血缘的主轴是时间与因果来源
  • ER 模型的主轴是静态事实结构
  • 领域模型的主轴是业务行为与一致性

DFD、IPO、数据血缘、ER 模型和领域模型的核心问题、时间视角、粒度、优势、盲区与推荐组合

自绘对比图:箭头给出一种常用收敛顺序,不是强制瀑布流程;运行血缘应持续反证并修正前面的设计模型。
方法 最擅长回答 主要产物 优势 主要盲区 最直接验证
DFD 数据经过哪里? 上下文图、分层 DFD、数据流字典 系统边界与跨组件流向直观 字段结构、行为、运行历史 接口清单、流量与存储审计
IPO 一个过程如何变换? 输入/处理/输出契约 简洁、可测试、可验收 全局依赖、持久状态、副作用 契约测试、异常样本回放
数据血缘 结果从何而来、变更影响谁? 数据集—作业—运行图 追溯、复现、影响分析 采集缺口、身份污染 运行日志、审计日志、抽样回放
ER 模型 事实如何组织和持久化? 概念/逻辑模式、键与基数 完整性与结构清晰 行为、时序、复杂策略 约束测试、孤儿与基数扫描
领域模型 业务规则由谁维护? 聚合、值对象、服务、事件 语义统一、不变量集中 建模成本、过度设计风险 状态机与属性测试、非法跃迁监控

最小组合

若时间有限,至少保留三层:用 DFD 画系统级通路,用 IPO 写关键过程契约,用数据血缘记录运行事实。只要系统中存在复杂对象关系,再补 ER 模型;只要规则开始跨表、跨服务散落,再补领域模型

四类平台如何组合

数据平台

数据平台首先需要 DFD 盘点数据源、采集、计算、存储、服务和跨域复制,再用 ER 模型定义目录、表、字段、数据产品、Owner 与策略之间的结构。关键 ETL/ELT 过程用 IPO 写清输入、变换、输出和失败语义,运行后由数据血缘记录实际的表级或列级依赖。

领域模型适合数据产品发布、质量门禁、权限申请和生命周期治理;如果平台只是搬运文件,不必为每个算子构造复杂聚合。

训练平台

训练平台的 DFD 应覆盖数据集注册表、缓存、训练任务、检查点、模型仓、评估器和部署门禁;IPO 用于数据校验、样本混合、训练启动、评估与模型打包等关键步骤。数据血缘必须绑定数据版本、代码版本、配置、运行实例、模型和指标,否则“可复现”只是口号。

ER 模型负责元数据存储结构,领域模型负责 TrainingRunModelVersionEvaluationReleaseDecision 的状态与不变量。MLMD 的 Artifact/Execution/Event 设计说明,训练平台的来源追踪本质上也是对象、执行和关系的组合。8

日志系统

日志系统用 DFD 描述 Agent、Collector、队列、解析器、索引与归档的通路,用 IPO 细化解析、脱敏、采样、路由和索引写入。ER 模型用于日志记录、资源、索引、保留策略和租户关系;领域模型只在审计日志、合规删除、保留策略等规则复杂处重点使用。

OpenTelemetry 日志数据模型把时间、观测时间、TraceId、SpanId、严重级别、正文、资源和属性等字段统一起来,说明“日志是什么”属于数据/领域语义问题;这些字段如何经过 Collector 才属于 DFD 与 IPO 问题。9

指标系统

指标系统首先用领域模型定义指标名称、单位、维度、聚合语义、时间窗口、有效范围和 Owner,再用 IPO 固化从事件到指标点的计算契约。DFD 描述 SDK、Collector、流处理、时序库和查询服务,数据血缘记录指标定义、输入事件、处理版本和输出时序之间的关系,ER 模型则支撑定义、维度和权限元数据。

OpenTelemetry 指标规范区分 Event、Metric Stream 和 Timeseries,并明确时间重聚合、空间重聚合和 Delta-to-Cumulative 等转换。这正好说明:同一指标系统同时需要语义模型、处理契约和数据流模型10

一套可执行的分析顺序

  1. 用领域语言定问题:列出关键业务名词、状态、规则和不能被破坏的不变量;复杂度低时只保留词汇表。
  2. 用 DFD 划边界:画一张上下文图,再只对高风险过程向下分解;所有箭头都用数据名而不是“调用”“同步”。
  3. 用 ER 固化事实结构:识别身份、属性、关系、角色和基数;不要从现有表名直接反推业务实体。
  4. 用 IPO 关闭关键过程:为高风险变换写输入类型、处理步骤、输出、拒绝条件和副作用。
  5. 用血缘记录运行事实:统一 Dataset/Job/Run 身份,覆盖 START、COMPLETE、FAIL 及代码、模式、质量等元数据。
  6. 反向校验设计:定期用真实事件、接口流量、数据库约束和生产异常修正 DFD、IPO、ER 与领域模型。

常见误区

  • 把 DFD 画成调用图:箭头应命名数据,不是 HTTPRPC 或“调用”。协议可作为数据流属性。
  • 把 IPO 的处理写成黑盒:若处理包含校验、排序、分支、重试或状态写入,应显式展开。
  • 把静态 SQL 解析当完整血缘:它能推断设计依赖,不能证明某次运行的真实输入、动态分支和失败输出。
  • 把 ER 实体当 DFD 外部实体:DFD 外部实体是系统边界外的数据源/汇;ER 实体是需要保存信息的业务对象。
  • 把领域模型等同数据库表:领域对象必须承载行为或不变量;纯表映射只是数据模型。

总结

DFD、IPO、数据血缘、ER 模型和领域模型不是五种互斥画法,而是五个不同问题的答案。 DFD 给全局通路,IPO 给局部契约,血缘给运行证据,ER 给持久结构,领域模型给业务行为。对数据平台、训练平台、日志系统和指标系统,最稳妥的做法是让设计模型与运行证据形成闭环:先用模型消除歧义,再让真实数据反证模型。

参考资料


  1. UK Health Security Agency, Approval standards and guidelines: data flow diagram, accessed 2026-08-03. 

  2. SAP Help Portal, Data Flow Diagram (DFD), accessed 2026-08-03. 

  3. Engineering LibreTexts, Input-Process-Output Model, accessed 2026-08-03. 

  4. OpenLineage, Object Model, accessed 2026-08-03. 

  5. W3C Recommendation, PROV-O: The PROV Ontology, 2013-04-30. 

  6. Peter Pin-Shan Chen, The Entity-Relationship Model—Toward a Unified View of Data, ACM Transactions on Database Systems, 1(1), 1976, pp. 9–36. 

  7. Martin Fowler, Domain Model, 2003-03-05. 

  8. TensorFlow, ML Metadata, accessed 2026-08-03. 

  9. OpenTelemetry, Logs Data Model, accessed 2026-08-03. 

  10. OpenTelemetry, Metrics Data Model, accessed 2026-08-03. 

评论