面向文档的数据库(特别是RavenDB)让我非常着迷,我想玩弄一下这些数据库。 然而,作为一个非常习惯于关系映射的人,我正在思考如何在文档数据库中正确地建模数据。
假设我有一个带有以下实体的CRM C#应用程序(省略不需要的属性):
public class Company
{
public int Id { get; set; }
public IList<Contact> Contacts { get; set; }
public IList<Task> Tasks { get; set; }
}
public class Contact
{
public int Id { get; set; }
public Company Company { get; set; }
public IList<Task> Tasks { get; set; }
}
public class Task
{
public int Id { get; set; }
public Company Company { get; set; }
public Contact Contact { get; set; }
}
我在考虑把所有信息都放在一个Company
文档中,因为联系人和任务没有公司之外的用途,并且大多数情况下查询任务或联系人也会显示有关相关公司的信息。但是对于
Task
实体来说,问题就出现了。假设业务要求任务始终与某个公司关联,但还可以选择性地与某个联系人关联。在关系型模型中,这很容易实现,因为您只需拥有一个
Tasks
表格,并且将Company.Tasks
与公司的所有任务相关联,而Contact.Tasks
仅显示指定联系人的任务。为了在文档数据库中建模,我想到了以下三个想法:
- 将任务建模为单独的文档。这似乎有点反文档数据库,因为大多数情况下,查看公司或联系人时您都会想要查看任务列表,因此必须经常在文档之间执行连接操作。
- 将未与联系人关联的任务保留在
Company.Tasks
列表中,并将与联系人关联的任务放在每个个人联系人的列表中。不幸的是,这意味着如果要查看公司的所有任务(这可能会很多),则必须将公司的所有任务与每个个人联系人的所有任务相结合。当您想要取消任务与联系人的关联时,我还看到这会很复杂,因为您必须将其从联系人移动到公司。 - 将所有任务保留在
Company.Tasks
列表中,每个联系人都有一个与其相关联的任务id值列表。这似乎是一种不错的方法,但是需要手动获取id值,并且必须为每个联系人制作一个子Task
实体列表。