多个源系统字段冲突,数仓该信谁?只用 COALESCE 够吗?
面试怎么回答
我会先确认实体匹配,再按字段配置来源权威、有效性和时效规则,区分未提供与明确清空。COALESCE只能表达简单非空优先,不能处理所有冲突。最终值应保存来源、源版本和规则版本,重要字段冲突进入复核;回放时固定规则,并对新规则影响做差异评估,避免当前优先级悄悄改写历史口径。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
客户名称在CRM里更新了,开票系统还保留旧名;联系电话却是客服系统最新。业务说“合成一张统一客户表”,这里的统一,显然不能只选一整行来源。
多源融合应按字段定义权威来源、有效性和时效规则,并保留取值证据;非空不等于可信,NULL也可能表示明确清空。
先确认两个系统说的是同一个对象
如果客户编号映射本身存在歧义,讨论字段优先级没有意义。先检查来源系统、租户、实体标识和映射有效期,防止把两个同名客户融合成一个。
实体匹配的证据与字段取值的证据也要分开。手机号相同可能帮助识别,但共享号码、号码回收和录入错误,都不能天然证明是同一个自然人或企业。
只有对象对齐可信,后续的冲突处理才是在挑选属性,而不是掩盖身份错误。
权威来源通常是字段级的
开票名称可能应以认证后的开票资料为准,联系方式则可能允许客服系统维护。给整个系统排一个全局名次,未必能同时覆盖这两种业务责任。
规则可以包括权威来源、合法性校验、有效时间、备选来源与冲突处置。例如权威值虽然存在却已被标记失效,就不能因为非空而永久压住有效备选值。
优先级也不宜只靠接收时间。一个晚到的批量同步,可能携带更早的业务版本;不同源系统的更新时间还可能来自不同语义和时钟,不能不加解释地比较大小。

COALESCE 缺少哪些信息?
它可以表达“第一个非空值”,但这个函数并不知道值为什么为空、不为空是否可信,也不知道一个字段是否已被用户主动清空。
至少要区分未提供、已知有效、明确清空与校验失败。若变更事件携带字段是否出现的标记或操作类型,应保留这些信息;不能把它们都压成一个NULL。
比如用户主动删除备用电话,权威源发出清空指令。下游如果继续回退到旧系统非空号码,就把已经清除的信息重新填了回来。该动作是否允许回退,是字段策略,不是函数默认行为。
同样,一行数据中的地址、邮编和地区可能存在整体一致性约束。字段级选择不意味着任意拼装;如果三者必须来自同一次地址认证,应把它们作为一个原子属性组进行融合和验收。
一个典型场景:手机号总被改回旧值
假设客服确认的新号码入仓后,夜间全量任务又把旧号码写回。团队首先怀疑实时任务丢了更新,检查消费延迟却没有异常。
追踪取值来源才发现,全量任务固定优先使用旧系统非空字段。旧验收只检查手机号非空率和格式,两项都合格;它从未验证这个号码是否来自当前有效的维护渠道。
修正不是简单颠倒所有系统的优先级,而是为联系电话建立独立策略,保留源业务版本、取值来源与清空状态,再对受影响客户进行差异回算。
同时应保留冲突样本:原值是什么、两个候选值是什么、命中了哪条规则。这样业务提出质疑时,可以解释选择过程,而不是只展示最终宽表。
规则变更,也是一种数据变更
当主来源迁移或有效性规则升级时,新增数据和历史数据是否一起切换,需要明确计划。用当前规则重跑历史,可能得到与原报表不同的属性结果。
因此规则最好有版本和生效范围。历史回放若要复现原结果,就固定当时版本;如果要按新规则重述历史,应该生成可对比的新版本并标注影响范围。
验证也分两层:单字段检查取值是否符合规则,关联字段检查组合是否合理。对重要身份或结算属性,冲突可能需要人工确认,不能为了提高覆盖率自动挑一个。
最后还要定义责任归属。数仓负责执行透明规则,不应默默替业务决定哪个系统有最终解释权;源系统负责人和字段负责人共同确认后,融合逻辑才能长期稳定。