【问题标题】:How to efficiently store and display nested data?如何高效存储和显示嵌套数据?
【发布时间】:2015-05-25 06:54:05
【问题描述】:

比如说,我有一个不是任意深度的嵌套结构。例如。员工和部门。

我想支持的最常见用途是显示部门及其员工的列表,并带有分页(X employees/page,而不是部门)。像这样的:

 - Department A
  - Person 1
  - Person 2
  - ...
 - Department B
 - ...

我应该如何存储它们?还有,我应该如何查询它们?

到目前为止我的解决方案:

似乎该结构可以很好地与基于文档的存储(或者可能是键值存储)一起使用。但是,我不知道如何在这种情况下进行分页。

如果我使用关系数据库,我能想到的最好的方法是获取X的员工人数,并在SQL中按部门列排序;显示时,如果当前人员与前一个人员在不同的部门,我们会为该部门打开一个新部分。

更新为an example for a flask solution

这就是我可以用平面表或连接做的; Jinja 的groupby 进行内部排序,并应用我上面所说的逻辑。

让员工成为X 员工的列表。

<ul>
{% for department in employees|groupby('department') %}
<!-- this is the department name -->
    <li>{{ group.grouper }}
        <!-- list of employees -->
        <ul>
        {% for employee in group.list %}
            <li>{{ person.department_name }} {{ person.name }}</li>
        {% endfor %}
        </ul>
    </li>
{% endfor %}
</ul>

这就是Jinjagroupby 中所做的事情:sorted(map(_GroupTuple, groupby(sorted(value, key=expr), expr)))

更新 2:

我唯一的问题是如何显示像上面这样的一级嵌套关系(请参阅部门/人员树)?存储和查询方面是我想了解的细节(并强调这些选项的问题是灵活的)。我最初询问如何将其进一步扩展到多级嵌套,这确实是不必要的混乱,因此将其删除。

Neil 评论说数据模型应该是相同的,“无论您是否正在分页”以及您是否有“一个或多个级别的部门嵌套”。很公平;如果它可以用相同的模型很好地完成,我很高兴。对于评论#4,如果我在 SQL 中排序(而不是在 python 中),我可以摆脱上面 Jinja 代码中的内部sorted,这可能有也可能没有一些好处。

对于评论 #2,虽然“使用树状 GUI 小部件进行分页”可能并不常见,但我仍然想要它;它不受欢迎的事实并没有真正改变我的问题。

【问题讨论】:

    标签: sql database database-design key-value-store nosql


    【解决方案1】:

    更新:

    你在这里同时问了几个问题,所以最好把这个问题分成几个独立的问题。

    一些cmets:

    1. 无论您是否在 UI 中进行分页,您的数据模型都应该是相同的
    2. 您不会经常看到带有树状 GUI 小部件的分页,更多的是“从展开的一个分支开始,如果展开另一个分支则请求更多数据”。或者,您可以为每个部门/子部门提供仅显示其员工和部门的超链接
    3. 您有一级还是多级部门嵌套?你似乎要求两者。您的数据模型实际上应该是相同的。
    4. 如果您想要稳定的显示顺序,请添加 display_order 列(一个好的 ORM 可以自动为您更新)

    我的答案是 SQL。

    这取决于数据是纯粹分层的,还是图形的(可以有多个父级)。

    如果分层:

    create table foo (
      foo_id int primary key,
      name text
    );
    
    create table bar (
      bar_id int primary key,
      name text,
      parent_id int null references foo(foo_id)
    );
    

    如果是图形:

    create table foo (
      foo_id int primary key,
      name text
    );
    
    create table bar (
      bar_id int primary key,
      name text
    );
    
    create table foo_bar (
      foo_id int references foo(foo_id),
      bar_id int references bar(bar_id),
    
      primary key (foo_id, bar_id),
    
      check (foo_id <> bar_id)
    );
    

    您可以使用Recursive Common Table Expressions 来查询这些结构(提示:不要使用 MySQL)。 A Recursive CTE example。还有How does a Recursive CTE run, line by line?

    在现实世界中,人们有时会被分配到多个部门(或为多个公司工作),因此这可能是一种图形关系。

    【讨论】:

    • 我更关心分层(单亲),我不太明白递归表达式在这里如何应用。你能举个例子吗?我还用 python 中 Jinja 模板的解决方案更新了原始问题,显示了我的逻辑。
    • 我已经更改了上面的措辞以使其更加清晰,并进行了新的更新。我看到您提出的模型是标准的一对多和多对多关系。您能否详细说明如何查询它们?
    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 2014-07-22
    • 2021-10-31
    • 2015-08-12
    • 2020-11-27
    • 1970-01-01
    相关资源
    最近更新 更多