递归是这种情况下的最优解?

时间:2015-02-07 12:43:22

标签: mysql sql recursion

我对此感到头痛。我正在构建一个可以处理许多项目,组和文件引用的系统。 请看看这个: enter image description here

用户应该能够创建无限数量的项目,无限数量的组并附加无限数量的文件引用 - 就像普通的PC文件结构与驱动器号,文件夹和文件一样。

所有提到的元素都驻留在MySQL数据库中。但是,我不确定这个(见下文)是否是构建整个事物的最佳方式:

enter image description here

如您所见,它包含一个名为" Xrefs"的实体,其中包含项目和组。行指向内部,可能使得在检索数据时进行递归调用非常理想。

另一种方法可以是为项目创建1个实体,为组创建1个实体,为文件引用创建1个实体...以及将三个实体连接在一起的1个帮助实体,还包含"父& #34; value(类似于第一个解决方案)指的是上层元组,以便创建层次结构。

如果你要建立一个类似的项目,你会做什么?

2 个答案:

答案 0 :(得分:1)

您的结构很好 - 因为您正在构建树而不是一般图形,所以不需要将实体连接在一起的单独表格。我会把项目放到他们自己的表中,因为它们看起来是独立的,除非你必须支持项目之间的层次结构。

但是,鉴于您的RDBMS是MySQL,您在构建递归查询时会遇到问题。例如,尝试考虑一个查询,该查询将为您提供与xfer_id 1(即项目)相关的所有文件。这些文件都没有绑定到该ID,因此您需要找到第一级组,然后是第二级组,然后将文件绑定到它们。由于您的组可以嵌套在任意数量的级别中,因此您的查询也必须是递归的。

虽然你当然可以做到,it is currently not simple, and requires writing stored procedures。这种情况的常见方法是在RDBMS的帮助下在内存中构建树。诀窍是在每个组中存储顶级项目的id,即

xfer_id xfer_fk xfer_top
------- ------- --------
    1      -       1
    2      1       1
    3      1       1
    4      3       1
    5      3       1

现在,条件为WHERE xfer_top=...的查询将为您提供所有个别"部分",这些部分可以合并到内存中,而无需将整个表格放入内存。

答案 1 :(得分:1)

您遇到了MySQL最着名的限制之一:能够使用所谓的递归查询(PostgreSQL)或CTE查询(Oracle)。有一些可行的解决方法,但考虑到具有这种要求的项目,您可能会遇到很多其他众所周知的MySQL限制。在这个问题上,甚至SQLLite也会更有用(除了一个并发用户限制)。

DBIx :: Class有一些组件可以帮助您规避MySQL限制,搜索嵌套树有序树使用RECURSIVE QUERY ...... [DBIx::Class::Tree::NestedSet][1]

您需要支持:7.8. WITH Queries (Common Table Expressions),MySQL不提供给您。