
PDM-only 约束校验PDM-Only Constraint Validation· 当 FK/CHECK 只存在于模型、不在数据库里版本v1.0 日期2026-07-06 状态已定稿文档定位这是《Schema-RAG-Patterns.md》《Multi-Source-Ontology-Federation.md》的上游专题文档。前两份文档假设表的用途与关系是已知或可推断的本文档回答一个更前置、更隐蔽的问题当外键FK、CHECK 约束、唯一约束为了写入性能而只存在于 PowerDesigner PDM 里、并未在数据库中物化为约束时怎么校验这些看不见的约束是否仍然正确这是企业级大库特别是为高吞吐牺牲了 DB 级约束的 OLTP/日志库做自动化理解的必经难点。目录§0 为什么约束只在 PDM是个被低估的难题§1 PDM-only 约束的四类与各自的校验难点§2 核心方法三源证据交叉验证无 DB 约束版§3 FK 校验的工程化最复杂的一类§4 CHECK / 唯一约束的校验§5 置信度评分模型§6 规模与成本控制§7 校验后的处置接受、软约束、修复§8 反模式§9 与已有文档的关系§10 总结三个判断参考资料0. 为什么约束只在 PDM是个被低估的难题很多人以为有 PDM 就够了约束在不在数据库里无所谓。但只要真去做自动化数据理解就会发现这是最棘手的一类。原因有四0.1 性能驱动的约束缺失是设计不是疏忽高吞吐场景日志库、监控库、订单库高峰期为了写入吞吐故意不建 DB 级 FK/CHECKFK 每次插入都要跨表校验代价在百万 TPS 下不可接受CHECK 也有额外开销。所以工程师把这些约束只画在 PDM 里文档化语义DB 里只有裸表 索引。这是有意的工程权衡不是漏建。后果PDM 里写着orders.cust_id → customers.id (FK)但数据库的information_schema里查不到这条 FK。自动化工具若只读 DB 元数据会以为这两张表无关这恰恰是推理出错多跳走偏、关系漏发现的根因。0.2 PDM 准确度不等于约束准确度即使 PDM 整体准确度 80-90%约束部分的准确度往往更低。因为约束是最容易过时的部分业务改了关联规则、表重构了、软外键换了指向但 PDM 里的 FK 箭头没人改。一个常见现象是PDM 整体看着对但 20% 的 FK 指向已失效指向的列已废、或关系已改。0.3 没有 DB 约束可对照校验方法必须换普通的 schema drift 检测PDM vsinformation_schema在这里失效DB 里压根没这条约束diff 出来PDM 有、DB 没有是预期的不能据此判定 PDM 错。必须改用数据级和行为级证据来校验一条看不见的约束。0.4 错约束比缺约束更危险缺约束PDM 漏标只是少发现关系错约束PDM 标错会主动误导下游的 GraphRAG 多跳推理会沿着错的 FK 箭头走到无关表产出看着对实际全错的结果。这是为什么 FK 校验必须做且要做准。本文核心论点当约束只存在于 PDM 而不在 DB 时校验的本质从对账reconcile 两份显式声明变成**“证伪”**用数据是否服从这条约束来判断它是否还成立。一条 PDM 声明的 FK只要数据持续违反它引用值大量不在被引用表它就大概率已失效。下面展开方法。1. PDM-only 约束的四类与各自的校验难点PDM 里可能只在模型、不在 DB的约束主要有四类校验难度差异巨大约束类型PDM 里的形式校验难度核心难点外键 FKchild.col → parent.pk最高要跨表查值域包含数据脏会干扰判断CHECK 约束col IN (a,b)/col 0/col ~ regex中单表内验证但要识别业务上允许的脏值 vs “约束已失效”唯一约束 UNIQUEUNIQUE(col_a, col_b)中低单表 count distinct但要处理软重复历史数据)NOT NULLcol IS NOT NULL低单表 count null最简单本文重点在前两类FK 与 CHECKUNIQUE/NOT NULL 校验直白查数据即可如 Qualytics/Great Expectations 的 schema 校验 [10]而 FK/CHECK 因为涉及约束 vs 脏数据的区分是真正的工程难点。1.1 FK 的特殊性引用完整性无法靠 DB 兜底DB 里有 FK 时违反引用完整性的插入会被 DB 直接拒数据天然服从约束。PDM-only FK 没有这道兜底数据可能早就违反了插入了指向已删客户的订单但你不知道。所以 FK 校验必须主动跑引用完整性检查referential integrity check这是 Great Expectations、Dataedo、Databricks informational constraint 等工具的核心用途 [1] [2] [3] [11]。其底层依赖包含依赖检测Inclusion Dependency, IND判断 child 列值是否都出现在 parent 列里Bauckmann 等给出了高效算法 [5]。1.2 CHECK 的特殊性违规可能是脏数据也可能是约束变了status IN (active,closed)这条 CHECK若数据里出现statussuspended有两种可能① 业务新增了 suspended 状态但 PDM 没更新约束过时该改 PDM② 这是脏数据约束对数据错该清洗。校验工具无法自动区分这两种必须结合业务判断或 LLM 语义推理。2. 核心方法三源证据交叉验证无 DB 约束版配套的 PDM 校准管线用元数据/血缘/数据三路验证。但当约束只在 PDM 时元数据这路基本失效DB 元数据查不到约束所以必须强化另外两路并加入第四路行为证据实际查询怎么用的。PDM 声明的约束(如: child.col → parent.pk 是 FK) │ ├── 证据①:数据服从性(主动跑约束校验) │ FK: child.col 的值有多少在 parent.pk 里(引用完整性) │ CHECK: 有多少行违反规则 │ → 核心证据,违反率高则约束存疑 │ ├── 证据②:血缘行为(SQL 实际怎么 JOIN) │ SQL 日志里这条关系被 JOIN 使用的频率 │ → 从没用过 关系可能已废 │ ├── 证据③:LLM 语义判断 │ 列名/注释/样本 是否支持这条关系/约束合理 │ → 补语义维度 │ └── 证据④:演化历史(约束何时加的、改过没) PDM 版本历史 表的变更记录 → 老约束风险更高 │ ▼ 加权投票 → 置信度 高 → 采信(约束仍有效) 中 → 待审 低 → 标记失效/人工复核与配套管线的关键区别配套管线里元数据 diff是第一层全自动高置信本文场景元数据这路失效数据服从性证据升级为第一主力。这是PDM-only 约束场景的方法学核心调整。该思路与 Flatiron DATA-VALID 框架对自动抽取数据建立分级置信与验证[8]、Palantir 的 LLM schema matching 多源核对 [9] 同源。3. FK 校验的工程化最复杂的一类FK 是最值得展开的它最难、最容易错、危害最大。3.1 引用完整性检查Referential Integrity Check对 PDM 声明的每条 FK主动算引用值有多少在被引用表里defcheck_referential_integrity(child_tbl,child_col,parent_tbl,parent_col,sample_ratio0.1):校验 PDM 声明的 FK: child.col → parent.pk 是否仍被数据服从。# 采样 child 表(大表不全扫),取 FK 列的非空值fk_valuessample_query(fSELECT{child_col}FROM{child_tbl}WHERE{child_col}IS NOT NULL,ratiosample_ratio)# 批量查这些值在 parent 表的命中情况matched,totalbatch_check_membership(fk_values,parent_tbl,parent_col)violation_rate1-matched/totalreturn{fk:f{child_tbl}.{child_col}→{parent_tbl}.{parent_col},violation_rate:violation_rate,# 核心指标sample_size:total,verdict:classify_violation(violation_rate),}defclassify_violation(rate):# 阈值需按业务调,以下是经验起点ifrate0.01:returnhigh_confidence# 1% 违规:约束有效(零星脏值)ifrate0.10:returnmedium# 1-10%:可能有脏数据,约束大概率仍有效ifrate0.50:returnsuspect# 10-50%:约束存疑(可能已失效或半失效)returnlikely_invalid# 50% 违规:约束大概率已失效阈值是核心决策点1% / 10% / 50% 是经验起点必须按业务调。有些域容忍高脏值日志库引用实体常缺失有些零容忍财务。阈值不能一刀切建议按业务域分组建阈值 profile。3.2 关键难点区分约束失效 vs “数据脏”violation_rate 高时有两种本质不同的原因处置完全相反原因violation_rate 表现正确处置约束已失效关系改了/表重构了违规值有规律如全指向某个已废弃的旧客户表改 PDM删/改这条 FK数据脏约束对数据有问题违规值零散、无规律清洗数据PDM 不动怎么自动区分看违规值的分布。如果违规值高度集中如 80% 违规都指向同一个不存在的 parent id更像指向已废弃实体约束失效如果违规值分散各种不存在的 id 都有更像脏数据。这个判断可以用 LLM 辅助把违规值样本 列注释喂 LLM让它判断这像关系失效还是数据质量问题。3.3 采样策略大表成本控制全表全列对跑 IND/FK 校验是 O(n²)大表不可行。分层采样defstratified_fk_check(child_tbl,child_col,parent_tbl,parent_col):# 第一遍:小样本(1%)快速筛查,识别高违规候选quickcheck_referential_integrity(child_tbl,child_col,parent_tbl,parent_col,sample_ratio0.01)ifquick.verdictin(high_confidence,):returnquick# 低违规,无需深查# 第二遍:对存疑的关系大样本(10%)或全量复核deepcheck_referential_integrity(child_tbl,child_col,parent_tbl,parent_col,sample_ratio0.10)# 第三遍(可选):极高价值/极存疑关系全量ifdeep.verdictsuspectandis_high_value(child_tbl):returncheck_referential_integrity(child_tbl,child_col,parent_tbl,parent_col,sample_ratio1.0)returndeep工程要点① 分层采样把成本集中在存疑关系上高置信的一遍过②时间维度采样不同时段查业务高峰 vs 低谷因为高峰期可能临时数据脏③ 校验结果要带checked_at和sample_size支持后续复检与置信度衰减老结果可信度下降④ IND 检测的扩展性在大表上是硬约束Kruse BTW 2015 讨论了 scale-out 策略 [12]。3.4 行为证据用查询日志佐证 FK 是否真被用光看数据服从性还不够。加一路行为证据翻 SQL 查询日志看这条 FK 关系在实际业务查询里被 JOIN 的频率。defbehavior_evidence(child_tbl,parent_tbl,sql_log):从查询日志统计这条 FK 被实际 JOIN 的频率。joinssql_log.find_joins_between(child_tbl,parent_tbl)return{join_count:len(joins),distinct_queries:len({j.query_idforjinjoins}),verdict:usediflen(joins)0elsenever_used,}# never_used 的 FK:数据服从但从未被查 → 可能是僵尸约束(PDM 历史遗留,业务早不用)行为证据的价值数据服从violation_rate 低 从未 JOIN 可能是僵尸 FKPDM 里画着数据碰巧服从但业务查询从不走这条路。这类 FK 留着会污染多跳推理GraphRAG 会沿它走到无关表。把它标低业务价值多跳时降权或忽略。3.5 多列复合 FK 的特殊处理PDM 可能声明复合外键(order_id, line_no) → (order_id, line_no)。这种校验要按列组合而非单列# 复合 FK:必须同时匹配所有列matchedcheck_membership_composite(child_rows[(r.order_id,r.line_no)forrinsample_child],parent_tblorder_lines,parent_cols[order_id,line_no])Zhang et al. (VLDB 2010) 的多列 FK 发现算法是这块的经典 [4]。对违规值零星脏值 vs 规律失效的精细区分可借助条件包含依赖CINDBauckmann ICDE 2012 区分覆盖条件值出现时必在 parent与完整条件所有值都在 parent能分离关系存在但数据脏 vs “关系本身失效” [6]。候选 FK 的批量判定则可用 IND ML 二分类的经典管线 [7]。4. CHECK / 唯一约束的校验4.1 CHECK 校验违规率 语义判断defcheck_check_constraint(tbl,col,rule,sample_ratio0.1):校验 PDM 声明的 CHECK 约束(如 status IN (active,closed))。rowssample_query(fSELECT{col}FROM{tbl},ratiosample_ratio)violations[rforrinrowsifnotrule.satisfies(r[col])]ratelen(violations)/max(1,len(rows))# 关键:违规值的分布(集中约束过时;分散脏数据)distinct_violationsCounter(r[col]forrinviolations)return{violation_rate:rate,violation_values:distinct_violations.most_common(10),needs_semantic_judgment:rate0.05,# 高违规需 LLM/人工判断原因}CHECK 校验的难点全在违规值含义statussuspended违规是业务新增状态改 PDM还是脏数据清洗这个判断常需 LLM 或业务专家。高频违规值喂 LLM结合列注释判断这像合法新值还是错误数据。4.2 唯一约束校验defcheck_unique(tbl,cols,sample_ratio0.1):校验 PDM 声明的 UNIQUE(col_a, col_b)。# 单表 count distinct vs count(*),最简单total,distinctsample_query(fSELECT COUNT(*) AS t, COUNT(DISTINCT ({,.join(cols)})) AS d FROM{tbl},ratiosample_ratio)dup_rate1-distinct/max(1,total)# 注意:历史数据可能软重复(旧业务允许),不代表约束错return{dup_rate:dup_rate,verdict:classify_dup(dup_rate)}陷阱历史数据常允许软重复如旧版订单系统不强制唯一dup_rate 高不代表 UNIQUE 约束错可能只是历史遗留。要按时间分段看近期数据 dup_rate 低、历史高 约束对但历史脏全程高 约束可能从没生效。5. 置信度评分模型三源数据/行为/语义 演化证据怎么合成一个置信度这是中置信进待审的判定依据。5.1 评分维度与权重经验起点维度权重高置信信号低置信信号数据服从性违规率0.45违规率 1%违规率 10%行为使用JOIN 频率0.25频繁被查从未使用LLM 语义合理性0.15列名/语义同源语义无关演化新鲜度PDM 版本/表变更0.15近期校准过老约束、表刚重构defconfidence_score(data_obey,behavior,semantic,freshness):score(0.45*data_obey# 0-1, 违规率越低越高0.25*behavior# 0-1, 使用频率0.15*semantic# 0-1, LLM 判定合理性0.15*freshness)# 0-1, 新鲜度ifscore0.85:returnhigh# 自动采信ifscore0.60:returnmedium# 待审队列returnlow# 人工复核权重不能一劳永逸数据服从性权重最高0.45是因为它最客观。但某些域日志库引用缺失常态数据这路噪声大应降权、提行为权重。建议按域分权重 profile并用人工复核结果回流校准权重监督学习思路。5.2 冲突仲裁三源常冲突数据服从但 LLM 说语义无关。仲裁规则数据高违规 → 一票否决数据大量违反无论其他路怎么说约束都存疑。数据低违规 行为从未用 → 标僵尸约束有效但无业务价值多跳降权。数据低违规 LLM 语义无关 → 进待审可能碰巧服从需人工确认关系真实性。6. 规模与成本控制几百表 分表万上的库里PDM 声明的约束可能有几千条。全量深查不可行。6.1 优先级排序按价值 × 风险排序先查高价值高风险的约束defprioritize(constraints):returnsorted(constraints,keylambdac:(value_score(c),# 核心域/高频查询表 长尾risk_score(c),# 老约束/表刚重构 新鲜约束),reverseTrue)# 先校准 top 20% 高价值表的约束(覆盖 80% 业务查询路径)6.2 增量校验不要每次全量。只校验自上次校验后变更的部分表结构变了DDL diff 检测→ 重查相关约束。数据大幅增长/变化 → 触发该表约束复检。PDM 版本更新 → 对比新旧 PDM只查 diff 部分。6.3 持续监控而非一次性把约束校验做成周期性数据质量任务像 Great Expectations 的 checkpoint每周/每月跑一次采样校验violation_rate 突然飙升 → 告警约束可能刚开始失效。这比一次性校验更能抓住约束何时开始失效。7. 校验后的处置接受、软约束、修复校验出结果后不是简单对/错二分有四种处置校验结果处置说明高置信有效接受入目录约束仍成立正常使用数据服从但业务不用僵尸降权标记入目录但标低业务价值多跳时降权或忽略中置信存疑软约束informational不强制执行但记录供查询优化/RAG 用 [3]低置信/高违规标记失效 人工复核不入目录或标疑似失效等人工确认后改 PDM“软约束”informational constraint是关键中间态Databricks 等支持声明informational PK/FK不强制执行不影响写入性能但告诉查询优化器和下游工具这里有个关系可用 [3]。PDM-only 约束校验后对数据服从但未物化的约束可以正式声明为 DB 的 informational constraint让它从PDM 里看不见变成系统可见但不强制既保性能又让下游能用。8. 反模式反模式 1把 PDM 约束当全真直接用❌ PDM 里的 FK 全部当作有效关系灌进 GraphRAG 做多跳。后果那 10-20% 失效/僵尸 FK 误导推理多跳走到无关表结果看着对实际全错。正确做法每条 PDM 约束都过校验、标置信度低置信的不入推理图或降权。反模式 2因为 DB 里没约束就放弃关系发现❌ “information_schema查不到 FK这库没结构没法做自动化理解。”后果错失 PDM 这个宝贵先验退回从零推断成本与准确度都差。正确做法PDM-only 约束正是要用数据/行为证据去验证的不能因 DB 没物化就放弃。反模式 3只看违规率不区分约束失效 vs 数据脏❌ violation_rate 高就判约束错直接删 PDM 里的 FK。后果把数据质量问题误判成约束失效删了有效约束掩盖了真正的数据脏。正确做法看违规值分布 LLM/业务判断区分两种原因分别处置改 PDM vs 清洗数据。反模式 4全量深查所有约束❌ 几千条 PDM 约束每条都跑全表全列 IND 校验。后果成本爆炸大表 O(n²)周期长得不可行。正确做法分层采样 优先级排序 增量校验成本集中在存疑与高价值约束。反模式 5校验一次就不管❌ 做过一次校验标记完置信度以后不再复查。后果约束会持续漂移业务变、数据长老的校验结果过时新失效的约束没人发现。正确做法周期性采样复检 突变告警把约束校验作为持续的数据质量任务。9. 与已有文档的关系已有文档本文关系《Automated-Database-Understanding.md》本文是其 §3/§4PDM 先验融入 关系发现深度的深化子专题——上游文档给自动理解的全景四层管线本文专门处理其中约束只在 PDM、不在 DB这个最难的校验场景《Schema-RAG-Patterns.md》本文是其 Schema Catalog§5的上游校准层——catalog 里的关系字段relations来自本文校验后的可信约束。低置信约束不应直接进 catalog 误导路由《Multi-Source-Ontology-Federation.md》本文是其数据契约DPROD的关系质量保障——契约声明的 schema 关系必须经本文校验否则契约本身不可信《Ontology-Implementation-Patterns.md》本文是模式 F隐式本体的前置质量门——隐式本体的列注释/关系提示若基于未校验的 PDM 约束会把错误固化进本体配套 PDM 校准管线本文是其中关系层校验的深化——专门处理约束只在 PDM这个配套管线里元数据 diff 失效的场景不重复本文不重述配套管线的元数据 diff、血缘解析见配套文档。新内容PDM-only 约束的四类与校验难点、三源证据无 DB 约束版、FK 校验工程化采样/区分失效 vs 脏/行为证据/复合 FK、置信度评分、软约束处置。10. 总结三个判断判断 1PDM-only 约束校验的本质是证伪不是对账普通 drift 检测是两份显式声明对账PDM vs DB。约束只在 PDM 时DB 那份不存在对账无对象。校验变成用数据是否服从来证伪持续违反的约束大概率失效。这是方法学的根本转向。判断 2数据服从性是第一证据但不是唯一证据没有 DB 约束时数据违规率是最客观的证据权重最高。但它有盲区僵尸约束数据服从但业务不用脏数据违规高但约束对。必须叠加行为证据JOIN 频率和语义证据LLM 判断三源投票才能区分有效/僵尸/失效/脏数据。判断 3软约束是性能与可信的桥梁PDM-only 约束的本质矛盾是要语义可信 vs “要写入性能”所以不物化 FK。软约束informational constraint破解了这个矛盾声明关系供下游用可信但不强制执行保性能。校验后的高置信约束应正式声明为 DB 的 informational constraint让它从PDM 里看不见变成系统可见但不强制。最后的话约束只在 PDM、不在数据库看起来是个工程细节实则是企业级数据理解的拦路虎。它让最常用的对账式校验失效迫使方法转向数据证伪。但只要认清用数据服从性 行为证据 语义判断三源投票配合分层采样与软约束处置就能把那 80-90% 的 PDM 准确度持续提升到可用水平。本文是这个方向的方法学与工程框架。参考资料编号来源主题链接[1]Great ExpectationsValidate Data Integrity引用完整性/FK 校验实践https://docs.greatexpectations.io/docs/reference/learn/data_quality_use_cases/integrity/[2]ChartDBAI Foreign Key DetectionFK 检测与置信度https://chartdb.io/blog/foreign-keys-in-databases-importance-and-ai-detection[3]DatabricksValidate pipelinesinformational PK/FK 软约束https://docs.databricks.com/gcp/en/transform/validate[4]VLDB (Zhang et al., 2010)On Multi-Column Foreign Key Discovery复合 FK 发现https://vldb.org/pvdb/vol3/R72.pdf[5]HPI (Bauckmann et al.)Efficiently Detecting Inclusion DependenciesIND 高效检测https://hpi.de/fileadmin/user_upload/fachgebiete/naumann/publications/PDFs/2007_bauckmann_efficiently.pdf[6]ICDE (Bauckmann et al., 2012)Discovering Conditional Inclusion Dependencies条件 IND覆盖 vs 完整https://dl.acm.org/doi/10.1145/2396761.2398580[7]ResearchGate (Rostin et al.)A Machine Learning Approach to Foreign Key DiscoveryIND ML 分类https://www.researchgate.net/publication/221035501_A_Machine_Learning_Approach_to_Foreign_Key_Discovery[8]Flatiron HealthDATA-VALID FrameworkLLM/自动抽取数据的验证方法论https://resources.flatiron.com/publications/ensuring-reliability-of-curated-ehr-derived-data-the-validation-of-accuracy-for-llm/ml-extracted-information-and-data-valid-framework[9]Palantir BuildSchema Matching and Data Validation Using LLMshttps://build.palantir.com/platform/ee5c0f4d-8c21-4987-be51-612973a03c99[10]QualyticsData Quality Checksschema 校验/完整性https://qualytics.ai/data-governance-and-quality/data-quality-checks[11]DataedoTesting Foreign KeysFK 测试实践https://docs.dataedo.com/data-catalog/documenting/documentation-tips/testing-foreign-keys/[12]BTW (Kruse et al., 2015)Scaling Out the Discovery of Inclusion DependenciesIND 扩展https://btw-2015.informatik.uni-hamburg.de/res/proceedings/Hauptband/Wiss/Kruse-Scaling_Out_the_Discovery_of.pdf