【问题标题】:How do I properly design a SQL database so that I can store nodes and connections to other nodes?如何正确设计 SQL 数据库,以便可以存储节点和与其他节点的连接?
【发布时间】:2015-08-27 02:52:39
【问题描述】:

例如,假设我有一个这样的项目表:

  ID
------
  0
  1
  2
  3
  4

并且表中的每个项目都需要能够“链接”到同一个表中的 N 个其他项目。因此,例如项目 0 可能链接到项目 2 和项目 4。第一个明显的解决方案似乎是将某种数组存储为另一列,并且该数组可以包含整数以“链接”到同一个表中的其他项目。但是 SQL 并没有真正的数组功能,使用字符串会导致执行特定查询需要更长的时间,因为我必须使用 LIKE %%。

所以必须有办法使用另一个表来存储整数的动态列表。

在 SQL 中存储此类数据的正常方式是什么?

【问题讨论】:

  • 规范化的做法是使用桥接表(多对多关系)。

标签: sql arrays database-design architecture


【解决方案1】:

您似乎正在尝试通过 many-to-many relationship 链接数据库项目。

要将其映射到关系 SQL 数据库中,您将拥有一个包含节点/项目的表,您可以在其中描述它们的“名称”以及它们具有的任何其他属性:

item_id | name
----------------
0       | test
1       | abcd
2       | node_2
3       | item_3
4       | item_4

然后你会有另一个表映射元素(0->20->4)在一起,它描述了图中两个节点之间的连接,如下表connection

connection_id | item_id_1 | item_id_2
--------------------------------------
0             | 0         | 2
1             | 0         | 4

每个连接都有自己的 id 以便于编辑,并通过它们的 id 链接到项目。您可以在此表中指定任意数量的节点之间的连接。这映射了一种单向、多对多的关系。您可以使用类似的表将两个不同的实体映射在一起,只需映射 id。

例如,您可以运行查询以获取两个连接项的名称,如下所示:

SELECT
    i1.name AS 'item_1_name'
    i2.name AS 'item_2_name'
FROM
    connection AS c
    INNER JOIN items AS i1
        ON i1.item_id = c.item_id_1
    INNER JOIN items AS i2
        ON i2.item_id = c.item_id_2

这将返回以下内容:

item_1_name | item_2_name
-------------------------
test        | node_2
test        | item_4

有关设置表的更多详细信息,有这个 stackoverflow 问题:How to make SQL many-to-many same-type relationship table 尽管他关于选择它们的答案容易受到 SQL 注入的影响,所以我会非常小心他提到的 PHP 变量。

【讨论】:

  • 但项目是动态的。我的表中肯定不能有 100k 列吗?
  • 数据存储在行中,而不是列中。
  • 您只需将行添加到将节点链接在一起的连接表中。然后,您的节点可以有一个名称、日期和一堆其他列来描述它们的数据(通常是 1-20 个额外的列)。这可能有助于您理解关系表:htmlgoodies.com/primers/database/article.php/3478051
  • 我使用这个答案来设计我的解决方案并且效果很好。我的数据库中现在有超过 1000 万个唯一连接。我在优化查询时也遇到了一些问题,所以我创建了 item_1 和 item_2 的索引。我只是发布此评论,以防其他人遇到类似的优化问题。
猜你喜欢
  • 2022-01-21
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
相关资源
最近更新 更多