MySQL - 处理这种分层数据的最佳方法?

Ker*_*nes 5 mysql table-structure

这是对以下内容的跟进:
MySQL - 是否可以获取层次结构中的所有子项?

我有一个任意深度的邻接列表模型表(我可以将它转换为嵌套集模型.

我阅读了有关如何使用嵌套集模型的MySQL数据,尽管它似乎变得越来越复杂并且非常复杂,无法执行插入,更新和删除等基本功能.

另一篇博客展示了如何使用具有邻接列表模型的触发器系统来保持将每个对象与其祖先相关联的祖先表.


现在我需要能够返回给定节点的所有子节点的列表,以更改或删除它们.这种层次结构一旦创建就不会一直在变化,但会有大量的层次结构.

我看到的三种方法是:

  1. 创建了一个存储过程,它将执行一个返回所有子节点的递归查询.

  2. 转换为嵌套集模型,这需要进入复杂性并可能创建一个存储过程来添加,编辑和删除.

  3. 在插入/删除触发器上创建上述Ancestor Table以处理所有数据.

如果还有其他方法我没有探索,请告诉我,我会更新此列表.

Mar*_*ers 4

Quassnoi对嵌套集模型和邻接表模型运行了一些性能测试,并在他的博客文章“邻接表与嵌套集:MySQL”中记录了结果和建议。执行摘要是:

  • 嵌套集可以更快地获取所有子节点或所有父节点。
  • 如果您经常需要更新表,则嵌套集不是一个好主意。

这是他文章的结论:

在 MySQL 中,如果层次结构的更新不频繁,并且在更新期间锁定表(在长表上可能需要几分钟)是可以承受的,则应首选嵌套集模型。

这意味着使用 MyISAM 存储引擎创建表,创建如上所述的 GEOMETRY 类型的边界框,使用 SPATIAL 索引对其进行索引,并将级别保留在表中。

如果表的更新频繁,或者更新所带来的长时间锁定表的负担无法承受,那么应该使用邻接表模型来存储分层数据。

这需要创建一个函数来查询表。

本文的其余部分将展示如何定义表、实现查询并提供性能测量。使用空间索引是一个聪明的想法,可以提高您可能不熟悉的嵌套集模型的性能。


如果您也在考虑不使用 MySQL 的方法,那么您可能需要考虑PostgreSQL,它是另一个免费的开源数据库。PostgreSQL 支持递归公用表表达式形式的递归查询,这使得查询层次结构数据比 MySQL 更容易,并且性能也更好。Quassnoi 还写了一篇文章“邻接表与嵌套集:PostgreSQL”,其中显示了详细信息。

当我们谈论其他方法时,Oracle 的数据库也值得一提。Oracle 还有一个自定义扩展CONNECT BY,使查询层次结构数据变得非常容易和快速。Quassnoi 的文章邻接表与嵌套集:Oracle再次介绍了性能细节。在这种情况下,获取所有子项所需的查询非常简单:

SELECT *
FROM yourtable
START WITH id = 42
CONNECT BY parent = PRIOR id
Run Code Online (Sandbox Code Playgroud)