5.08 图数据库的结构设计¶
图数据库采用图结构表示现实世界中的实体和关系,其图数据模式由节点、边与属性构成:节点表示现实世界中的实体,对应ERD概念模型中的实体。节点具有标签(名称)和属性,其中一个属性为唯一属性,作为该节点的唯一标识。边表示两个节点之间的关系,对应ERD概念模型中的关系。边具有方向,即它有起始节点和终止节点。边也具有属性但不必需要唯一属性,其起始节点和终止节点可作为唯一标识。本章节以属性图模型为例,介绍图数据库的设计。
5.08.1 图结构设计规则¶
ERD概念模型包含一组具有属性的实体,这些实体通常表示真实世界中的对象,并描述实体之间的联系。通常而言,任何ERD概念模型都存在一个对应的属性图模式。实体和关系可以分别映射为属性图模型中的顶点类型和边类型,节点和关系属性分别存储实体和关系的属性。然而,某些ERD概念模型可能包含无法直接映射到图数据模型的结构。例如,ERD概念模型可能包含多元关系,而属性图模式仅支持节点和二元边。因此,在将ERD概念模型转换为图数据库模式时,需要先将原始ERD模型中的多元关系转换为二元关系。
我们以图5-1-2中用户、运营商和手机之间的1:1:n三元关系为例,说明ERD概念模型中多元关系的调整方法。首先,将该三元关系“使用”映射到一个弱实体,并为该弱实体与各相关实体建立二元关系。如果该关系具有属性,则将这些属性添加到弱实体中,例如“使用”的时间属性。这种方法将三元关系转换为二元关系,而对于三元以上的多元关系,转换方法类似,即将多元关系分解为多个二元关系。 对于更为复杂的ERD概念模型的结构,如父类-子类的ISA联系等,本书不再对其调整方法进行详细讨论。
将调整过的ERD概念模型映射为图数据库模式时,遵循以下设计规则: - 实体转换规则。一个实体转换为一个节点。如5-1-1中的员工实体映射为一个员工节点(employee),项目实体转换为项目节点(project)。 - 属性转换规则。将ERD概念模型中实体的属性转换为节点的属性。例如,图5.01中的员工实体的属性有员工编号、姓名、性别、年龄等,这些属性映射为员工节点的属性。而对于多值属性,则将其转换为新节点,并建立二元关系。具体来说,多值属性的具体值成为新节点的属性。例如,图5-1-1中员工的“技能”多值属性技能转换为“技能”节点,该节点包含“技能”属性,并与对应员工建立“具有”关系。 - 联系转换规则。实体之间的每个联系都映射到连接相应节点的边。边的名称可以是关系的名称,或基于所连接节点的角色命名。与 ERD 概念模型不同,在图数据库中,边是有向的,因此需要区分每条边的起始节点和终止节点。例如,对于员工和项目之间的关系,有两种关系映射方式:员工工作于项目(即,起始节点为员工,终止节点为项目,关系名称为“工作”)和项目雇佣员工(起始节点为项目,终止节点为员工,关系名称为“雇佣”)。
5.08.2 图结构设计¶
基于以上的规则,我们对图5-1-3(b)的购物网站ERD概念模型进行图结构设计。在后面的图数据库设计中,我们用(起始节点)-[:边名称{边属性}]->(终止节点)的形式表示边的设计。
节点设计
用户节点: User(Uid, Uname, Uadd, Tel),Uid为主码;
商品节点: Product(Pid, Pname, Category, Price, Padd),Pid为主码;
订单详情节点: OrderLine(Oid, Date),Oid为主码;
喜好节点: Preference(Pref),Pref为主码;
边设计
“下单”边: User - [:HAS_ORDER] -> OrderLine
“包含”边: OrderLine - [:HAS_PRODUCT {Quantity}] -> Product
“喜好”边: User - [:HAS_Pref] -> Preference
首先,将图5-1-3(b)中每个实体类转换为一个节点模式,实体类的唯一属性和单值属性构成节点的属性,并将其唯一性属性设为主码。以此实体转换规则生成的节点包括:用户节点User(Uid, Uname, Uadd, Tel),商品节点Product(Pid, Pname, Category, Price, Padd)以及订单详情节点OrderLine(Oid, Date),其中下划线标注的属性为主码。对于多值属性,依据转换规则,创建喜好节点Preference(Pref),其中Pref为唯一属性,并通过“喜好”关系HAS_Pref与用户节点关联。
接下来,依据关系转换规则,将图5-1-3(b)中的联系转换为图数据模式中的边:“下单”边User-[:HAS_ORDER]->OrderLine,“包含”边OrderLine-[:HAS_PRODUCT {Quantity}]->Product。其中,HAS_ORDER表示“下单”关系,HAS_PRODUCT表示“包含”关系,Quantity表示订单详情节点OrderLine与商品节点Product之间的联系属性“数量”。
5.08.3 合理利用数据冗余¶
与关系型数据库和文档数据库类似,基于非规范化(Denormalization)的数据冗余设计对于图数据库也是一把双刃剑。虽然数据冗余设计会增加存储和更新操作的开销,但它也能提高查询效率。例如,如果要查询2024年以来的所有订单号及其用户姓名。基于上一节的图数据库设计,需要执行下面的查询语句:
在该查询中,图数据库需要遍历OrderLine节点以及通过HAS_ORDER边相连的User节点,以获取订单的用户姓名。但是,如果采用数据冗余的方式,在OrderLine节点中增加一个属性Uname来存储订单对应的用户姓名,那么查询语句可以简化为:
这种设计虽然提升特定查询的执行性能,但是易引发数据冗余和一致性维护的问题。即,用户姓名同时存储于OrderLine和User节点中,一方面增加了数据的存储开销,另一方这可能导致数据的不一致性。比如,如果用户节点的姓名发生变化,若不同时更新对应OrderLine中的用户姓名,则会导致数据不一致性问题。 因此,非规范化的数据冗余设计需要根据查询工作负载精心设计。例如,不常更新但频繁访问的属性适合进行数据冗余。通过权衡这些因素,可以在提高图数据库性能的同时,最小化非规范化带来的负面影响。
练习题¶
1. 在图数据库中,以下哪种情况最适合使用数据冗余?
- 频繁更新的属性,以保证数据一致性。
- 很少被查询的属性,以节省存储空间。
- 不常更新但频繁访问的属性,以提高查询效率。
- 主键属性,以保证数据唯一性。
2. 某大学数据库中有如下ER模型:
其中Enroll是一个多对多关系,表示学生选课信息。请将上述 ER 模型映射为图数据库结构,并说明每种实体或关系在图中的表示形式(节点 / 边 / 属性),并思考将Enroll 建模为边或中间节点各自的优劣。
3. 在某电影知识图谱中,电影被建模为节点 (:Movie {Title, Year, Genre, BoxOffice, ReviewScore, Length})。若系统中“按评分区间筛选影片”和“按类型查询高票房影片”等操作非常频繁,是主要查询热点。为提高查询效率,应该如何优化当前的建模方式?
4. 对于5.03节习题中的第3题(员工建模),请思考以下问题: 1. 在图数据库中你会如何表示这种“继承结构”?员工是否应建为单一节点类型,还是多个节点类型?对应的属性应该如何存储?请提出不同的建模方案,并分析它们各自有什么优劣。 2. 如果使用多个节点类型来建模不同的子类,假设需要对员工进行大量类型聚合查询(如 HR 查询所有员工的绩效信息),如何对模式进行优化(例如:冗余存储)?