DocumentDB中每个集合的单个或多个实体

文档DB中每个集合应该有一个实体吗?

考虑我在下图中有外键关系: 在此处输入图像描述

我应该为员工创建两个集合,为公司创建其他集合。 或者我应该将它们存储在一个集合中?

我在这里读到,在documentdb中,存储过程触发器等的范围都在一个集合中。 因此,通过将不同的实体拆分为单独的集合,我开箱即用。

因此,将这两个类转储为单个实体并不是更好,如下所示:

{ "Id": 1001, "Industry": "Software", "Employees": [ { "Id": 10011, "Name": "John Doe", "CompanyId": 1001 }, { "Id": 10012, "Name": "Jane Doe", "CompanyId": 1001 } ] } 

在DocumentDB中实现相关实体的标准做法是什么?

通常,每个集合存储多个实体类型。 是否将实体类型存储到单个文档中需要更多考虑。

正如大卫所说 – 如何建模数据有点主观。

在集合中存储多个实体类型

首先……让我们谈谈在集合中存储多个实体。 DocumentDB集合不是表。 集合不强制架构; 换句话说,您可以在同一个集合中存储具有不同模式的不同类型的文档。 只需在文档中添加type属性,即可跟踪不同类型的实体。

您应该将集合视为分区和边界的单元,以执行查询和事务。 因此,在同一个集合中存储不同实体类型的巨大优势是您可以通过sprocs获得开箱即用的事务支持。

在文档中存储多个实体类型

是否在单个文档中存储多个实体类型需要更多考虑。 这通常被称为反规范化 (通过在单个文档中嵌入数据来捕获数据之间的关系)和规范化 (通过创建其他文档的弱链接来捕获数据之间的关系)您的数据。

通常, 去标准化提供了更好的读取性能。

应用程序可能需要发出较少的查询和更新以完成常见操作。

通常,在以下情况下使用非规范化数据模型:

  • 实体之间有“ 包含 ”关系
  • 实体之间有一对一的关系
  • 非规范化数据不经常变化
  • 非规范化数据不会无限制地增长
  • 去标准化数据是文档中数据的组成部分

非规范化数据模型的示例:

 { "Id": 1001, "Type": "Company", "Industry": "Software", "Employees": [ { "Id": 10011, "Type": "Employee", "Name": "John Doe" }, { "Id": 10012, "Type": "Employee", "Name": "Jane Doe" } ] } 

通常, 规范化提供更好的写入性能。

提供比去标准化更多的灵活性

客户端应用程序必须发出后续查询以解析引用。 换句话说,标准化数据模型可能需要更多往返服务器。

通常,使用标准化数据模型:

  • 当反规范化会导致数据重复但不能提供足够的读取性能优势而不是重复的影响。
  • 代表一对多的关系
  • 代表多对多的关系。
  • 相关数据经常变化

规范化数据模型的示例:

 { "Id": 1001, "Type": "Company", "Industry": "Software" } { "Id": 10011, "Type": "Employee", "Name": "John Doe", "CompanyId": 1001 } { "Id": 10012, "Type": "Employee", "Name": "Jane Doe", "CompanyId": 1001 } 

混合方法

在标准化和去标准化之间进行选择不一定是黑白选择。 我经常发现获胜的设计模式是一种混合方法,在这种方法中,您可以选择标准化对象场的部分集合并对其他字段进行去标准化。

换句话说,您可以选择对频繁读取的稳定(或不可变)属性进行反规范化,以减少后续查询的需要,同时规范化频繁写入/变异字段以减少扇出写入的需要。

混合方法的示例:

 // Author documents: [{ "id": 1, "firstName": "Thomas", "lastName": "Andersen", "countOfBooks": 3, "books": [1, 2, 3], "images": [{ "thumbnail": "http://....png" }, { "profile": "http://....png" }, { "large": "http://....png" }] }, { "id": 2, "firstName": "William", "lastName": "Wakefield", "countOfBooks": 1, "books": [1, 4, 5], "images": [{ "thumbnail": "http://....png" }] }] // Book documents: [{ "id": 1, "name": "DocumentDB 101", "authors": [{ "id": 1, "name": "Thomas Andersen", "thumbnailUrl": "http://....png" }, { "id": 2, "name": "William Wakefield", "thumbnailUrl": "http://....png" }] }, { "id": 2, "name": "DocumentDB for RDBMS Users", "authors": [{ "id": 1, "name": "Thomas Andersen", "thumbnailUrl": "http://....png" }, ] }] 

你的问题有点主观,因为你要求实体设计,为此,没有一个正确的答案。

但是:从更客观的角度来看:没有什么可以阻止您在集合中拥有多个实体类型 (例如, Company文档类型和Employee文档类型,在您的情况下)。

您需要为自己包含某种类型的提示(可能是type属性),以帮助在运行查询时区分这两种提示。 但是,通过在同一个集合中包含这两种类型,您现在可以使用集合范围。 关于type属性:由于DocumentDB默认为所有属性编制索引,因此type属性很容易集成到查询中。

编辑删除了有关每个容量单元3个集合的部分,因为当DocumentDB从预览转换为生产时,该安排被删除。