图:将双向边建模为两个独立边的优缺点是什么?

时间:2012-10-17 09:34:48

标签: java database graph relationship relation

我目前正在开发一个应用程序,我们基本上在“项目”之间建立一个图表。 我认为这些项目之间存在不同类型的链接,但我现在正在努力决定如何对这些项目进行建模,尤其是双向链接。

1。示例

ItemB --isChildOf---> ItemA
ItemA --isMasterOf--> ItemB

我认为可以这样建模:

示例2

ItemA <---> ItemB

在我的数据库模型中,我目前正在模拟我的链接:

* sourceID
* targetID
* relationType (e.g. isMasterOf, isChildOf, maybe more...)

我还需要在桌子上作为一个字段的方向吗?到目前为止,我没有把它作为一个单独的字段,因为IMO的方向是由sourceID和targetID隐式定义的。

我不确定在哪种情况下我需要示例1,在哪种情况下示例2就足够了。我认为示例1就像是推特,其中UserA可以跟随用户B,但可能不是反过来。另一方面,Facebook在我看来总是Example2。

希望我的问题有道理。

1 个答案:

答案 0 :(得分:3)

如果您想要一个尽可能通用的解决方案,并且可以在任何简单的图形建模案例(一对多/多对一,多对多)中工作,只需将链接建模为(source_id) ,target_id)在单独的链接表中配对。那样你就可以了

  • 通过边缘对(a.id,b.id)和(b.id,a.id)和单向链接建模双向链接,其中一个取决于方向
  • 通过查看哪个节点是源节点以及哪个节点是目标来区分边缘方向 - 不需要单独的方向字段。

如果您想针对特定情况制定一个优雅的解决方案,但是对于您想要建模的图表有实际限制,您首先需要决定

  1. 您希望在对象之间允许哪种类型的链接:它们总是单向还是双向,或者您是否需要区分它们
  2. 它是否是一个树状结构,其中一个对象只能有一个父对象但有很多子对象,或者是一个更通用的图形,其中一个对象可能有多个边缘来来往往。
  3. 关于第一点,如果你知道所有的链接都是同一类,你真的不需要在代码中区分edge(source_id,target_id)和edge(target_id,source_id),因为两者都意味着两个对象/节点之间的边缘。

    至于第二点:如果您想要建模的图形类似于树或森林(每个对象具有0或1个父项以及0到n个子项,则所有链接都是相同类型 - uni-或双向),你可以只添加像parent_id这样的东西到对象本身,而不是在单独的链接表上建模连接。

    显然,如果你需要在边缘有其他属性(例如权重或某种类型属性而不是方向),你必须相应地添加字段。在这种情况下,在任何情况下在单独的表上对边进行建模是最有意义的,因为边不仅仅是节点之间的简单链接,而是具有实际属性的对象。