使用DynamoDB进行N对N建模

锦鸿

我正在使用将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上,但显然不惜一切代价...

迈克·迪内斯库

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

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

您是否期望只有几个(少于十个?)类别?或很多(即成千上万,数万等)

每个类别的项目怎么样:您希望每个类别中都有很多类别的物品,还是少数类别中有很多物品?

然后,您需要考虑总数据集的基数以及各种类型的查询的频率。您最经常需要只检索一个类别中的项目吗?或者,您将主要是查询要逐个检索项目,而您只需要针对每个类别的项目数等进行停留即可。

最后,考虑数据集随时间的预期增长。只要您的查询能很好地分区,DynamoDB通常将在规模上胜过RDBMS。

还应考虑您希望执行的每种查询的可接受延迟,尤其是大规模查询。例如,如果您希望有数百个类别,每个类别都有成千上万的项目,那么检索类别中的所有项目意味着什么?当然,您不会立即将所有内容都显示给用户。

如果需要统计数据(例如ElasticSearch或Redis集群),我建议您也考虑将另一种类型的数据存储与DynamoDB一起使用。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章