HiQ Cortex
EN 打开 Chat

Practitioner's Journal

两万三千行背景数据,怎么从 3.10 搬到 3.12

一份 ecoinvent 数据库升级的映射复盘:为什么不能直接替换 UUID,以及项目-官方-官方-项目的四步跳转是怎么跑通的。

两万三千行背景数据,要从 ecoinvent 3.10 搬到 3.12。

听起来像是一次版本号更新,点一下导入就完事。实际不是。这批数据在项目内部做过二次编码——每一行挂的是项目自己的 UUID,不是 ecoinvent 原生的 Activity UUID。所以不能拿官方 3.12 的 UUID 直接覆盖旧的。直接覆盖,审计断链,验证时谁也说不清一行数据从哪来、为什么换成了那个新条目。

这篇文章记一次真实的映射复盘:为什么这一步绕不开,以及我们是怎么把它跑通的。

为什么不能直接替换 UUID

先说清楚卡点在哪。

ecoinvent 每个过程(process)有一个官方的 Activity UUID。版本之间——比如 3.10 到 3.12——官方会发布一份映射表,告诉你哪个旧 UUID 对应哪个新 UUID。如果你的项目直接用官方 UUID,照着表替换就行。

但中电气这批数据不是。项目方导出自己的库时,重新生成了项目侧的 UUID 和 ID,作为业务主键。一份 3.10 的导出表,里面两万三千多行,每一行的 UUID 是项目自己造的,跟官方那张映射表里的 Activity UUID 对不上。

于是出现一个死结:官方映射表能告诉你 3.10 官方条目对应 3.12 官方条目,但它不知道你项目侧的 UUID 是哪个。直接替换,等于拿一把对不上的钥匙去开锁。

四步跳转

解法是把”项目”和”官方”拆成两层,用业务主键做桥。完整路径是四步:

  1. 项目 3.10 数据,用业务主键对齐到官方 3.10 数据。
  2. 通过官方映射表,从官方 3.10 跳到官方 3.12。
  3. 官方 3.12 数据,再用业务主键对齐回项目 3.12 数据。
  4. 最后落出来的,是项目侧的旧 UUID 到项目侧新 UUID 的对应表——这才是数据库升级真正要用的东西。

业务主键是三件套:活动名称(Activity Name)、参考产品(Reference Product)、地理位置(Geography)。同一个过程,在两个版本里只要这三项一致,就认作同一条。

真正要交付的不是官方 UUID,是项目 UUID 到项目 UUID 的对应关系。官方映射表只是中间的桥。

地理位置这关

业务主键里最坑的是地理位置。

项目导出的地理字段不是干净的代码,而是带中文标注的,比如 China, Hebei (河北)。官方映射表里写的是 CN-HB。字符串对不上,join 直接漏掉一大片。

所以匹配前必须先标准化。这一步用 ecoinvent 自带的地理参照表——源端 3.10 用 geo3.10.xlsx,目标端 3.12 用 geography.xlsx,读 Name → Shortname 那一列,把带标注的名字洗成短代码。China, Hebei (河北) 先去掉括号成 China, Hebei,再映射成 CN-HB

不能靠模糊匹配猜省份代码。猜错一个,整条链路就静默地接到错的数据上,而报表上看着还是”匹配成功”。这一关必须用参照表硬对。

一对多怎么办

跑完四步跳转,会得到一张”源 UUID → 目标 UUID”的表。这时候要分类,按基数关系分成四种:

  • 一对一:一个旧 UUID 对一个新 UUID,最干净。
  • 多对一:几个旧 UUID 指向同一个新 UUID,通常是因为 3.12 合并了某些条目,保留即可。
  • 一对多:一个旧 UUID 对应多个新 UUID,需要选一个。
  • 无目标:旧 UUID 在 3.12 里找不到对应,官方映射表那一行的 3.12 端是空的。

一对多是这次的主要冲突源。一个 3.10 的过程,到 3.12 可能拆成了按地区分的多个条目。这时候不能随便挑。我们用的是一条优先级规则:中国区(CNCN-*)优先,其次是 RoW,再是 GLO,都没有就取候选里的第一个。

关键是一对多不能在匹配阶段就塌成一条。必须先把每个候选都保留下来,标好各自的地理代码,排序后再选。否则你根本不知道自己丢了哪些选项,也没法在结果里留下”为什么选了这条”的审计记录。

跑完之后的数字

这次 EN15804 这一档,最后落出来的数:

  • 源数据 23,603 行,全部进入流程。
  • 源到官方 3.10 匹配上 23,603 行,地理标准化零丢失。
  • 官方 3.12 到项目 3.12,匹配上 23,575 行,剩 28 行是官方映射表里 3.12 端本身就空着的——不是项目端漏了,是官方那行没给目标。
  • UUID 关系:一对一 23,115,多对一 169,一对多 291,无目标 28。

按”保留一对一和多对一、一对多按中国区优先塌缩”的策略,最终可用映射 23,575 行。其中一对多塌缩选中国区 45 条、选 RoW 179 条、选 GLO 0 条、兜底取首位 67 条。

每一条选择都带 selection_reason 列,写清楚是按哪条规则选的。最后输出的表里,旧版本 UUID 列和新版本 UUID 列做了黄色高亮——交付给项目人员时,第一眼能看到的就是这两列对应关系,旁边的活动名称、产品、地理字段留着做抽查。

复盘里值得记下的一条

整个过程里最容易出错、也最值得写进操作手册的,是这条:不要拿 PROCESS_UUID 当主键

项目导出里有两类 UUID——UUIDPROCESS_UUIDPROCESS_UUID 看着像官方原生那个,容易让人以为它是唯一的、可以直接拿来做替换键。实际不是,项目导出里 PROCESS_UUID 会重复。拿它当主键去 join,会静默地多对多串线,报表数字看着都对,底层对应关系已经乱了。

主键始终用项目侧的 UUIDPROCESS_UUID 只能当审计辅助字段,不能当迁移键。这一条如果不在脚本里卡死,后面所有的匹配统计都是在一个歪掉的地基上盖楼。


数据库版本升级这件事,难点不在”换版本号”,在”怎么证明每一行都换对了”。四步跳转、地理标准化、基数分类、选择留痕——每一步都不是为了让流程好看,是为了让最后那张表经得起抽查。两万三千行搬完,能逐行说清楚来源,这次才算交付。

— w1f