【发布时间】:2018-01-03 18:36:39
【问题描述】:
我正在使用 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 = ?
有没有希望以一种相当有效的方式(不需要大量(N,甚至?)单独的操作)为一个简单的 NoSQL 数据库,特别是 DynamoDB 建模这样的关系?像上面那样的用例 - 当没有 JOINs 的等价物时?
或者我应该直接选择 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,但显然不会不惜一切代价......
【问题讨论】:
标签: sql nosql amazon-dynamodb