MySQL有效地存储无向图边

时间:2011-09-01 23:42:56

标签: mysql graph

我想存储无向图边(例如,对于朋友)。要存储和检索节点a的所有朋友,可以使用:

每条边创建两行,每个节点查询一列:

+--------------------------+
| id | from_node | to_node |
+--------------------------+
| 1  |  a        |  b      |
| 2  |  b        |  a      |
+--------------------------+
SELECT * FROM `x` WHERE from_node = a

每条边创建一行,使用OR

+--------------------------+
| id | node_a    | node_b  |
+--------------------------+
| 1  |  a        |  b      |
+--------------------------+
SELECT * FROM `y` WHERE node_a = a OR node_b = a

哪种搜索效率更高?

  • 表格x包含2n行,from_nodeto_node上的索引,在一列上查找
  • 表格y包含n行,node_anode_b上的索引,使用OR在两列上查找

2 个答案:

答案 0 :(得分:2)

这可能过于过时而无用,但我会发布,以帮助其他人!

我存储了第二个示例中的无向图,并且有一个约束,即node_a必须小于node_b。然后,您可以在对上放置UNIQUE约束,并且知道数据是一致的。通过将node_a与{a,b}中的较小者和node_b中的较小者进行比较,查询必须进行更多的工作。 PostgreSQL(我最了解的数据库)提供了GREATEST()LEAST()函数,可以在这里提供帮助。

答案 1 :(得分:1)

如果你优化了所有内容,那么X将是最快的,假设你从磁盘读取数据并且正在查询单个人的朋友。那是因为您可以将数据排列在磁盘上,以便命令它们匹配一个索引,这是您要查询的索引。所以,对于一个人来说,你只需要做一次磁盘搜索。 Y需要对两个索引进行查询,因此可能意味着多次搜索以检索朋友,即使是单个人(并且磁盘访问时间通常主导简单查询)。

请参阅维基百科的clustered indices(和the mysql manual

如果你足够幸运地知道数据总是在内存中那么它们可能都“足够快”(即使数据在磁盘上它们也可能足够快 - 我不是说X是最好的设计,只能使它最有效率。)