如何存储嵌套位置?

时间:2014-02-24 12:09:04

标签: mysql sql database-design relational-database

在我的项目中,我有产品的位置,可能如下所示:

- Location 1
-- SubLocation 1
-- SubLocation 2

- Location 2
-- SubLocation 3
-- SubLocation 4

想象一下在设施中带有子区域的区域。 我需要将其存储在DB中,然后在以后的某个时间进行检索,如下所示:SubLocation 1 at Location 1

我的第一个猜测是有两张表有一对多的关系,但这不会扩展,后来我需要有这样的东西:

- Location 2
    -- SubLocation 3
    -- SubLocation 4
    ---- SubLocation 5
    ---- SubLocation 6

所以我的问题是在关系数据库中存储这种结构的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

您可以将parent_id引用FK定义为具有id的另一条记录(根目录为null parent_id)。

要定义hierarhy并在一个查询中检索所有子树,您可以定义一个额外的字段路径(VARCHAR)。该字段应具有以“_”

分隔的完整路径ID

在您的情况下,SubLocation 5的路径=“2_4_5”

要检索SubLocation 4的所有子项,您可以使用

select *
from myTable
where path like '2_4%';

存在级别深度限制(实际上是路径的大小),但在大多数情况下它应该有效。

答案 1 :(得分:1)

在MySQL中处理分层数据很困难。因此,尽管您可能将数据存储在递归表中,但查询数据(通常)并不容易。

如果您有一组固定的层次结构,例如三个(我在想“城市”,“州”,“国家”),那么您可以为每个实体创建一个单独的表。这适用于元素随时间变化的情况。

或者,您可以使用单个表来展平尺寸。因此,“城市”,“州”和“国家”都存储在一行中。这使数据变平,因此不再标准化。更新变得乏味。但如果数据很少更新,那么这不是问题。此表单是“维度”表单,用于OLAP解决方案。

有混合方法,您可以以递归形式将每个元素存储在单个表中。但是,该表还包含顶部的“完整路径”。例如,在你的上一个例子中:

/location2/sublocation3
/location2/sublocation4
/location2/sublocation4/sublocation5
/location2/sublocation4/sublocation6

这便于查询数据。但它以维护成本为代价。更改sublocation4之类的内容需要更改多行。思考触发器。

最简单的解决方案是为不同的实体使用不同的表,如果可以的话。

答案 2 :(得分:0)

您可以将其存储在一个表格中,并使用self join检索子位置。