使用DynamoDB建模N到N.

问题描述 投票:3回答:1

我正在使用DynamoDB进行大多数持久性数据的项目。我现在正在尝试建模一个更类似于传统SQL数据库模型的数据结构,但是我想探索一种针对这种数据的良好NoSQL设计的可能性。例如,考虑一个简单的N对N关系,例如按类别分组的项目。在SQL中,这可以使用连接表建模,例如

items
-----
item_id (PK)
name

categories
----------
category_id (PK)
name

item_categories
---------------
item_id     (PK)
category_id (PK)

要列出类别中的所有项目,可以执行连接,例如

SELECT items.name from items 
  JOIN item_categories ON items.item_id = item_categories.item_id
  WHERE item_categories.category_id = ?

要列出项目所属的所有类别,可以进行相应的查询:

SELECT categories.name from categories 
  JOIN item_categories ON categories.category_id = item_categories.category_id 
  WHERE item_categories.item_id = ?

有没有希望用这样的关系建模一般的NoSQL数据库,特别是DynamoDB,以一种相当有效的方式(不需要很多(N,甚至?)单独的操作)用于简单的用例,例如以上 - 当没有相当于JOINs?

或者我应该选择RDS吗?

我考虑过的事情:

  1. 内联类别作为项目中的数组。这样可以轻松找到项目的类别,但无法解决获取类别中的所有项目的问题。我需要在每个项目中复制所需的属性,例如类别名称等。类别更新会很尴尬。
  2. 复制每个类别的每个项目,并使用category_id作为范围键,并添加反向的GSI(category_id作为哈希,item_id作为范围)。对NoSQL进行去标准化是常见的,但我仍然有疑问。可能将项目拆分为itemsitem_details,并且仅复制列表等所需的最常见属性。
  3. 转到将项目映射到类别的连接表,反之亦然。使用[item_id, category_id]作为密钥,使用[category_id, item_id]作为GSI,以支持两种查询。在这里复制最常见的属性(名称等)。为了获得一个类别的所有完整项目,我仍然需要执行一个query,然后执行N get操作,这会消耗很多CU:s。更新项目或类别名称需要多重update操作,但不是太困难。

我遇到的困境是数据格式本身完全适合文档数据库,而我需要的关系适合SQL数据库。如果可能的话,我想继续使用DynamoDB,但显然不是不惜任何代价......

sql nosql amazon-dynamodb
1个回答
1
投票

你已经在寻找正确的方向!

为了做出明智的决定,您还需要考虑数据的基数:

你会期望只有几个(少于十个?)类别吗?或者相当多(即数百,数千,数万等)

每个类别的项目如何:您是否希望拥有许多卡车,每个项目中的一些项目或几个类别中的大量项目?

然后,您需要考虑总数据集的基数和各种类型查询的频率。您最常需要检索单个类别中的项目吗?或者您将主要查询单独检索项目,您只需要每个类别的项目数量的宿舍。

最后,考虑数据集随时间的预期增长。只要您的查询分区良好,DynamoDB通常会大规模地超越RDBMS。

还要考虑您希望执行的每种查询的可接受延迟,尤其是在规模上。例如,如果您期望拥有数百个类别,每个类别包含数十万个项目,那么检索某个类别中的所有项目意味着什么?当然,您不会立即将它们全部显示给用户。

如果您需要数据统计信息(例如ElasticSearch或Redis群集),我建议您还考虑使用另一种类型的数据存储来配合DynamoDB。

最后,如果聚合查询或联接对于您的用例至关重要,或者如果通常可以在单个RDBMS实例上轻松处理大规模数据集,请不要尝试在圆孔中放置方形挂钩。像Aurora这样的托管RDBMS解决方案可能更适合。

© www.soinside.com 2019 - 2024. All rights reserved.