在我的项目中,我有产品的位置,可能如下所示:
- 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
所以我的问题是在关系数据库中存储这种结构的最佳方法是什么?
答案 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
检索子位置。