nosql - 支持对任何给定属性进行查询的 DynamoDB 模型

标签 nosql amazon-dynamodb key-value entity-attribute-value key-value-store

我们正在设计的应用程序具有一个功能,用户可以动态地将新元素添加到实体中,然后需要有效地搜索该实体。这些元素的数量基本上是无限的。我们的团队一直将 DynamoDB 视为一种数据存储选项,并且一直在研究键/值模型以及如何在索引下获取动态数据以进行高效查询。

我认为我有一个单表解决方案,可以优雅地处理问题,并且还允许查询数据存储中的任何给定属性,但我很不安,因为我找不到以下示例它在其他任何地方。希望它在某些方面没有根本性的缺陷 - 我将不胜感激任何批评!

该模型本质上是 Entity-Attribute-Value用于向 RDBM 添加动态或稀疏数据的方法。因此,不要像这样在 DynamoDB 表中存储不同的实体/对象:

PK       SK   SK-1   SK-2   SK-3   SK-N...      PK       SK   SK-1   SK-N...
              Key    Key    Key    Key     -->                Name   Money
Entity   Id   Value  Value  Value  Value        Person   22   Fred   30000

...这让我可以查询诸如“name = Fred的所有人”之类的内容,但是您最终会用完排序键索引,并且您需要在查询之前知道哪个索引与哪个键对应,数据可以以 EAV 格式存储,如下所示:

PK      SK & GSI-PK  GSI-SK     PK      SK & GSI-PK  GSI-SK
Id      Entity#Key   Value      22      Person#Name  Fred
Id      Entity#Key   Value  --> 22      Person#Money 30000
Id      Entity#Key   Value      22      Person#Sex   M
Id      Entity#Key   Value      22      Person#DOB   09/00

现在,通过一个全局二级索引(Entity.Key 上的 GSI-1 PK 和 Value 上的 GSI-1 SK),我可以对任何键的任何值进行范围搜索,并获取匹配的 Id 列表。用户可以添加他们的属性甚至全新的实体,并以立即索引的方式保留它们,而无需我们修改 DynamoDB 架构。

我能想到的这种方法的一个主要缺点是,从 Entity#Key-Value 查询返回的数据仅包含该键和实体 Id 的值,而不是整个实体。这对于图表和图形来说很好,但如果您想通过一个查询获得网格类型的结果,那就是一个问题。我还担心索引上的热分区键,但希望我们可以通过智能写入分片来解决这个问题。

差不多就这些了。通过一些调整,可以扩展模型以支持记录每个键上的所有更改,并允许针对这些更改进行一些不错的时间序列查询,但我的问题是是否有人发现对 KV 存储采用 EAV 类型方法很有用例如 DynamoDB,或者是否有其他方法来处理动态架构查询?

最佳答案

您可以将 pk 作为实体的 id。然后是排序键 {attributeName}。您可能仍然希望拥有带有诸如createdAt等字段的基本实体。

所以你可能有:

PK              SORT               Attributes:  
#Entity#22    #Entity#Details    createdAt=2020     
#Entity#22    #Attribute#name                     key=name    value=Fred   
#Entity#22    #Attribute#money                    key=money   value=30000

要获取实体的所有属性,您只需执行不带 pk={id} 过滤器的查询。您无法按每个给定属性动态排序,这正是 DynamoDB 不擅长的,我重复一遍!这种情况正是 NOSQL 表现不佳的地方。

你可以做的是使用流式传输来进行聚合。例如,您可以存储前 10 位最富有的人:

PK              SORT               Attributes:      
#Money#Highest    #1               id=#Entity#22    value=30000
#Money#Highest    #2               id=#Entity#52    value=30000

您将在 DynamoDB Streams 中进行计算。但是您无法动态索引值,DynamoDB 的工作原理是有效地将数据从一种表单复制到另一种表单,以便可以有效地检索数据。因此,您将复制您想要搜索的每个新属性的整个数据库,否则您将不得不使用扫描,而这样做没有任何意义,因为如果您所做的一切都不会从使用 DynamoDB 中获得任何好处一直在进行扫描。

您需要很好地理解您的流程才能充分利用 DynamoDb,如果您想随意索引数据并执行各种不同的查询,您可能需要 SQL 数据库或 elasticsearch。

关于nosql - 支持对任何给定属性进行查询的 DynamoDB 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61836423/

相关文章:

javascript - 无法获取文档

amazon-web-services - 如何从 AWS DynamoDB 获得低于 10 毫秒的响应时间?

angular - 使用 *ngFor 和 [(ngModel)] 通过 Map 更改对象数组

mysql - 相关键/值表索引/搜索

node.js - 用于 node.js(MongoDB?)的分布式数据库的事件记录

sql - 用于数据分析的 NoSQL 或 RDBMS

amazon-web-services - 为什么通过 cdk 向 dynamodb 表添加二级索引需要重新创建该表?

amazon-web-services - 如何在 AppSync/Amplify 中过滤非标量类型

javascript - 从以键/值结构格式化的数组中检索值

c++ - 如何在 mongocxx (c++) 中抑制字段?