Teamcenter学习平台正式上线(https://www.plmvision.top),安装配置实施开发源码仓库,全套学习教材!关注公众号发送“二维码“咨询加入!
摘要:
第一章:硬编码的终结 —— 元数据驱动(Metadata-Driven)的本质
1.1 上帝视角:BMIDE
Type(类型) :定义了对象的“身份”和“行为”。它是一个类(Class)。例如 Item 是基类,Part 是子类,MyCompany_Bolt 是孙子类。
Property(属性) :定义了数据的“形态”。它不仅是数据类型(String, Int),更包含了业务语义(最大长度、是否必填、默认值、LOV 约束)。
1.2 运行时渲染(Runtime Rendering)
用户请求打开 Part-001。 UI 询问元数据引擎:“Part 长什么样?” 引擎回答:“它继承自 Item,有 Name(字符串),有 Weight(双精度),还有一个特殊的 Voltage(变长数组)。” UI 根据这个回答,动态画出界面。
第二章:数据库的噩梦 —— 海量字段与稀疏矩阵
存储浪费 :99% 的格子存的是 Null。IO 灾难 :数据库页(Page)会变得巨大,一次磁盘 IO 读不到几行数据。扩展地狱 :每次加一个字段,都要 Alter Table,导致全表锁死。
2.1 POM 的解法:类表继承(Class Table Inheritance)
POM_object (最底层):存 PUID(唯一ID)、创建时间。WorkspaceObject (中间层):存 Name, Owner, Group, ACL(权限)。Item (业务层):存 Item_ID。Part (领域层):存 Material(材质)。My_Special_Part (客户层):存 Voltage(电压)。
SELECT t1.puid, t2.object_name, t3.item_id, t5.voltage
FROM POM_object t1
JOIN WorkspaceObject t2 ON t1.puid = t2.puid
JOIN Item t3 ON t2.puid = t3.puid
JOIN Part t4 ON t3.puid = t4.puid
JOIN My_Special_Part t5 ON t4.puid = t5.puid
WHERE t3.item_id ='P-001';
优势 :极致的空间效率:没有 Null 值浪费。如果没有电压属性,第 5 张表就不存数据。 无限扩展:客户要加新属性,只需新建一张小表,不需要动核心的大表。
劣势 :Join 的代价 。这就是为什么 TC 对数据库性能要求极高。但在索引设计良好的情况下,5 层 Join 的速度远快于扫描一张 5000 列的稀疏宽表。
第三章:VLA (Variable Length Array) —— 变长数组的黑魔法
3.1 物理存储结构:POM_array 表
PPOM_CHAR_ARRAY (存字符串数组) PPOM_DOUBLE_ARRAY (存浮点数数组) PPOM_INT_ARRAY (存整数数组)
写入 :当你在界面上输入数组 [A, B, C]。POM 引擎遍历数组,生成 3 条 SQL Insert 语句,打入 PPOM_CHAR_ARRAY 表中。读取 :POM 引擎执行 SELECT val FROM PPOM_CHAR_ARRAY WHERE puid=? AND attr_id=? ORDER BY seq。
3.2 性能与容量的平衡:Blob 优化
在属性定义时,可以标记为“序列化存储”。 此时,POM 不会把数据拆行存入 Array 表。 而是将整个数组 [20.5, 21.0 …] 序列化为一段二进制流。 直接存储在主表的 Blob 字段中。 代价 :无法使用 SQL 进行精确搜索 (你搜不到“温度>20”的记录,因为它是二进制)。收益 :IO 速度极快 (一次读取,无需 Join)。
第四章:Form(表单)与冷热数据分离
20% 的核心数据 (ID、版本、状态)被 80% 的场景(BOM 展开、搜索)使用。 ->Hot Data 80% 的辅助数据 (详细工艺参数、备注、长描述)只有在查看详情时才用。 ->Cold Data
4.1 Master Form 机制
Item 对象 :保持极度轻量。只存核心识别信息。Item Master Form 对象 :这是一个辅助对象,专门用来背那 5000 个辅助字段的锅。关系 :通过 IMAN_master_form 关系(强所有权)链接。
4.2 懒加载(Lazy Loading)
当你在“结构管理器”里展开 BOM 时,系统只加载 Item 和 ItemRevision 表。Form 表的数据 根本不加载 。只有当你右键点击零件,选择“查看属性”时,前端才会发请求,后端才会去 Join 那个巨大的 Form 表。
第五章:Table Property(表格属性)—— 关系中的关系
5.1 存储机制:行对象 (Row Object)
定义 Row Class :在 BMIDE 里定义一个类 VendorPriceRow,包含 4 个属性。定义 Table :在主对象上定义一个属性,类型是 Reference Array(引用数组)。连接 :这个数组里存的不是值,而是指向那些 Row 对象的Tag (指针) 。
5.2 性能陷阱
如果你有一张 100 行的表。 加载这个对象时,POM 需要实例化 101 个对象(1 个主对象 + 100 个行对象)。 这就是所谓的 “N+1 Select 问题” 。TC 的优化 :同样采用了Packed Storage 策略,将这种轻量级对象的数据打包存储,减少数据库交互次数。
第六章:扩展机制 —— 动态逻辑的注入 (AOP)
6.1 操作 (Operation) 与 扩展点
Pre-Condition :在动作开始前执行。用于权限检查。Pre-Action :在数据库事务提交前执行。用于数据校验。如果不通过,抛出异常,事务回滚。Post-Action :在数据库事务提交后执行。用于触发下游动作(如发邮件、推送到 ERP)。
6.2 库分离 (Library Separation)
libUserEx.dll :这是标准库,里面全是空函数。libMyCompany.dll :这是客户开发的库,实现了具体的校验逻辑。Mapping :通过 BMIDE 的 XML 配置,将 Item_save 操作映射到 libMyCompany.dll 中的函数。
终章:偷师要点 —— 如何构建“核弹级”数据底层
拥抱类表继承 (CTI) :
不要恐惧 Join。现代数据库的 Join 性能已经非常强悍。 恐惧的是“稀疏宽表”。它会让你的 Buffer Pool 充满垃圾数据。 基类存共性,子类存特性。
不要让业务开发人员去建子表存数组。 在底层提供一套通用的 Attribute_Value 存储机制。 对小数组用“行存储”,对大数组/高频读数组用“Blob 序列化”。
识别你的 Indexable Data(需要搜索的)和 Payload Data(只读的)。 前者放在主表,后者放在 Form 表或 NoSQL 附件中。 永远不要在列表页加载 Payload Data。
UI 是奴隶,元数据是主人。 构建一个能够解析 Schema 并动态生成 SQL 的中间件层。 这是从“项目级软件”进化到“产品级软件”的必经之路。