我想存储无向图边(例如,对于朋友)。要存储和检索节点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_node
和to_node
上的索引,在一列上查找y
包含n
行,node_a
和node_b
上的索引,使用OR
在两列上查找答案 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是最好的设计,只能使它最有效率。)