【问题标题】:MySQL hierarchical storage: searching through all parent/grandparent/etc. nodes given a child node id?MySQL分层存储:搜索所有父/祖父/等。给定子节点ID的节点?
【发布时间】:2011-08-10 14:24:31
【问题描述】:

我使用这样的分层模型存储类别:

CATEGORIES
id | parent_id | name
---------------------
1  | 0         | Cars
2  | 0         | Planes
3  | 1         | Hatchbacks
4  | 1         | Convertibles
5  | 2         | Jets
6  | 3         | Peugeot
7  | 3         | BMW
8  | 6         | 206
9  | 6         | 306

然后我使用这些类别 ID 之一存储实际数据,如下所示:

CARS
vehicle_id | category_id | name
-------------------------------
1          | 8           | Really fast silver Peugeot 206 
2          | 9           | Really fast silver Peugeot 306 
3          | 5           | Really fast Boeing 747
4          | 3           | Another Peugeot but only in Hatchbacks category

在搜索任何此类数据时,我想查找所有子/孙/曾孙等节点。因此,如果有人想查看所有“汽车”,他们会看到 parent_id 为“Hatchbacks”的所有内容,以及 parent_id 为“Peugeot”的所有内容,依此类推,直至任意级别。

因此,如果我列出了 category_id 为 1、3、6 或 8 的“非常快的 Peugeot 206”,我的查询应该能够“遍历”树并找到任何更高的类别,即父母/祖父母该子类别的。例如。在类别“8”中搜索 Peugeots 的用户应该会找到以类别 6、3 或 1 列出的任何 Peugeots - 所有类别 8 的后代。

例如使用上述数据,在类别 3 中搜索“Peugeot”实际上应该会找到车辆 1、2 和 4,因为车辆 1 和 2 有一个类别祖先轨迹,可以追溯到类别 3。看到了吗?

对不起,如果我没有很好地解释这一点。它很难!不过还是谢谢你。

注意:我已阅读the MySQL dev article on hierarchies。

【问题讨论】:

  • 这对于 MySQL 来说会变得混乱和笨拙,因为它不支持分层查询
  • @a_horse_with_no_name: this article 似乎使用与我使用的相同的存储方法,并且看起来工作正常。还是我错过了什么?
  • 那篇文章的主旨不是使用“分层”模型,而是使用嵌套集模型(不需要DBMS支持分层查询)
  • MySQL 可以支持邻接表模型,看我的回答。

标签: php mysql hierarchy hierarchical-data


【解决方案1】:
【解决方案2】:

规范化模型很棒,但当您实际需要查询它们时就不行了。

只需将“路径”存储到类别表中即可。像这样:path = /1/3/4 当查询你的数据库时像“select .... where path like '/1/3/%'” 这将比多个分层查询更简单和快速......

【讨论】:

    【解决方案3】:

    我喜欢 SitePoint 提供的解释。它为您提供代码并解释其背后的理论。

    http://blogs.sitepoint.com/hierarchical-data-database/

    注意:这种方法更适合读取而不是写入。如果你经常写树,我会使用不同的算法。此方法针对读取(查找)进行了优化。

    【讨论】:

      【解决方案4】:

      您已将数据表示为邻接列表模型,其 querying in MySQL is best done using session variables。现在,这不是you can represent a hierarchy in a relational database 的唯一方法。对于您的特定问题,我可能会改用materialized path 方法,在这种方法中您取消了实际的类别表,而是在您的汽车表上有一列看起来像Cars/Hatchbacks/Peugeot 在每条记录的基础上并使用LIKE查询。不幸的是,随着记录数量的增长,这将是缓慢的。现在,如果您知道层次结构的最大深度(例如四个级别),您可以将其分解为单独的列,这样您就可以利用索引。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-28
        • 1970-01-01
        相关资源
        最近更新 更多