2

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

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 就像 twitter,其中 UserA 可以关注 userB,但反过来可能不行。另一方面,我认为 Facebook 始终是 Example2。

希望我的问题有意义。

4

1 回答 1

3

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

  • 通过具有边对 (a.id, b.id) 和 (b.id, a.id) 对双向链接进行建模,通过根据方向具有其中之一对单向链接进行建模
  • 通过查看哪个节点是源节点和哪个节点是目标来区分边缘方向 - 无需单独的方向字段。

如果您想为要建模的图形类型存在实际限制的特定情况制定一个优雅的解决方案,您首先需要决定

  1. 您希望在对象之间允许什么样的链接:它们是否始终是单向或双向的,或者您是否需要区分两者和
  2. 无论是一个对象可以只有一个父对象但有多个子对象的树状结构,还是一个对象可能有多个边来来去去的更通用的图。

关于第一点,如果您知道所有链接都属于同一类型,那么您实际上不需要在代码中区分边缘 (source_id, target_id) 和边缘 (target_id, source_id),因为两者都意味着两者之间的边缘两个对象/节点。

就第二点而言:如果您要建模的图形类似于树或森林(每个对象都有 0 或 1 个父对象和 0 到 n 个子对象,所有链接都是相同类型的 - 单向或双向),您可以将诸如 parent_id 之类的内容添加到对象本身,而不是在单独的链接表上对连接进行建模。

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

于 2012-10-17T11:23:42.593 回答