有关MongoDB模式设计的建议

假设你想模拟某种情况。 公司可以有一个或多个分支机构。 这些分支机构的员工可以在不同的公司工作(甚至可以在同一家公司的两个不同分支机构工作)。 这当然只是一个例子。

我们还假设大多数搜索/查询将在员工和公司集合上完成。

第一种(天真)的做法是嵌入所有东西(公司有一系列分支和分支有员工数组):

{
    name: "Company name",
    // other company data
    branches : [
        { 
            name: "Branch name",
            // other branch data
            Employees: [
                {
                    // employee1 data
                },
                {
                    // employee data
                },
            ]
        }
    ]
}

但是,如果有兴趣检索员工信息(人们必须检索公司,然后遍历每个分支以查找需要的员工),这将会非常低效。

另一方面,可以使用引用和模仿RDBMS(将有公司,分公司和员工集合),但这意味着更多的查询。

第三种选择(我最接近)是将Employee作为单独的集合,然后在分支中有一个引用数组。 此外,为了允许更快的查询,如:“某些名称的员工,某些公司和某个分公司”,公司ObjectId可以存储在Employee集合中:

{
    company_id: "some id",
    first_name: "First name",
    last_name: "Last name",
    //
}

因此,在这种情况下,要搜索某些名称适用于某些公司和某些分公司的所有员工,则必须执行两个查询。 第一个查询将返回满足“公司条件”(公司名称和分公司名称)的公司,然后对Employee集合的第二个查询将返回具有指定名称并且在第一个查询中返回了id的公司中工作的所有员工。

你会以其他方式做这个吗? 有没有其他“推荐”的方式来做到这一点? 你会添加一些改进?

更重要的是,当这两个查询返回具有小交集的结果集时,该怎么办? 在这种情况下如何提高性能?


我认为你大部分都是朝着正确的方向前进。

虽然有些情况下MongoDB中的非规范化不像关系数据库中的恶意,但事实上这是正确的事情,但在这种情况下,您应该使用多个集合。 这是因为MongoDB文件的上限为16MB。 当你有一个拥有很多员工的分公司的大公司时,员工子文件变得更加复杂,你可以很容易地破解这个限制。

从雇员到公司的参考是一个好主意。 但是,您应该考虑不使用公司的_id字段,而是使用公司名称和分支名称,只要您可以保证它们的每个组合在公司集合中都是唯一的(例如在这两个组合上具有唯一的复合索引字段)。 原因在于,当你查找一名员工时,通常也会需要公司和分支机构的名称。 当你只有_id时,你将不得不做额外的查询来获取这些信息。

你说你在分支机构和员工之间没有1:n的关系,而是一个m关系。 在这种情况下,我建议你为每个员工添加一个“分配”数组,其中包含两个字段company_name和company_branch的对象(也许你想添加第三个字段“职位”,说明他或她在做什么那里)。

您的员工文件将如下所示:

{
    first_name: "First name",
    last_name: "Last name",
    //
    assignments: [
        { company:"Aperture Science", branch:"R&D", position:"test subject" },
        { company:"Black Mesa", branch:"security", position:"leader of blue shift" }
    ]
}

请注意,您可以在这里使用无模式数据库的优势:您可以轻松拥有不仅拥有分支机构,而且拥有更多层级(如部门和团体)的公司,而其他公司则不会。

但是当我想重新命名一家公司或分公司时呢?

在这种情况下,您必须更新每个引用更名公司/分公司的员工文件。 是的,它不会是这种情况下最有效的模式。 但请记住,MongoDB模式应该始终针对最常见的用例进行优化。 你认为哪些事情会更频繁地发生:a)公司或分支机构被重新命名或b)有人想要查找员工?

链接地址: http://www.djcxy.com/p/67961.html

上一篇: Recommendations for MongoDB schema design

下一篇: How to do this with std::bind?