RavenDB建模 - 单个文档与多个文档?

时间:2012-12-13 08:58:17

标签: ravendb

给出一个简单的例子如下,我想要一些关于是将单个文档存储为多个文档的指导。

class User
{
    public string Id;
    public string UserName;
    public List<Post> Posts;
}

class Post
{
    public string Id;
    public string Content;
}

存储数据后,有时我会想要给定用户的所有帖子。有时我可能希望跨多个用户的帖子符合特定条件。

我应该将每个用户存储为文档(嵌入帖子),还是将用户和帖子存储为单独的文档更有意义,并且在我的帖子中有某种ID可以将其链接回用户?

现在,如果每个用户属于一个组织(我的应用程序中将有数百个组织)会怎样?

class Organization
{
      public string Id;
      public List<User> users;
}

我是否应该继续使用单一文档方法?在这种情况下,我会为每个组织存储一个巨大的文档,其中包含嵌入式用户,而嵌入式用户又包含嵌入式帖子?

1 个答案:

答案 0 :(得分:3)

您应该将它们保存为单独的文档。 User,Organization和Post是聚合实体的很好的例子,在Raven中,每个聚合通常都是它自己的文档。

只有非聚合的实体才应嵌套在同一文档中。例如,在帖子中,您可能有一个List<Comment>。 Comment和Post都是实体,但只有Post是聚合。

您应该使用引用对它们进行建模:

public class User
{
    public string Id { get; set; }
    public string Name { get; set; }
    public List<string> PostIds { get; set; }
}

public class Post
{
    public string Id { get; set; }
    public string Content { get; set; }
}

public class Organization
{
    public string Id { get; set; }
    public List<string> UserIds { get; set; }
}

或者,您可以在适当情况下将某些数据非规范化为您的参考文献:

public class UserRef
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Organization
{
    public string Id { get; set; }
    public List<UserRef> Users { get; set; }
}

将用户名重新规范化为组织文档的好处是,在显示组织时无需获取每个用户文档。但是,它的缺点是每次更改用户名时都必须更新组织文档。每当你考虑一段关系时,你应该权衡这个的利弊。所有案例都没有正确答案。

此外,您应该考虑如何真正使用数据。在实践中,您可能会发现您的Organization类可能根本不需要用户列表。相反,您可以在OrganizationId类上放置一个字符串User属性。这将更容易维护,如果您想要组织中的用户列表,您可以使用索引查询该信息。

您应该在Document Structure DesignHandling Document Relationships上的乌鸦文档中阅读更多内容。