Database design DynamoDB设计模式

Database design DynamoDB设计模式,database-design,nosql,amazon-dynamodb,Database Design,Nosql,Amazon Dynamodb,我目前正在尝试设计一种数据库模式来存储需要按需扩展能力的数据。我正在寻找DynamoDB来完成这项任务。我不熟悉无sql设计模式,在进行设计时遇到了一些问题。我的数据集将被连接到一个摄像头系统上,该系统可以跟踪人们进出房间的情况 我目前的设计计划是有一个表,该表将特定相机的设备id作为主键。每5分钟,摄像机将发送进入房间的总数、离开房间的总数、组id(用于跟踪有多个入口/出口的整个房间)和时间戳 我的问题是,对于给定的主键,DynamoDB似乎只需要一个条目。每当我要添加新内容时,它都要覆盖我的

我目前正在尝试设计一种数据库模式来存储需要按需扩展能力的数据。我正在寻找DynamoDB来完成这项任务。我不熟悉无sql设计模式,在进行设计时遇到了一些问题。我的数据集将被连接到一个摄像头系统上,该系统可以跟踪人们进出房间的情况

我目前的设计计划是有一个表,该表将特定相机的设备id作为主键。每5分钟,摄像机将发送进入房间的总数、离开房间的总数、组id(用于跟踪有多个入口/出口的整个房间)和时间戳

我的问题是,对于给定的主键,DynamoDB似乎只需要一个条目。每当我要添加新内容时,它都要覆盖我的数据

我在想,这样的设计可能会奏效:

DeviceID: ID
{
    GroupID: ID,
    Entries: [
        {
            In: numIN, 
            Out: numOUT, 
            TimeStamp: time
        },
        // appending on each entry to the list
    ]
}

我是否在低效地使用DynamoDB?有没有更好的办法?似乎很难提出诸如“第y天x房间有多少人?”之类的问题

效率低吗?

不,你没有低效地使用它。DynamoDB擅长为每个请求的单个元素存储和检索分层数据组。AWS绝对推荐嵌套/非规范化数据,使单个设备具有条目数组,因为在我看来,您不能正确地进行连接(条目表和设备表)。一个缺点是您必须提取单个设备的每个条目并附加,但如果您每5分钟进行一次更新,这似乎是可以接受的。在一个用户流量较低的小应用程序上,我会做同样的事情,将用户信息添加到用户列表中,然后将用户放回去。DynamoDB每个请求都非常便宜,所以如果你没有数百万个请求,我认为这是值得的

如何运行更复杂的查询?

使用DynamoDB,您将失去查询灵活性,因为在某些情况下,它是100%管理的,并且每个请求的成本较低……对于更复杂的查询,您可以添加,以便运行涉及该表主键以外的列的查询。他们也有自己的缺点;每个索引仍然只能获得2个属性,本质上是一个包含2列的where子句,并且每个GS索引都有自己的配置吞吐量,因此您需要为新索引支付额外的固定费率。对我来说,当您要查询的数据被非规范化时,全局二级索引并没有真正起到帮助作用,就像您嵌套条目的方式一样。在您的情况下,您将无法将In、out、timestamp字段应用于全局二级索引,因为“Entries”列是文档类型。但是,您可以将整个设备JSON对象转储到其他NoSQL数据库中,它们甚至可以索引嵌套字段

另一个用于复杂查询的数据库


我自己也不想使用另一个数据库,因为我认为我可以不使用DynamoDB作为我的主要或唯一的数据存储,但是如果你需要问“给我x,其中A=1,B=2,C=3”,这真的是不可能的。我发现,在对数据进行非规范化处理的同时,使其便于查询是很困难的。因此,我使用DynamoDB存储项目并检索项目,而使用AWS Elasticsearch服务跨这些项目运行查询。因此,在您的情况下,我将在DynamoDB和elasticsearch中存储设备及其嵌套条目。当我需要检索单个设备或条目或通过Id提取任何内容时,它将来自DynamoDB。当我想在任何属性上运行分析时,我使用elasticsearch

似乎对这些数据建模的最佳方式是1对多模型。在此过程中,我将DeviceID作为分区键,时间戳作为排序键。还可以添加其余属性。拥有一个排序键还允许多个条目具有相同的分区键,因为在后台排序的哈希是分区键和排序键的组合。该模型使得根据请求的时间间隔对数据进行排序变得更加简单

谢谢你的详细回复。它让我对如何使用DynamoDB有了更多的了解。你是说我把数据拉下来,附加到新数据上,然后把它放回数据库?有没有一种方法可以只附加新数据,而不需要我下拉以前存储的数据?@AlexDeCamillo,没错。我不知道有什么方法可以在不执行GET之后加PUT或POST的情况下进行追加。我认为这可能是DynamoDB公开的restapi的局限性。如果你能找到解决方法,请告诉我,但我没有。我有一些关于数据标准化的问题。将时间戳设为属性,然后输入/输出数据位于该属性内部,这可能是更好的解决方案吗?我会有大量的属性,但我基本上可以在那一点上附加属性,而无需先拉。这可能会使搜索更快?另外,在您发布的关于规范化的链接中,他们给出了一个示例,其中有多个条目具有相同的分区键。我认为这在DynamoDB中是不可能的?你的意思是把输入/输出作为时间戳的属性吗?如果是这样,那将阻止您索引时间戳,因为您只能索引非文档/对象类型。我可能误解了你的问题。是的,属性的名称是时间戳,属性的数据可能是包含输入/输出数据的数字集。我能根据时间戳搜索特定的数字集吗?就像每次运行一个循环查询并获取存储在该时间戳中的所有数字集一样,这确实是一个更简单的解决方案。