MongoDB架构设计的建议

kev*_*vin 7 mongodb nosql

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

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

第一个(天真的)方法是嵌入所有东西(公司有一系列的分支机构和分支机构都有员工阵列):

{
    name: "Company name",
    // other company data
    branches : [
        { 
            name: "Branch name",
            // other branch data
            Employees: [
                {
                    // employee1 data
                },
                {
                    // employee data
                },
            ]
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

但是当人们有兴趣检索员工信息时,这将是非常低效的(人们必须检索公司,然后遍历每个分支以找到所需的员工).

另一方面,可以使用引用并模仿RDBMS(会有Company,Branch和Employee集合),但这意味着更多的查询.

第三个选项(我最接近),将Employee作为一个单独的集合,然后在Branches中有一个对它的引用数组.此外,为了允许更快的查询,例如:"具有特定名称的员工,适用于某个公司和某个分支",公司ObjectId可以存储在Employee集合中:

{
    company_id: "some id",
    first_name: "First name",
    last_name: "Last name",
    //
}
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,要搜索具有某些公司和特定分支的某些名称的所有员工,就必须进行两次查询.第一个查询将返回满足"公司条件"(公司名称和分支名称)的公司,然后对Employee集合的第二个查询将返回所有具有指定名称且在第一个查询中返回其ID的公司中工作的员工.

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

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

Phi*_*ipp 5

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

虽然在某些情况下,MongoDB 中的非规范化并不像关系数据库中那样邪恶,而且实际上是正确的做法,但在这种情况下,您应该使用多个集合。这是因为 MongoDB 文档的上限为 16MB。当你有一家非常大的公司,有很多分支机构,有很多员工,并且员工子文档变得更加复杂时,你可以很容易地突破这个限制。

获得员工对公司的推荐是个好主意。但是您应该考虑不使用公司的 _id 字段,而是使用公司名称和分支机构名称,只要您可以保证它们的每个组合在公司集合中都是唯一的(就像对这两个字段使用唯一的复合索引一样)字段)。原因是,当您查找员工时,您通常还会想要公司和分支机构的名称。当您只有 _id 时,您必须执行额外的查询才能获取该信息。

你说分支机构和员工之间不是1:n的关系,而是m: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" }
    ]
}
Run Code Online (Sandbox Code Playgroud)

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

但是当我想重命名公司或分支机构时该怎么办?

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