目录
[2.1 三者不是简单的三层外键关系](#2.1 三者不是简单的三层外键关系)
[2.2 Die 的主键是坐标,不是自增 ID](#2.2 Die 的主键是坐标,不是自增 ID)
[2.3 封装之后,Die 与成品芯片需要桥接](#2.3 封装之后,Die 与成品芯片需要桥接)
[3.1 Recipe 维度的正确粒度](#3.1 Recipe 维度的正确粒度)
[3.2 加工事实表要同时保留设备与工艺上下文](#3.2 加工事实表要同时保留设备与工艺上下文)
[3.3 重入流必须在模型中显式表达](#3.3 重入流必须在模型中显式表达)
[4.1 Availability:计划时间的边界必须先定下来](#4.1 Availability:计划时间的边界必须先定下来)
[4.2 Performance:标准节拍必须绑定产品与工艺](#4.2 Performance:标准节拍必须绑定产品与工艺)
[4.3 Quality:设备口径与产品口径不能混用](#4.3 Quality:设备口径与产品口径不能混用)
[5.1 先区分测试阶段](#5.1 先区分测试阶段)
[5.2 良率指标必须显式定义分子与分母](#5.2 良率指标必须显式定义分子与分母)
[5.3 一段带口径控制的良率计算](#5.3 一段带口径控制的良率计算)
[5.4 Wafer Map 的价值在于空间特征,不在于图片](#5.4 Wafer Map 的价值在于空间特征,不在于图片)
[6.1 分层职责](#6.1 分层职责)
[6.2 DWS 层最值得沉淀的四类模型](#6.2 DWS 层最值得沉淀的四类模型)
[七、领域专属的 DQC 规则设计](#七、领域专属的 DQC 规则设计)
[8.1 CIM 系统语义复杂,ODS 到 DWD 是主要工作量](#8.1 CIM 系统语义复杂,ODS 到 DWD 是主要工作量)
[8.2 FDC 高频时序数据不能全量进离线数仓](#8.2 FDC 高频时序数据不能全量进离线数仓)
[8.3 深层追溯查询不适合多表 Join](#8.3 深层追溯查询不适合多表 Join)
在半导体制造企业做数仓,最容易出现的失败不是任务跑不动,也不是指标算不出来,而是指标算出来了,但业务不认。
一个典型场景:数据团队交付了良率看板,显示某产品当周良率 98.6%,工艺工程师看了之后直接指出三个问题------分母里混进了监控片、返工批次被重复计数、CP 良率被当成了最终出货良率。
SQL 语法没有任何问题,错在建模时对制造过程的理解缺失。
半导体数仓的核心不是把 MES、EAP、YMS 的数据搬到 Hive 里,而是把制造过程中的实体关系、工艺上下文、质量判定口径准确地表达成数据模型。Lot、Wafer、Die、Recipe、OEE、YMS 这六个概念,分别对应六条建模主线:生产批次、物理载体、最小质量单元、工艺上下文、设备产能、质量结果。下面逐一拆解,并给出对应的建模设计。
一、六个概念在数仓中承担什么职责
| 概念 | 业务含义 | 典型数据粒度 | 主要来源系统 | 建模中的核心职责 |
|---|---|---|---|---|
| Lot | 生产批次,一起流转的一组晶圆 | 批次 × 工序 × 作业 | MES | 生产进度、WIP、Cycle Time、批次追溯 |
| Wafer | 晶圆,物理载体,通常一片 300mm / 200mm 晶圆 | 单片晶圆 | MES / EAP / 物料系统 | 晶圆级质量、加工履历、位置与状态 |
| Die | 裸晶,晶圆上的最小功能单元 | 晶圆 + X/Y 坐标 | CP/FP 测试、Tester | 良率计算、失效分析、封装追溯 |
| Recipe | 机台执行某道工序的参数集合及版本 | 设备 × 腔体 × 配方版本 × 生效时间 | EAP / RMS / 机台日志 | 工艺归因、参数漂移分析 |
| OEE | 设备综合效率,由时间、性能、质量三部分构成 | 设备/腔体 × 时间窗口 | EAP / MES / 状态采集 | 产能分析、停机归因、瓶颈识别 |
| YMS | 良率管理系统,聚合测试与缺陷数据 | 晶圆 / Die / 批次 / 产品 | YMS、CP、FT、缺陷检测 | 良率分析、Bin 分布、失效定位 |
这六个概念不能混在同一张表里表达。Lot 是流转单位,Wafer 是物理单位,Die 是质量单位,Recipe 是工艺上下文,OEE 是设备指标,YMS 是质量分析域。 把它们的粒度分清,模型设计就已经完成了一半。
二、Lot、Wafer、Die:先解决实体关系,再谈指标
2.1 三者不是简单的三层外键关系
最直觉的理解是:一个 Lot 包含多片 Wafer,一片 Wafer 包含多个 Die。这个关系在生产初期成立,但在整个生命周期里不成立。
实际制造过程中会发生以下情况:
-
Lot Split(批次拆分):一个 Lot 拆成多个 Sub-lot,分别在不同机台加工。
-
Lot Merge(批次合并):多个 Sub-lot 合并后继续流转。
-
Rework(返工):部分 Wafer 从某道工序退回前道工序重做。
-
Scrap / Hold:部分 Wafer 报废或被扣留,批次内数量发生变化。
-
Dummy / Monitor 片:批次中包含挡片、监控片,不参与产品良率计算。
因此,Lot 与 Wafer 是多对多关系,且带有时间有效性 。如果在 Wafer 维表上直接放一个 lot_id 字段,就只能记录最后一次归属,历史追溯必然出错。
正确做法是建立批次---晶圆关系桥表:
sql
-- dwd_lot_wafer_relation:批次与晶圆的时变关系
CREATE TABLE dwd_lot_wafer_relation (
relation_id STRING,
lot_id STRING,
sub_lot_id STRING,
wafer_id STRING,
wafer_seq INT, -- 在载具中的槽位
wafer_type STRING, -- PRODUCT / DUMMY / MONITOR / ENGINEERING
effective_start TIMESTAMP,
effective_end TIMESTAMP,
event_type STRING -- CREATE / SPLIT / MERGE / REWORK / SCRAP
);
关键点:
-
关系必须带生效时间,支持"某片晶圆在某个时刻属于哪个批次"的时点查询。
-
wafer_type必须参与所有良率与产能指标的计算条件,不能默认批次内所有片都是产品片。 -
拆分与合并要保留事件链,否则 WIP 数量和投入产出数量无法对账。
2.2 Die 的主键是坐标,不是自增 ID
Die 在物理上由晶圆上的位置决定,标准标识是:
die_key = wafer_id + die_x + die_y
这里还需要补充三个工程细节:
-
坐标系必须统一:不同测试机、不同 YMS 供应商的坐标原点、 notch 方向、行列编号规则可能不同。入仓时必须统一到产品版图定义的坐标系。
-
需要区分 Reticle / Shot 与 Die:一次曝光覆盖的是一个 Shot,里面包含多个 Die。做工艺归因时,问题可能出在 Shot 级而不是 Die 级。
-
Gross Die 与 Tested Die 不同:Gross Die 是版图设计上的总裸晶数,Tested Die 是实际测试到的数量。边缘失效、探针接触不良会导致两者不一致。
Die 级测试明细建议采用如下粒度:
sql
-- dwd_cp_test_detail:CP 测试明细,一次测试一条
CREATE TABLE dwd_cp_test_detail (
test_run_id STRING,
wafer_id STRING,
die_x INT,
die_y INT,
lot_id STRING,
product_id STRING,
test_program STRING,
tester_id STRING,
test_start_time TIMESTAMP,
test_end_time TIMESTAMP,
is_retest INT,
hard_bin STRING,
soft_bin STRING,
test_result STRING
);
is_retest 与测试时间必须保留。只有保留测试次序,才能区分一次通过良率 和复测后良率。
2.3 封装之后,Die 与成品芯片需要桥接
晶圆切割、封装、测试之后,业务标识从 wafer_id + x + y 变成封装体的 chip_uid / unit_code。车规芯片客诉追溯要求能从 chip_uid 一路反查到硅片批次、机台、腔体、配方版本。
这里必须建桥表,而不是在成品表上塞一堆冗余字段:
sql
-- dwd_die_unit_mapping:裸晶与封装成品映射
CREATE TABLE dwd_die_unit_mapping (
chip_uid STRING,
wafer_id STRING,
die_x INT,
die_y INT,
package_lot_id STRING,
assemble_lot_id STRING,
ft_test_run_id STRING,
mapping_time TIMESTAMP
);
这张表是全链路追溯的主干。有了它,正查(原材料影响了哪些出货芯片)和反查(退货芯片来自哪一批、哪台设备)才有统一的实现路径。
三、Recipe:工艺归因的关键在于"当时用的是哪一版"
工艺工程师排查良率问题时,最常见的一个问题是:
"昨天下午那批货,用的是哪台机台、哪个腔体、哪一版 Recipe?"
如果数仓里只存了 recipe_name,这个问题答不了。因为同名配方会有多个版本,同一配方在不同腔体上的表现也不同。
3.1 Recipe 维度的正确粒度
Recipe 上下文的最小粒度应当是:
设备(tool_id) + 腔体(chamber_id) + 配方标识(recipe_id) + 版本(version) + 生效时间区间
建模建议:
sql
-- dim_recipe_version:配方版本维表
CREATE TABLE dim_recipe_version (
recipe_sk BIGINT,
tool_id STRING,
chamber_id STRING,
recipe_id STRING,
recipe_version STRING,
route_id STRING,
operation_id STRING,
effective_start TIMESTAMP,
effective_end TIMESTAMP,
is_current INT
);
这是一个典型的带生效区间的版本维表。加工事实表时,必须用加工时间落在生效区间内进行关联,不能用当前版本直接关联历史事实。否则会发生"配方上周才改版,但上个月的数据全被打上新版本"的错误。
3.2 加工事实表要同时保留设备与工艺上下文
sql
-- dwd_process_run:工序加工执行明细
CREATE TABLE dwd_process_run (
run_id STRING,
lot_id STRING,
wafer_id STRING,
route_id STRING,
operation_id STRING,
step_no INT,
tool_id STRING,
chamber_id STRING,
recipe_sk BIGINT,
recipe_version STRING,
track_in_time TIMESTAMP,
process_start TIMESTAMP,
process_end TIMESTAMP,
track_out_time TIMESTAMP,
run_qty INT
);
保留 track_in / process_start / process_end / track_out 四个时间点非常重要。这四个时间点把一次加工拆成了三种等待与执行状态:
-
进站到开始加工:Queue Time,排队等待
-
开始加工到加工结束:Process Time,实际加工
-
加工结束到出站:Wait Time,出站等待
Cycle Time 分析如果只用 track_out - track_in,就只能得到一个总时长,无法定位瓶颈。把四段拆开,才能判断问题是产能不足(排队久)、机台效率低(加工久),还是物流与作业流转慢(出站久)。
3.3 重入流必须在模型中显式表达
半导体制造是典型的重入流:同一批晶圆会在光刻、刻蚀等工序反复进出。这意味着:
-
lot_id + operation_id不唯一,同一个批次会多次经过同一工序。 -
事实表主键必须是
run_id或lot_id + operation_id + step_no + seq_no。 -
返工会产生同一工序的多次执行记录,不能简单去重。
如果按 lot_id + operation_id 做 Group By 去重,会直接丢掉返工记录,导致产能、良率、Cycle Time 全部失真。
四、OEE:真正难的不是公式,是分母和状态口径
OEE 的标准公式很简单:
OEE = Availability × Performance × Quality
但在 Fab 里落地,争议全部集中在三个输入项上。
4.1 Availability:计划时间的边界必须先定下来
Availability = (计划生产时间 - 停机时间) / 计划生产时间
需要明确的口径问题:
-
计划生产时间是否包含计划保养(PM)? 不同企业口径不同,包含与不包含会直接改变Availability结果。建模时必须把计划时间作为独立事实,而不是用 24 小时直接代替。
-
停机是否区分计划停机与非计划停机? 建议分开统计,否则"设备很忙"和"设备很健康"会被混为一谈。
-
统计对象是 Tool 还是 Chamber? 多腔体设备的一个腔体 Down、另一个腔体继续 Run 是常态。按 Tool 统计会掩盖腔体级问题。
参考状态事实表:
sql
-- dwd_tool_state_duration:设备状态时长明细
CREATE TABLE dwd_tool_state_duration (
state_record_id STRING,
tool_id STRING,
chamber_id STRING,
state_code STRING, -- 对齐 SEMI E10 状态定义
state_group STRING, -- PRODUCTIVE / STANDBY / ENGINEERING / DOWN
reason_code STRING,
start_time TIMESTAMP,
end_time TIMESTAMP,
duration_sec BIGINT,
source_system STRING
);
工程上必须处理两件事:
-
状态区间重叠:MES 与 EAP 可能对同一时段都上报状态,直接 SUM 会重复累计,需要先做区间去重与优先级仲裁。
-
状态区间缺口:采集断链时不能默认填成 Run。缺口应当单独标记为 Unknown,并作为数据质量问题告警。
4.2 Performance:标准节拍必须绑定产品与工艺
Performance = (理论标准节拍 × 实际产出) / 实际运行时间
标准节拍不是设备的一个固定属性,它随产品、Recipe、层别变化。因此标准节拍应当建成产品 × 工序 × 配方版本的维表,不能用一个全厂统一的 CT 值。
4.3 Quality:设备口径与产品口径不能混用
设备产出中的 Quality 通常指该设备当次加工的一次通过率,与 YMS 中的最终产品良率不是同一指标。混用会导致 OEE 被其他工序的问题污染。
另外,Fab 中大量使用 设备利用率(Utilization) 来衡量产能。它与 OEE 不是同一个指标:Utilization 只看设备有没有在跑,OEE 还要看跑得快不快、产出好不好。看板上必须分开命名与定义,不能把 Utilization 标成 OEE。
五、YMS:良率不是一个字段,而是一组带口径的指标体系
5.1 先区分测试阶段
| 阶段 | 测试对象 | 业务用途 | 常见问题 |
|---|---|---|---|
| WAT | 晶圆上的工艺测试结构 | 判断工艺参数是否达标 | 不能直接代表芯片功能良率 |
| CP | 晶圆上的每颗 Die | 打 Bin、筛除坏 Die、指导封装 | 复测、探针接触异常影响结果 |
| FT | 封装后的成品芯片 | 出货判定 | 已混批,不能直接归因到某片晶圆 |
| SLT / Burn-in | 系统级或老化测试 | 筛除早期失效 | 与 CP/FT 的失效模式不同 |
把 CP 良率当作出货良率,是半导体数仓最常见的口径错误。 CP 通过只代表晶圆测试通过,封装与 FT 还会产生损失。
5.2 良率指标必须显式定义分子与分母
| 指标 | 分子 | 分母 | 使用注意 |
|---|---|---|---|
| 测试良率 | 通过 Die 数 | 实际测试 Die 数 | 分母不含未测到的位置 |
| 一次通过良率 FPY | 首次测试通过 Die 数 | 首次测试 Die 数 | 必须排除复测记录 |
| 投入产出良率 | 合格出货 Die 数 | 投入的 Gross Die 数 | 需产品版图提供 Gross Die |
| 累积良率 | 各工序连续通过的产出 | 对应投入 | 需处理返工与跳步 |
| Bin 损失占比 | 某 Bin 的 Die 数 | 测试 Die 总数 | Hard Bin 与 Soft Bin 不可混用 |
Hard Bin 通常是测试机与分选机使用的粗分类,Soft Bin 是更细的失效原因分类。做 Pareto 分析时,两者要分别建维度,不能用 Soft Bin 的数量去对 Hard Bin 的账。
5.3 一段带口径控制的良率计算
下面的示例计算首次 CP 测试良率,注意三个控制点:排除非产品片、按 Die 取首次测试、分母只用实际测试过的 Die。
sql
WITH first_cp AS (
SELECT
t.wafer_id,
t.die_x,
t.die_y,
t.hard_bin,
ROW_NUMBER() OVER (
PARTITION BY t.wafer_id, t.die_x, t.die_y
ORDER BY t.test_start_time ASC, t.test_run_id ASC
) AS rn
FROM dwd_cp_test_detail t
JOIN dwd_lot_wafer_relation r
ON t.wafer_id = r.wafer_id
AND t.test_start_time >= r.effective_start
AND t.test_start_time < r.effective_end
WHERE r.wafer_type = 'PRODUCT'
AND r.lot_id IS NOT NULL
)
SELECT
COUNT(1) AS tested_die_cnt,
SUM(CASE WHEN hard_bin = '1' THEN 1 ELSE 0 END) AS pass_die_cnt,
SUM(CASE WHEN hard_bin = '1' THEN 1 ELSE 0 END)
/ COUNT(1) AS first_pass_yield
FROM first_cp
WHERE rn = 1;
如果计算的是最终良率,ORDER BY 应改为按测试时间倒序取最后一次有效测试。FPY 与最终良率必须是两个字段,不能共用一段逻辑。
5.4 Wafer Map 的价值在于空间特征,不在于图片
YMS 分析中,单纯的良率数字定位不了问题,必须结合 Wafer Map 的空间分布。数仓不需要存图片,但需要存空间特征:
sql
-- dws_wafer_map_feature:晶圆级空间失效特征
CREATE TABLE dws_wafer_map_feature (
wafer_id STRING,
test_stage STRING,
center_fail_cnt INT,
edge_fail_cnt INT,
ring_fail_flag INT,
scratch_fail_flag INT,
cluster_cnt INT,
max_cluster_size INT,
bin1_rate DECIMAL(10,4),
feature_version STRING
);
这些特征才能与工艺维度做关联分析。例如:
-
边缘失效集中 → 优先关联刻蚀、薄膜均匀性、腔体状态
-
同一 Shot 位置重复失效 → 优先关联 Reticle、曝光套刻
-
同一批次在多片晶圆上出现相同空间特征 → 优先关联共同经过的设备与配方版本
需要注意:这类关联分析产出的是排查方向,不是因果结论。归因还需要结合 DOE 实验与工艺验证。
六、把业务语义落成数仓分层
6.1 分层职责
| 层级 | 主要内容 | 关键设计动作 |
|---|---|---|
| ODS | MES / EAP / YMS / Tester 原始数据 | 保留原始报文与源系统主键,不做业务清洗 |
| DWD | 批次流转、晶圆关系、加工执行、测试明细、设备状态、Die---Unit 映射 | 统一坐标、统一状态码、建立时变关系 |
| DWS | 批次/晶圆/产品级良率、设备 OEE、WIP 与 Cycle Time、工艺特征汇总 | 固化指标口径,排除非产品片与无效记录 |
| ADS | 良率 Pareto、OEE 看板、瓶颈分析、客诉追溯、工艺归因 | 面向具体分析场景组装 |
| DIM | 产品与版图、工艺路线、工序、设备与腔体、配方版本、Bin 字典 | 版本化管理,保留生效区间 |
6.2 DWS 层最值得沉淀的四类模型
结合前面讨论的 DWS 建模原则,半导体场景下高复用模型主要是:
-
晶圆全景宽表 :以
wafer_id为主键,融合当前批次归属、累计经过工序、CP 良率、缺陷特征、报废状态。 -
批次流转汇总表 :以
lot_id + operation_id + dt为粒度,输出投入、产出、Hold、Scrap、Rework 数量与各段耗时。 -
设备腔体效率表 :以
tool_id + chamber_id + dt为粒度,输出状态时长分布、OEE 三因子、停机 Pareto。 -
产品良率汇总表 :以
product_id + test_stage + dt为粒度,输出 FPY、最终良率、Top Bin 损失,统一对外口径。
这四类模型覆盖了 Fab 的绝大多数分析需求,且都是多下游复用,适合下沉到 DWS,而不是在各 ADS 任务里重复实现。
七、领域专属的 DQC 规则设计
半导体数仓的数据质量问题具有很强的领域特征,通用 DQC 规则远远不够。以下是几条必须落地的领域规则:
| 校验对象 | 规则 | 建议强度 |
|---|---|---|
| 批次---晶圆关系 | 同一 wafer_id 的归属区间不得重叠 |
强规则 |
| 数量守恒 | 批次拆分前后 Wafer 总数一致(扣除 Scrap) | 强规则 |
| Die 坐标 | (die_x, die_y) 必须落在产品版图有效范围内 |
强规则 |
| 测试记录 | 同一 test_run_id + wafer_id + x + y 不重复 |
强规则 |
| Bin 编码 | Hard Bin / Soft Bin 必须在字典范围内 | 强规则 |
| 设备状态 | 状态时长之和不超过窗口时长,无 Unknown 缺口 | 强规则 |
| 良率值域 | 良率必须在 0, 1 区间 | 强规则 |
| CP → FT 数量 | 封装投入 Die 数与 CP Pass Die 数可解释对账 | 弱规则(存在混批与库存) |
| Recipe 版本 | 加工时间必须能匹配到生效版本 | 强规则 |
| FDC 特征 | 关键工艺特征缺失率超阈值告警 | 弱规则 |
其中数量守恒 与状态时长闭合是半导体场景特有的高价值校验,能够提前发现批次拆分漏记、状态采集断链等严重问题。
八、三个必须提前设计的工程问题
8.1 CIM 系统语义复杂,ODS 到 DWD 是主要工作量
Fab 的 MES、EAP 往往由多家供应商提供,表结构包含大量通用扩展字段与状态码。真正的工作量在于把 OPERATION_ID = '3200' 翻译成"第几层光刻",把机台上报的状态码翻译成可用的状态分组。
建议建立领域语义映射表并版本化管理,而不是把翻译逻辑硬编码在 SQL 里。工艺路线变更时,只更新映射,不改加工代码。
8.2 FDC 高频时序数据不能全量进离线数仓
机台 Sensor 以毫秒级上报,全量入仓的成本不可控。合理架构是:
-
原始时序数据落在低成本存储或时序数据库;
-
流计算按
run_id提取统计特征(均值、极值、标准差、积分、突变点); -
离线数仓只接收Run 级特征表与元数据索引;
-
需要回溯原始波形时,通过索引回到时序存储查询。
特征表粒度为 tool_id + recipe_id + run_id,这样才能与良率明细关联,支撑参数与良率的相关性分析。
8.3 深层追溯查询不适合多表 Join
从 chip_uid 反查到原材料批次,需要跨越封装、切割、CP、加工、物料五层关系。即使用了宽表,深层回溯的查询成本依然很高。
实践中的方案是:离线数仓负责加工与固化关系,ADS 层用图数据库或支持高性能多表关联的 OLAP 引擎承载追溯查询,并把常用路径预计算为血缘宽表。不要试图用一条多层 Join 的 SQL 解决所有追溯场景。
九、模型评审时的六个检查项
在半导体数仓的模型评审会上,可以用下面六个问题判断设计是否成立:
-
粒度是否正确:事实表一行代表一次测试、一次加工执行,还是一个批次?返工记录是否被误去重?
-
分母是否明确:良率的分母是 Gross Die、Tested Die 还是 Pass Die?是否排除了 Dummy 与 Monitor?
-
时变关系是否保留:批次拆分合并、Recipe 版本变更、设备归属变更,是否都能按历史时点还原?
-
状态是否闭合:设备状态区间是否有重叠与缺口?Cycle Time 四段是否能相加还原总时长?
-
追溯是否连通:能否从出货芯片反查到晶圆坐标、加工机台、腔体、配方版本?桥表是否完整?
-
口径是否唯一:FPY、最终良率、设备 Quality、出货良率是否分别定义,是否存在一名多义?
结语
半导体数仓的难度不在于数据量,而在于制造过程的语义密度。
Lot 决定了生产流转的主线,Wafer 决定了物理追溯的主线,Die 决定了质量判定的主线,Recipe 决定了工艺归因的主线,OEE 决定了产能分析的主线,YMS 把这些主线汇聚成可行动的结论。
只有先把这些概念的粒度、关系、边界、口径定义清楚,SQL 才是在计算业务事实;否则计算出来的只是一个语法正确、业务无效的数字。这也是工业级数仓与取数脚本之间最本质的区别。
往期精彩
数仓建模实战:每日真GMV怎么算?交易域正向/逆向链路的事实表设计难点
短视频平台用户行为建模实战:如何支撑完播率、互动率与用户活跃度计算?
ERP 货龄计算问题:FIFO加权平均 | Doris SQL
面试问:数据出现异常波动,如何让 Agent 自动定位根因?| 美团
OneData 视角下的数仓建模实践:一份明细表,到底能不能归多个主题域?
面试题解析:数仓中的"烟囱式开发"到底是什么?如何看待、影响与治理方案?