产品数据管理(Product Data Management,PDM)是管理所有与产品相关的信息和过程的技术,其主要功能包括产品文档管理、产品结构管理和工作流管理等。PDM能使产品数据在其生命周期内保持一致、最新和安全,能够缩短产品研发周期、降低成本、提高质量,并为企业赢得竞争等优势。PDM为机械制造企业数据管理系统的核心系统之一,也是数字化制造的实现奠定基本物质基础之一,但现代PDM也面临着挑战,如PDM一般采用关系型数据库,而传统关系型数据库很难克服数据库高并发读写、海量数据的高效率存储和访问、数据库的高可扩展性和高可用性的问题。说明随着MBE全三维信息化技术逐步成熟,装备制造业PDM系统中数据的结构化特点越来越弱——企业能够不需要数据转换而充分使用三维模型,则企业获得的数据将是原始CAD数据。
关系型数据库中的数据往往需要极高的精确度,一般须遵守ACID特征,非关系型数据库NoSQL则打破了长久以来关系型数据库与ACID理论大一统的局面。相对于传统的关系型数据库系统,NoSQL数据管理系统有很多优势特征:高扩展性、高容错性、高性价比等,这些特性使得NoSQL数据管理系统更利于管理大规模海量数据,且能有效地处理非结构化数据,例如文件、电子邮件、多媒体和社会媒体。
产品结构与配置管理作为PDM的核心内容之一,它以创建产品结构树为中心,从PDM集成应用系统中自动捕捉产品结构信息建立产品结构树。基于此,本文着重研究以非关系型数据库NoSQL来存储产品结构信息,以产品结构树形式展示给用户的问题。
1 产品结构树
产品结构树用于对产品进行逐层分解,第一层将产品分解成多个部件(在树中,零件为叶子结点,部件为非叶子结点),而部件则再进一步分解成子部件和零件,此过程以此类推,直到将此产品的全部组成成分分解成零件为止,由此形成的分层的树状结构便是产品结构树,故产品结构树反映了产品与零部件之间的层次关系。产品A的分解过程如图1所示:
图1 产品分解过程示例图
如图1所示的产品A是由多个零部件组成,其中部件又由多个零件或子部件组成。由图1可知,产品结构树为多叉树,而多叉树中非叶子结点的子结点数是没有限制的,且产品结构树中的零部件可能会被多个部件重复使用(如图2所示),树中每个部件都有,n(n>=0)个子部件和零件组成,每个零件又被n(n>=0)部件使用,则树的内部为多对多的关系。
图2 产品结构树中零部件被重用示例图
则由图1和图2可知,产品结构树主要有两个特点:树中非叶子结点的子结点数不固定;树内部结点之间为多对多关系。产品结构树的存储结构主要有两种:双亲表示法和孩子表示法。由于RDB(关系型数据库)的表中的列数是固定的,不允许列数动态地变化,因而在基于RDB的传统PDM系统产品的数据存储结构中,主要建有基本信息表:产品、部件及零件表,和一个关系表以记录产品的配置关系,在关系表中以一条记录来记录一对直系的父子关系,即将多对多的关系拆分成多个一对一的关系,并且基于此关系表记录产品的更新信息。对于成型产品,其配置结构是固定的,故可在基本信息中直接记录其结构关系,结合产品结构树及RDB的特点,本文以文档型NoSQL数据库(MongoDB)作为其底层数据支撑环境来研究产品结构树的数据组织,由于NoSQL具有嵌入文档、模式自由等特点,因而较RDB能更好地记录产品的基本属性与配置关系信息。
2 基于NoSQL的PDM数据存储结构及产品结构树生成算法
根据产品结构树创建原理,利用NoSQL数据库的特点,摒弃PDM系统中数据在关系型数据库中的存储结构的传统模式,以更灵活的方式构建PDM的数据存储结构,便于用户更好地理解和操作。
2.1 基于NoSQL的PDM基本信息的数据存储结构
NoSQL打破RDB的一行只记录一对关系规则,利用NoSQL的数组和内嵌文档功能,一条记录便可以记录多组关系对的功能,且关系对的数目无限制,故可在产品基本信息的集合中设定一个Children[]数组字段,即将产品结构树中的多对多关系拆分成一对多的关系,且在Children[]数组字段中记录该产品(或部件)的所有直系孩子结点的编码_id,并在Children[]字段中再插入一个num字段以记录被包含的相应孩子结点的数量,而在零件集合中则没有Children[]数组字段。
在NoSQL中,PDM基本信息主要由产品product集合、部件component集合、零件parts集合组成,产品product的属性主要有产品编码Product_id、产品名称Name、类型Type、子结点Children[]、自制/外购Make/Buy、净重Weight、创建者Creator、设计者Designer和创建日期CreateDate,字段子结点Children[]是一个数组,在Children[]中设有_id字段、Type字段和num字段,分别记录此产品的所有直系孩子结点的编码、相应结点的类型及此结点被包含的数量。该结构相较于传统RDB需要多条行记录才能完成的存储方式而言,更便于数据库管理员直观地看到某父结点的直系子结点。产品product集合在数据库中的存储结构如下所示。
部件component集合中的主要属性为部件编码Component_id、部件名称Name、类型Type、子结点Children[]、自制/外购Make/Buy、净重Weight、创建者Creator、设计者Designer和创建日期CreateDate,部件component集合在数据库中的存储结构如下所示:
零件parts集合的主要属性为Parts_id、部件名称Name、类型Type、材质Material、图纸Picture、自制/外购Make/Buy、净重Weight、数量quantity、创建者Creator、设计者Designer和创建日期CreateDate,零件已是最小的产品单位,它在产品结构树中处于最底层的,故其零件parts集合在数据库中的存储结构如下所示:
2.2 产品结构树生成算法
基于上述存储结构,采用层次遍历方法生成产品结构树,算法如下:
(1)以某一产品为根结点,即为树的第一层结点;
(2)在产品集合中查找此产品记录中的Children[]字段,记下其所有的孩子结点以及它们的类型Type,即为树的第二层结点;
(3)第二层的所有结点中,若有类型为零件的直接定为叶子结点,若为部件类型则定为非叶子结点并查找其在部件集合记录中的Children[]字段中的所有孩子结点的编码及类型,这些孩子结点组成了树的第三层;
(4)对第三层的结点的处理方法同第三步对第二层结点所做的处理,以此类推,直到树的最底层中的各个结点均为零件类型为止。
若产品A的结构为(A(B1(B3(a5,a6),a2),B2(B4(a7,a8,a9),a3,a4),al))以大写字母代表产品(A、A1、…)和(子)部件(B、B1、…),以及小写字母代表零件(a、a1…),采用Tree Tag技术在Jsp页面上显示,如图3所示:
图3 产品A结构树示例图
3 基于NoSQL的PDM系统产品结构树的维护
随着产品信息多样性的发展、产品升级,以及客户对产品性能、结构、特征等需求的变化,产品结构树的结构也必然随之发生变化,其中,增加、删除零部件操作,即对产品结构树做增加、删除结点(根结点除外)操作最为关键。
3.1 产品结构树的结构关系地整理
PDM的基本信息集合中产品product、部件component和零件parts集合皆用于存放某个(某类)产品的全部信息,而配置关系仅表示相邻两层之间的直系父子关系,不能全面、直观地表达整棵树中结点之间的(被)包含关系,因而在基于RDB的PDM系统中,查找某结点的祖先或后代时需要多次连接操作才能完成。
在关系型数据库中,通常用闭包表(如表1所示)来存储整棵树的结构,用祖先(ancestor)和后代(descendant)两个字段将树中任意结点的祖先一后代关系对存储于此闭包表中。因而在查找某结点X的祖先(后代)时,只需要在闭包表中搜索后代(祖先)是X的所有行的祖先(后代)字段对应的结点即可。
表1 闭包表
在NoSQL(以MongoDB为例)亦可采用闭包结构形式的集合来存储产品结构树中的结构关系。设集合RelationComplete用来存储产品的结构关系,并且对它只做添加新记录的操作。RelationComplete主要设有六个字段:编码_id、参考referenceID、所属产品ofProduct、后代descendant[]、祖先ancestor[]和类型Type。其中referenceID和ofProduct字段是内嵌文档,包括相应参考结点编码_id和名称name两个列;后代descendant[]字段是一个嵌入文档的数组,包括后代的编码descendantld、名称name、类型type、层次pathLevel四列。字段层次pathlevel能更加清晰地记录此后代结点与参考的祖先结点之间的间隔层数,其中,一个结点的直接子结点的pathLevel为1,再下一层为2,以此类推。集合RelationComplete结构如下所示:
在集合RelationComplete中,由于只有类型type为产品和部件的参考结点才可能有后代descendant[]字段,因而用户在查找某产品中结点的祖先时,首先在所属产品的记录中后代descendant[]数组字段中查找此结点,然后将相应的参考结点按照此后代结点的pathLevel值进行排序;而在查找非叶子结点的后代时,直接查找其后代descendant[]数组字段中的所有记录即可,故可一次地查出此结点在树中的所有后代,较传统RDB需多次查找的模式更为灵活。
3.2 产品结构树的维护
产品结构树的维护亦采用闭包结构来管理,更新时,只需更新变动的树枝上的祖先一后代关系即可。产品结构树的维护过程如图4所示。
图4 产品结构树的维护过程
如图4所示,在更新树中结点X1的基本四种情况中,只需更新变动树枝上X与T的后代信息,这里只考虑了更新树中底层的情况,其它情况可基于此四种情况推演得出。
具体实现时,首先创建集合RelationChange用以保存结构树更新时的临时关系,其结构与RelationComplete相同,设有四个字段编码_id、祖先(ancestor)、后代(descendant[])和类型Type,而后代数组字段记录则相应地包含后代的编码childld、名称name、类型type。
3.2.1 插入节点
结点的更新必须同时更新其祖先及后代信息,如在树Ax中添加一个叶子结点,则该结点祖先与后代的关系都需要更新,其过程如图5所示。
图5 添加叶子结点过程
如图5所示,向树Ax的非叶子结点Bx中添加一个叶子结点b,则零件a4、a5与b组成新部件Bx1,即其原父部件由Bx变成新部件Bx1,产品Ax则变成新产品Ax1。而在集合RelationChange中,第一步将集合RelationComplete中产品Ax内部祖先与后代的关系对复制到集合中,则集合RelationChange如下所示:
由于添加结点b时,a4、a5与b组成新结点Bx1,第二步则在集合RelationChange中插入一条关于Bx1的祖先与后代关系记录,Bx1记录如下所示:
第三步:在字段后代descendant[]中查找含有a5结点的记录,插入Bx2以及Bx2的(除结点a4、a5以外)后代的信息。
第四步:将集合中信息中含有Bx的记录删除。
当添加一棵子树(部件)时,首先将这棵树内部的祖先与后代关系对从RelationComplete复制到集合RelationChange中,然后再将沿着此子树所在产品结构树中的位置向上遍历的结点与子树中的所有结点设置为祖先与后代的关系对,并插入到相应的集合中。
3.2.2 删除节点
删除叶子结点的过程如图6所示,若删除Ax中的结点a3,则其父结点B1变成B11(只有a1和a2两个孩子结点),首先删除集合中祖先结点为B1的记录,并添加B11记录;然后在集合的后代信息查找B1以及a3记录,插入B11记录,并删除B1和a3记录。
图6 删除一个叶子结点
删除一棵完整的子树X时,首先在集合后代descendant[]数组字段中删除所有以X为后代的记录,然后在集合中删除树X的记录。在集合RelationChange中完成更新操作后,将更新信息添加到基本信息集合中,然后删除集合RelationChange。当再次更新产品结构树时,再创建集合RelationChange,如是在此集合中存储的是正在更新的树的相关信息。
4 结束语
本文以产品结构树来描述产品的配置关系,分析了产品结构树的结构特点,以及基于RDB的传统PDM产品信息数据存储结构,提出了利用NoSQL-MongoDB嵌入文档的数组产品信息的新存储结构模式,以及在运行时动态创建产品结构树的新思路,较关系型数据库建表的传统模式更加便于管理产品的结构关系,且更利于产品结构树的维护,为企业产品数据管理探索出一条更为广阔的新视野。
核心关注:拓步ERP系统平台是覆盖了众多的业务领域、行业应用,蕴涵了丰富的ERP管理思想,集成了ERP软件业务管理理念,功能涉及供应链、成本、制造、CRM、HR等众多业务领域的管理,全面涵盖了企业关注ERP管理系统的核心领域,是众多中小企业信息化建设首选的ERP管理软件信赖品牌。
转载请注明出处:拓步ERP资讯网http://www.toberp.com/
本文标题:基于NoSQL的PDM产品结构数据组织