我正在使用将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
甚至?)单独的操作)来为像这样的简单用例建模这种关系,是否有希望?以上-没有JOIN
s的等效项?
还是应该代替RDS?
我考虑过的事情:
内联类别作为项目内的数组。这使查找项目的类别变得容易,但是并不能解决将所有项目归入一个类别的问题。而且我需要在每个项目中复制所需的属性,例如类别名称等。类别更新将很尴尬。
复制每个类别的每个项目,并将其category_id
用作范围键,然后添加带有反向符号的GSI(category_id
作为哈希值,item_id
作为范围)。去规范化对于NoSQL很普遍,但是我仍然有疑问。可能将项目拆分为items
,item_details
并且仅复制清单等中所需的最常见属性。
寻找将项目映射到类别的连接表,反之亦然。使用[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] 删除。
我来说两句