如何有效地存储和显示嵌套数据?

时间:2015-03-22 03:34:47

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

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

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

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

我应该如何储存它们?而且,我应该如何查询它们?

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

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

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

使用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>

这是groupby sorted(map(_GroupTuple, groupby(sorted(value, key=expr), expr)))中所做的sorted:{{1}}

更新2:

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

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

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

1 个答案:

答案 0 :(得分:2)

更新:

你在这里一次提出几个问题,所以把这个问题分成几个独立的问题可能会更好。

一些意见:

  1. 无论您是否在UI中进行分页,您的数据模型都应该相同
  2. 您不经常看到与树状GUI小部件的分页,更多&#34;从扩展的一个分支开始,如果另一个分支被扩展则请求更多数据&#34;。或者,您可以为每个部门/子部门提供仅显示其员工和部门的超链接
  3. 您是否有一个级别或多个级别的部门嵌套?你似乎要求两者兼而有之。您的数据模型实际上应该是相同的。
  4. 如果您想要一个稳定的显示顺序,请添加一个display_order列(一个好的ORM可以自动为您更新)
  5. 我的答案是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查询这些结构(protip:不要使用MySQL)。 A Recursive CTE example。另外How does a Recursive CTE run, line by line?

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