0

不幸的是,代码受我的工作保护,所以我不能分享它。

我的同事制作了一段代码,旨在从关系数据库中选择数据,该数据库以关系格式保存树结构。

树结构的一个例子是这样的:

{
    "top_level_node": {
        "meta_info_1": "meta_info_keyword1",
        "meta_info_2": "meta_info_keyword2",
        "meta_info_3": "meta_info_keyword3",
        "meta_info_4": "unique string of data", 

        "main_container": {
            "container_attribute": "container_attribute_keyword",

            "sub_container_1": {
                "container_attribute": "container_attribute_keyword",

                "pattern_1": {
                    "pattern_property_1": "pattern_property_1_keyword",
                    "pattern_property_2": "pattern_property_2_keyword",
                    "pattern_property_3": "unique string of data"
                },

                "pattern_2": {
                    "pattern_property_1": "pattern_property_1_keyword",
                    "pattern_property_2": "pattern_property_2_keyword",
                    "pattern_property_3": "unique string of data"
                }
            },

            "pattern_3": {
                "pattern_property_1": "pattern_property_1_keyword",
                "pattern_property_2": "pattern_property_2_keyword",
                "pattern_property_3": "unique string of data"
            }
        }
    }
}

我的同事生成的代码首先涉及执行 50 行 CTE 递归查询,该查询以线性格式(每行 1 条数据)生成树中所需的所有数据。

然后我的同事将这些线性数据成行提取并使用递归 PHP 函数遍历它,以从数据中重建树结构。

我试图说这是错误的方法,因为:

  1. 数据已经是一种格式(关系数据库表),可用于通过递归 php 函数和简单的查询来重建树结构,以便随时选择每条数据。我认为这更容易阅读,并且只需要一个递归循环。

  2. 这不是一个时间敏感的操作,我们正在为“编译过程”重建一个数据树,该过程可能每月发生一次。我认为,因为时间在这里并不重要,递归 CTE 查询几乎没有提供任何好处。

  3. 查询非常长且难以阅读,如果有人想了解 php 代码在做什么,他们必须首先了解查询。我认为递归应该在代码中,并且查询应该简单且易于理解它们正在检索的内容。

我认为理论上这里只需要一个递归——要么在 SQL 上递归,要么在 PHP 上递归。我认为 PHP 中的递归更容易理解,而 SQL 中的递归在没有大量查询的情况下无法重建树结构。

我对么?为什么/为什么不?我错了吗?为什么/为什么不?执行递归查询以将数据从关系格式更改为线性格式,然后执行另一个递归函数将线性数据更改为树是否有意义?

4

1 回答 1

1

您的同事开发了一种技术,允许他在单个请求中检索递归结构的数据。这可能有合理的技术原因。他的查询是递归的,因为这是一种将树状数据结构展平为表的合理技术。然后,他从该数据表的另一侧构建一棵新树,这又是一个递归操作,因为这是他正在构建的一棵树。

要删除一个或两个递归,您必须回答以下问题:“我如何编写一个查询以返回不需要展平的递归结构中的所有数据?” 或者,您可以放弃扁平列表的想法,并在单个查询中检索每个分支(以及每个分支的每个分支)的数据。我怀疑他的方法要快得多。

简而言之,你既不对,也没有错。“正确”方法是最能满足您的软件的功能和非功能要求(对于“最佳”的某些定义)的方法,无论该方法可能是什么。在做出此类决定时,总是需要权衡取舍。为了获得你想要的速度,你可能不得不牺牲一些代码的可读性、简洁性和可维护性。这就是它的工作原理。

于 2018-12-10T19:22:35.737 回答