如何存储 sql 个表的图表
How to store a graph of sql tables
假设我们有很多 table(T1、T2...T50),我们希望它们之间有 n 对 n 的关系。
什么是正确的实施方式。
如果 table 的数量增加到 100 或更多,则每对 Tx 和 Ty 的关系 table 将不切实际。
我目前的解决方案是
relationships_table
id_x, table_name_x, id_y, table_name_y
用于存储所有关系。这种方式添加新的 tables 是微不足道的,但缺点是什么?
1) 如果我们仅限于 sql,支持这种用例的更好方法是什么?
2) 如果我们不限于 sql 如何有效地解决这个问题?
仅添加必要的关系表。 tblA 与 tblB 相关,tblB 与 tblC 相关。所以, 通常 这意味着你可以通过
从 A 到 C
FROM tblA
JOIN tblB ON ...
JOIN tblC ON ...
这样不行吗?不需要超过 50 张额外的桌子?变得更干净?
您提出的方案是对所述问题最合理的方案。不过这个问题好像有点不合理。
如果你需要一个图,那么你只需要两个表,一个用于节点,另一个用于边。
如果某些节点属于特定类型,那么您可以为它们提供额外的专业化表。
我 运行 遇到了同样的问题,但我的方法略有不同。我添加了一个名为 relationable 的 table,只存储一个 id,图中出现的所有 table 都引用了这个 table。我自己确保只有一个元素引用整个数据库中的相关条目(这实际上是最让我烦恼的,但实际上这不是一个看起来不好看的问题)。然后是关系 table 为 n 到 n 之间的关系 relationable.
为了说明我的观点,我添加了一个我在 MySQL.
中制作的示例
CREATE TABLE relationable
(
relationable_id INT AUTO_INCREMENT PRIMARY KEY
) ENGINE=INNODB;
在关系table中我添加了一个名字,因为我的顶点有一个名字,两个节点之间甚至可能有多个不同名字的顶点。
CREATE TABLE relation
(
from_id INT NOT NULL,
to_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
FOREIGN KEY (from_id) REFERENCES relationable(relationable_id) ON DELETE CASCADE,
FOREIGN KEY (to_id) REFERENCES relationable(relationable_id) ON DELETE CASCADE
)ENGINE=INNODB;
最终出现在图表中的 table 如下所示
CREATE TABLE place
(
place_id INT NOT NULL,
name VARCAHR(255),
FOREIGN KEY (PLACE_ID) REFERENCES relationable(relationable_id)
ON DELETE CASCADE
) ENGINE=INNODB;
显然这有利有弊,
缺点
- 您需要自己确保关联对象仅被引用一次。在一个 table 中,这是由 PRIMARY KEY 处理的,但在所有 table 中,这还没有完成。
- 您可能需要一个巨大的 int 作为 relationable 的 id。
- table 关系可能会变得相当大。
优点
- 要删除一个条目及其所有关系,删除相关条目就足够了,相关的所有条目和相应的 table 将被删除。
- 加入两个 table 时,不需要相关 table.
假设我们有很多 table(T1、T2...T50),我们希望它们之间有 n 对 n 的关系。
什么是正确的实施方式。 如果 table 的数量增加到 100 或更多,则每对 Tx 和 Ty 的关系 table 将不切实际。
我目前的解决方案是
relationships_table
id_x, table_name_x, id_y, table_name_y
用于存储所有关系。这种方式添加新的 tables 是微不足道的,但缺点是什么?
1) 如果我们仅限于 sql,支持这种用例的更好方法是什么?
2) 如果我们不限于 sql 如何有效地解决这个问题?
仅添加必要的关系表。 tblA 与 tblB 相关,tblB 与 tblC 相关。所以, 通常 这意味着你可以通过
从 A 到 CFROM tblA
JOIN tblB ON ...
JOIN tblC ON ...
这样不行吗?不需要超过 50 张额外的桌子?变得更干净?
您提出的方案是对所述问题最合理的方案。不过这个问题好像有点不合理。
如果你需要一个图,那么你只需要两个表,一个用于节点,另一个用于边。
如果某些节点属于特定类型,那么您可以为它们提供额外的专业化表。
我 运行 遇到了同样的问题,但我的方法略有不同。我添加了一个名为 relationable 的 table,只存储一个 id,图中出现的所有 table 都引用了这个 table。我自己确保只有一个元素引用整个数据库中的相关条目(这实际上是最让我烦恼的,但实际上这不是一个看起来不好看的问题)。然后是关系 table 为 n 到 n 之间的关系 relationable.
为了说明我的观点,我添加了一个我在 MySQL.
中制作的示例CREATE TABLE relationable
(
relationable_id INT AUTO_INCREMENT PRIMARY KEY
) ENGINE=INNODB;
在关系table中我添加了一个名字,因为我的顶点有一个名字,两个节点之间甚至可能有多个不同名字的顶点。
CREATE TABLE relation
(
from_id INT NOT NULL,
to_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
FOREIGN KEY (from_id) REFERENCES relationable(relationable_id) ON DELETE CASCADE,
FOREIGN KEY (to_id) REFERENCES relationable(relationable_id) ON DELETE CASCADE
)ENGINE=INNODB;
最终出现在图表中的 table 如下所示
CREATE TABLE place
(
place_id INT NOT NULL,
name VARCAHR(255),
FOREIGN KEY (PLACE_ID) REFERENCES relationable(relationable_id)
ON DELETE CASCADE
) ENGINE=INNODB;
显然这有利有弊,
缺点
- 您需要自己确保关联对象仅被引用一次。在一个 table 中,这是由 PRIMARY KEY 处理的,但在所有 table 中,这还没有完成。
- 您可能需要一个巨大的 int 作为 relationable 的 id。
- table 关系可能会变得相当大。
优点
- 要删除一个条目及其所有关系,删除相关条目就足够了,相关的所有条目和相应的 table 将被删除。
- 加入两个 table 时,不需要相关 table.