database - 用于树结构数据的图形数据库或关系数据库
问题描述
我有公司按年持有具有层次结构的数据。例如,A 公司持有 B 的 50%,B 持有 C 的 50%,D 持有 C 的 50%。每个公司都有自己的属性,例如行业。
写入操作很少,主要是读取。具体来说,从一组节点(根)开始,以一定的百分比份额阈值向下追踪,提取家谱。家谱中有几个感兴趣的指标。
对于每个节点:
- 从根的深度
- 从根开始逐层共享的乘积,例如A持有0.5*0.5 = 25%的C。
对于每个级别:
- 每个根的份额分配
- 产业分布
请注意,每个节点可能有多个根,我们对所有根都感兴趣。
目前,数据存储在关系数据库中,上述任务通过连接完成。像 neo4j 这样的图形数据库会更适合数据和这项任务吗?问题的关键是要有一个合适的索引,这样就不需要每次都加入。任何建议和指针将不胜感激。
解决方案
几乎任何图形数据库都可以对您描述的信息进行建模。您如何构建查询以获得您想要的内容在每种产品中都会有所不同。
在 InfiniteGraph 中,我们可以使用以下模式对信息进行建模:
UPDATE SCHEMA {
CREATE CLASS Company {
name : String,
industry : String,
owns : LIST {
element: Reference {
edgeClass : Owns,
edgeAttribute : owns
},
CollectionTypeName : SegmentedArray
},
ownedBy : LIST {
element: Reference {
edgeClass : Owns,
edgeAttribute : ownedBy
},
CollectionTypeName : SegmentedArray
}
}
CREATE CLASS Owns
{
percentage : Real { Storage: B32 },
owns : Reference {referenced: Company, inverse: ownedBy },
ownedBy : Reference {referenced: Company, inverse: owns }
}
};
然后我们可以加载您在问题中提到的数据:
LET coA = CREATE Company { name: "A", industry: "Manufacturing" };
LET coB = CREATE Company { name: "B", industry: "Manufacturing" };
LET coC = CREATE Company { name: "C", industry: "Retail" };
LET coD = CREATE Company { name: "D", industry: "Construction" };
CREATE Owns { owns: $coB, ownedBy: $coA, percentage: 50.00 };
CREATE Owns { owns: $coC, ownedBy: $coB, percentage: 50.00 };
CREATE Owns { owns: $coC, ownedBy: $coD, percentage: 50.00 };
最后,我们可以定义一个权重计算器算子,它可以有效地将沿路径的边权重相乘。在这里,我们将每条边的权重表示为 1/百分比,然后在最后我们再次翻转总和,这给了我们您正在寻找的值。
CREATE WEIGHT CALCULATOR wcOwnership {
minimum: 0,
default: 0,
edges: {
(:Company)-[ow:Owns]->(:Company): 1/ow.percentage
}
};
“edges”部分定义了要匹配的边缘模式以及为计算该边缘的边缘权重而执行的计算。在 InfiniteGraph 中,边权重不一定是属性;它可以是一个简单的属性,也可以是基于一个或多个对象的内容进行复杂计算的结果。
在给定的数据上,我们可以使用权重计算器从目标公司 (C) 向上查询层次结构,对于发现的每个根,我们可以显示目标 (C)、所有权百分比、路径长度和根公司的名称。这个特定的查询只进行 1 到 10 度 ([*1..10]),但这个数字可以根据需要扩展。
DO> Match m = max weight 1000.0 wcOwnership
((cTarget:Company {name == 'C'})-[*1..10]->(cRoot:Company))
return cTarget.name,
1/Weight(m) as PercentageOwnership,
Length(m),
cRoot.name;
{
_Projection
{
cTarget.name:'C',
PercentageOwnership:50.0000,
Length(m):1,
cRoot.name:'B'
},
_Projection
{
cTarget.name:'C',
PercentageOwnership:50.0000,
Length(m):1,
cRoot.name:'D'
},
_Projection
{
cTarget.name:'C',
PercentageOwnership:25.0000,
Length(m):2,
cRoot.name:'A'
}
}
该模型将捕获每个相关公司的所有根节点。
#无限图
推荐阅读
- c# - 在 C# 中将选定的属性添加到列表并作为 API 调用返回
- php - 日期差未正确输出
- error-handling - Power BI - 处理不存在的参数并在表中返回有效参数的数据
- sql - 在临时表的列中显示多行
- powershell - 如何使用 powershell 重命名 blob 文件
- graphql - 查询以获取按关系中的项目数排序的数据
- events - 如何在 Flutter 上实现事件监听器或委托
- kubernetes - Kubernetes 中并发 pod 数量增加导致资源限制突破
- nginx - 设置 root 后,nginx 配置仍提供默认主页
- excel - 无法重命名excel文件