AWS Dynamo智能家居架构(位置/房间)

时间:2019-01-03 15:52:48

标签: amazon-web-services database-design aws-lambda amazon-dynamodb serverless

我正在尝试使用iot core,lambda和dynamodb以及无服务器框架和后续的Android / iOS应用程序在AWS上构建可扩展的智能家居基础架构。

我正在dynamodb中实现位置和房间。用户可以有多个位置,并且位置可以有多个房间。我习惯于使用Firebase Firestore,因此使用分区键和排序键(哈希和范围?)以及查询的组合会有些混乱。我实现了自己的哈希,以用作主要(分区?哈希?)ID。这是我正在考虑的结构:

位置

  • id
  • 名称
  • 用户名

我还在username上添加了二级索引,以便用户可以查询其所有位置。

房间

  • id
  • 名称
  • locationId

我还在locationId上添加了二级索引,以便用户可以查询给定位置的所有房间

这是我创建ID的代码:

// need a unique hash for the id
let hash = event.name + event.username + new Date().getTime();

let id = crypto.createHash('md5').update(hash).digest('hex');
let location = {
    id: id,
    name: event.name,
    username: event.username
};

对于房间:

// need a unique hash for the id
let hash = event.name + event.locationId + new Date().getTime();

由于我是Dynamo / AWS的新手,所以我想知道这是否是可以接受的解决方案。显然,我将通过roomId关联在房间下添加多个设备来对此进行扩展。我还希望能够共享设备,因此我不确定该如何工作,因为与用户的关联位于位置上-因此,我认为我必须共享位置,房间和设备(s)(我认为这是Google Home的工作方式)

任何建议将不胜感激!

编辑 我能想到的查询是:

  • 通过ID获取位置
  • 按用户获取所有位置
  • 按ID获取房间
  • 按位置获取所有房间

但是随着应用程序将来的扩展,我希望这些查询具有灵活性(共享位置,获取共享位置等)

1 个答案:

答案 0 :(得分:2)

  

我希望这些查询具有灵活性

然后一般而言,noSQL和Dynamo可能不是正确的选择。

@varnit暗示,noSQL DB在存储内容方面非常灵活,但是在查询数据方面却非常灵活。

例如,

Dynamo仅在使用排序键(SK)或进行全表扫描(不推荐)时才可以返回列表(查询)。否则,它只能返回一条记录。

我不知道“共享位置”会带来什么。

但是在Dynamo中有多个原则(每个用户仅查看其数据),简单的解决方案是将userID用作分区键(PK)。

我将使用location#room的复合排序键

  • 通过ID获取位置-> GetItem(PK =用户,SK =位置)
  • 按用户获取所有位置->查询(PK =用户)
  • 按位置获取所有房间->查询(PK =用户,SK以位置开头)

这有点棘手...  -通过ID获取空间->

如果您确实需要在没有位置的情况下获得房间,那么除了将其作为排序键的一部分之外,您还希望将房间作为独立的属性。然后,您可以在其上创建一个本地二级索引并进行查询(PK =用户,索引SK =房间)

我怀疑通过GetItem(PK =用户,SK = location#room)查找房间可能适合您。

关键点,分区键的比较总是。分区键比较没有开头,结尾或包含。

如果您还没看过,请看以下视频
AWS re:Invent 2018: Building with AWS Databases: Match Your Workload to the Right Database (DAT301)
AWS re:Invent 2018: Amazon DynamoDB Deep Dive: Advanced Design Patterns for DynamoDB (DAT401)

还要确保阅读SaaS Storage Strategies - Building a Multitenant Storage Model on AWS白皮书。

编辑
“位置”和“房间”对于您的应用程序可能是最有意义的。 GUID或自然键,例如“ Home”。在noSQL数据库中,当多个节点添加记录时,GUID很有用。但是,当应用程序用户可以方便使用时,自然键就很好了。因为您不想通过自然键查找向导。 RDBMS惯例不适用于noSQL数据库。

是的,我将使用“家庭”作为位置,这意味着用户将不能拥有多个“家庭”。但我认为这没什么大不了的,我会在现实生活中使用“房屋”和“度假屋”。

EDIT2
Dynamo不在乎它是GUID还是自然键。它在内部散列用于分区键的任何值。重要的是不同值的数量。不同是不同的,无论值是“ 0ae4ad25-5551-46a7-8e39-64619645bd58”还是“ charles.wilt@mydomain.com”都没有关系。如果您的授权过程返回了GUID,请使用该GUID。否则,请使用用户名。