在图表中存储中间值

时间:2018-05-19 17:01:17

标签: graph neo4j data-modeling directed-acyclic-graphs

我试图掌握将数据沿袭表示为图形(特别是DAG)的最佳实践,并将值存储在neo4j之类的内容中。

例如,我有一个多步骤处理管道 - 一个具有各种输入值,中间值和最终输出分数的推荐引擎。我想将任何给定分数的历史表示为其先前值的组成部分,每个节点代表一个纯函数。

图形数据库本身不负责计算,仅用于表示节点表示的每个纯函数的输入。让我们假设一些节点的计算成本很高,因此保持中间值是有意义的。随着图中的任何值发生变化,子节点可能被标记为陈旧,以便某些进程异步重新计算它们。

对于那些已经看过这种架构的人来说,围绕这种方法有哪些最佳实践,图形数据库是存储这些数据依赖关系的正确位置?

2 个答案:

答案 0 :(得分:0)

当我不得不自己滚动这样的东西时,我会在我的数据库中添加一个dateUpdated列,以便在我更新时显而易见。然后,您可以沿着节点的子列表向下走,以确保孩子在其父母之后始终更新。我假设:

  • 您始终有DAG
  • 拓扑无法更改

然后你可以将图形一次性划分为不相交的段(一次),在每个段内 - 将所有根扫描成一堆,并处理每个根和root的子节点,更新dataUpdated列,就像你一样需要更新节点。

如果您想保留完整的历史记录,请在更新"时执行INSERT。 dateUpdated(复制没有改变的所有内容,设置dateUpdated = NOW。)如果您只想表示当前处理的状态,请进行更新。

执行UPDATE的一个问题是,如果您有其他进程读取此数据,您可能会遇到一个竞争条件,您可以在其中更新父级,读取未更新的子级并获取过时值。另一种方法是你实际上没有给出值,直到所有孩子的更新时间都超过他们的父母(或你的函数中的任何输入)。如果你做一个INSERT,那么子节点赢了'在它们被处理之前一直存在,但是你必须处理查询由于重建而不存在的节点的情况,而不是你查询的节点是什么&#&# 39; t存在。

如果拓扑发生变化,那么您可能需要强制执行DAG约束,然后每次都进行分区。

因此,我认为这取决于您希望保留的历史记录(完整历史记录或预先计算的值历史记录)以及图形拓扑结构随时间的变化情况。

我很擅长你添加的四个标签中的三个,但我对neo4j一无所知,很抱歉,如果那里已有数据结构了。在不同的版本中,似乎应该有一些数据库系统可以存储数据,但是我总是依赖于使用MySQL更新dateUpdated ...

答案 1 :(得分:0)

是的,图形数据库在结构上镜像DAG,是您描述的存储一个DAG的理想场所。至于最佳实践,它取决于哪个数据库。 Neo4j是一个方向属性图,您可以为节点和关系指定属性和值("顶点"和#34;边缘"在图形说话中)。

因此,对于您的管道,首先要注意的是每个节点代表一个函数,并且可以包含诸如函数标识符和版本,执行时间,服务器配置等属性。

每个关系代表从一个函数到另一个函数的消息。您可以选择,您可以选择哪种方式取决于查询。根据您的描述,我可能会在函数中保留输入和输出参数值。但您也可以将这些描述为关系的有效载荷。后者是管道的更真实的表示,但如果您需要存储最终输出,则需要一些不一致。