我正在尝试使用iot core,lambda和dynamodb以及无服务器框架和后续的Android / iOS应用程序在AWS上构建可扩展的智能家居基础架构。
我正在dynamodb中实现位置和房间。用户可以有多个位置,并且位置可以有多个房间。我习惯于使用Firebase Firestore,因此使用分区键和排序键(哈希和范围?)以及查询的组合会有些混乱。我实现了自己的哈希,以用作主要(分区?哈希?)ID。这是我正在考虑的结构:
位置
我还在username
上添加了二级索引,以便用户可以查询其所有位置。
房间
我还在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的工作方式)
任何建议将不胜感激!
编辑 我能想到的查询是:
但是随着应用程序将来的扩展,我希望这些查询具有灵活性(共享位置,获取共享位置等)
答案 0 :(得分:2)
我希望这些查询具有灵活性
然后一般而言,noSQL和Dynamo可能不是正确的选择。
@varnit暗示,noSQL DB在存储内容方面非常灵活,但是在查询数据方面却非常灵活。
例如,Dynamo仅在使用排序键(SK)或进行全表扫描(不推荐)时才可以返回列表(查询)。否则,它只能返回一条记录。
我不知道“共享位置”会带来什么。
但是在Dynamo中有多个原则(每个用户仅查看其数据),简单的解决方案是将userID用作分区键(PK)。
我将使用location#room的复合排序键
这有点棘手... -通过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。否则,请使用用户名。