Netflix: UDA 完整例子

建一个完整的、从建模定义到多系统映射使用的 UDA 全流程例子,以 Netflix 的经典业务概念 “演员(Actor)” 为主线,让你看到 UDA 是如何“建模一次,处处使用”的。


🎬 场景背景:跨系统表达 “演员” 的信息

Netflix 内部系统中,关于演员的信息存在多个碎片:

  • 企业 GraphQL API 中用于前台内容展示
  • Data Mesh 中用于推荐系统训练
  • Iceberg 表中用于数据仓库分析
  • Avro Schema 定义中用于事件流传输

每个系统模型都略有不同,造成概念割裂和数据对齐困难。


🧱 第一步:用 Upper 建模 “Actor” 概念(定义一次)

使用 UDA 的元建模语言 Upper,建模 Actor

@prefix domain: <http://netflix.com/domain#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

domain:Actor a upper:KeyedConcept ;
    upper:hasAttribute [
        upper:name "fullName" ;
        upper:datatype xsd:string ;
    ] ;
    upper:hasAttribute [
        upper:name "birthDate" ;
        upper:datatype xsd:date ;
    ] ;
    upper:hasRelationship [
        upper:name "actedIn" ;
        upper:target domain:Movie ;
        upper:cardinality upper:many ;
    ] .

这里定义了:

  • Actor 是一个有主键的概念(Keyed Concept)
  • fullNamebirthDate 属性
  • 与 Movie 存在多对多关系 actedIn

这就是“建模一次”。


🔗 第二步:建立 Mappings,连接到各个系统的实现

现在我们告诉 UDA:概念 Actor 的这些属性,在不同系统中的“落点”在哪里:

概念字段 GraphQL API Avro Schema (流) Iceberg 表(数仓)
Actor.fullName Person.name actor_name actors.name
Actor.birthDate Person.dateOfBirth actor_dob actors.birth_date

这些 Mappings 本质上是一组图中节点之间的边,让 “Actor.name” → “Iceberg 字段 actors.name” 成为图谱中的语义连线。

domain:Actor_fullName
    uda:mapsTo graphql:Person.name ;
    uda:mapsTo avro:actor_name ;
    uda:mapsTo iceberg:actors.name .
{
  "@id": "domain:Actor_fullName",
  "@type": "uda:MappedField",
  "uda:mapsTo": [
    {"@id": "graphql:Person.name"},
    {"@id": "avro:actor_name"},
    {"@id": "iceberg:actors.name"}
  ]
}


🧪 第三步:UDA 投影为不同系统的 Schema(处处表示)

📌 GraphQL 投影

type Actor @key(fields: "id") {
  id: ID!
  fullName: String
  birthDate: Date
  actedIn: [Movie]
}

投影后,这个 Schema 被自动部署进 Netflix 企业 GraphQL Gateway。

📌 Avro 投影

{
  "type": "record",
  "name": "Actor",
  "fields": [
    {"name": "actor_name", "type": "string"},
    {"name": "actor_dob", "type": "string"}
  ]
}

这个 Avro Schema 被用于构建 Kafka Stream → Data Mesh → Iceberg 数据管道。

📌 Iceberg 表投影

UDA 会自动创建一个 actors 表,并通过 CDC / Mesh pipeline 自动注入数据,映射字段为:

  • actors.name
  • actors.birth_date

你完全不需要手动建表。


📊 第四步:真实使用案例

🌐 被 PDM 系统使用

内容审核部门在 PDM 中维护 “知名演员” 列表(One Piece 演员、演出、关系等),PDM 自动将 SKOS 建模为 UDA 模型,并投影成:

  • Avro Schema → 写入 Data Mesh
  • GraphQL Schema → 注入前台 CMS API

🔎 被 Sphere 系统使用

业务用户搜索 “Actor”,Sphere:

  1. 在 UDA 知识图中查找概念 Actor
  2. 沿 Mappings 找到 Iceberg 表 actors
  3. 自动生成 SQL:
SELECT name, birth_date FROM warehouse.actors

并支持向下 drill 到 Movie 表,通过 actedIn 映射自动推导 join:

SELECT a.name, m.title
FROM warehouse.actors a
JOIN warehouse.actor_movie am ON a.id = am.actor_id
JOIN warehouse.movies m ON am.movie_id = m.id

无需用户手写任何 SQL 或理解底层 schema!


✅ 总结流程图

flowchart TD A[Upper 定义 Actor 模型] --> B[UDA 建立 Mappings] B --> C[GraphQL 投影] B --> D[Avro 投影] B --> E[Iceberg 表投影] C --> F[被前台 GraphQL 应用读取] D --> G[用于 Data Mesh 流转] E --> H[Sphere 查询自动生成 SQL] A --> I[PDM 生成概念 UI / SKOS 接入]

这就是 “建模一次,处处表示(Model Once, Represent Everywhere)” 的完整链路。
如果你愿意,我可以将整个 Actor 模型(Upper)、Avro Schema、GraphQL 类型和 SQL 查询打包成一个 JSON-LD 示例集或 RDF turtle 文件,供本地演练。想继续深入建模语言、Pipeline 构建或 Schema 变更策略吗?📐🔥

posted @ 2025-07-02 16:57  ffl  阅读(27)  评论(0)    收藏  举报