处理重复数据
当你将相关数据嵌入到单个文档中时,你可能会在两个集合之间重复数据。复制数据允许你的应用程序在单个查询中查询多个实体的相关信息,同时在模型中逻辑上分离实体。
关于此任务
关于数据复制的担忧之一是增加了存储成本。然而,优化访问模式的好处通常超过存储成本增加的潜在成本。
在复制数据之前,请考虑以下因素:
需要更新复制的数据的频率。频繁更新复制的数据可能会导致沉重的负载和性能问题。然而,处理不频繁更新的额外逻辑比在读取操作中执行连接(查找)的成本要低。
当数据被复制时,读取性能的提升。复制数据可以消除在多个集合之间执行连接的需求,这可以提高应用程序性能。
示例:电子商务模式中的数据复制
以下示例展示了如何在电子商务应用模式中复制数据以改进数据访问和性能。
步骤
填充数据库
在电子商务
数据库中创建以下集合
集合名称 | 描述 | 示例文档 | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
customers | 存储客户信息,如姓名、电子邮件和电话号码。 |
| ||||||||||||||||||||||||||
products | 存储产品信息,如价格、尺寸和材料。 |
| ||||||||||||||||||||||||||
orders | 存储订单信息,如日期和总价。在 orders 集合的文档中,lineItems 字段包含该订单对应的产品。 |
|
以下从products
集合的属性在orders
集合中重复
productId
product
price
size
数据重复的好处
当应用程序显示订单信息时,它会显示相应的订单行项目。如果订单和产品信息存储在不同的集合中,则应用程序需要执行$lookup
来连接两个集合中的数据。查找操作通常成本高昂且性能较差。
与仅将行项嵌入到orders
集合相比,重复产品信息的原因是应用程序在显示订单时只需要产品信息的一个子集。通过仅嵌入所需字段,应用程序可以在不向orders
集合添加不必要冗余的情况下存储额外的产品详细信息。
示例:产品评论的重复数据
以下示例使用了子集模式来优化在线商店的访问模式。
考虑一个应用程序,当用户查看产品时,应用程序会显示产品的信息以及最近五条评论。这些评论存储在products
集合和reviews
集合中。
当写一条新评论时,会发生以下操作
评论被插入到
reviews
集合。使用
$pop
和$push
更新products
集合中最近评论的数组。
步骤
填充数据库
在 productsAndReviews
数据库中创建以下集合
集合名称 | 描述 | 示例文档 | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
products | 存储产品信息。在 products 集合中的文档在 recentReviews 字段中嵌入最近五条产品评论。 |
| |||||||||||||||||||||
评论 | 存储所有产品的评论(不仅仅是最近评论)。在 reviews 集合中的文档包含一个 productId 字段,表示该评论针对的产品。 |
|
重复数据的益处
应用程序只需要对数据库进行一次调用,就可以返回它需要显示的所有信息。如果数据完全存储在单独的集合中,应用程序需要连接来自 products
和 reviews
集合的数据,这可能会引起性能问题。
评论很少更新,因此存储重复数据并不昂贵,且在集合之间保持数据一致性不是挑战。
了解更多
了解如何保持重复数据的一致性,请参阅数据一致性。