我们使用AWS dynamodb存储学校详细信息。未来学校的入学人数可能过高。所以我们首选基于无sql的存储。
我们将从不同来源获取学校详细信息,因此我们从所有来源获得的详细信息结构不同。例如,在少数地方,我们可能会得到一些学生和老师。但在其他来源中,我们只获得位置详细信息。
因此我们考虑使用"重载全局二级索引"概念
以下是我们用于保存学校详细信息的表格。
school name is partition key
info type is sort key
Attr1... AttrN is Details based on the info type.
信息类型可以包含"学生信息","教师信息","位置信息","学校董事会"
Partition key infotype Attr1 Attr2 Attr3
schoolx students 150
schoolx teachers 50 (permanent) 25 (Temp)
schoolx Location Delhi India
schooly students 25
schooly Location Mumbai
我创建的索引是针对字段"信息类型"
现在我们需要支持如下的查询
问题:
答案 0 :(得分:2)
1 :嗯那取决于。它对于No-SQL模式并不完全合适。但它并非“不可行”。问题是数据的非规范化。 SQL在多表上传播(规范化)数据的好处,并且能够以灵活的模式进行查询。喜欢在孟买合并,不到100'。
2:让我们说,你写下位置旁边的所有属性(教师数,学生数)
Partition key infotype Attr1 Attr2 Attr3 StudentCount TeacherCount
schoolx students 150
schoolx teachers 50 (permanent) 25 (Temp)
schoolx Location Delhi India
schooly students 25
schooly Location Mumbai 25 180
这意味着您只需使用Location
孟买的排序键以及Attr1
,StudentCount > 10
的过滤器查询TeacherCount > 125
GSI(必须将这些属性投射到GSI)。它是一个查询。读取容量单位等于孟买项目的数量。它不到3个查询。
然而,这种非规范化伴随着写操作成本。每次这些属性发生变化时,您都需要更改Teachers
和Location
项。每次更新2次写入。
所有这些都是为了解释,在决定TRADE-OFFS时你必须考虑你的访问模式和频率。如果你的属性太少,低于1KB,那么这个工作变得容易,因为你可以自由地投影属性和更新而不会增加太多的成本。还有许多因素需要包括在内。考虑到一切可能,你必须努力。
3:实际上,您必须多次查询。因为第一个查询将返回' schoolx,schooly ..'并且您必须分别查询每个这些以获取其详细信息。
答案 1 :(得分:0)
GSI重载可能不是此用例的最佳选择。我建议只使用三个更新构建一个项目,在City上创建常规GSI,并在学生,PermanentTeachers和TempTeachers上创建3个分片GSI。
更新将插入一个新项目,如果它不存在,那么第一个作者将创建该项目,接下来的两个编写者将只添加他们的数据。
City GSI每个分区密钥永远不会包含超过几百个项目,并且它们都相当小,因此热键的风险可以忽略不计。当查询包含城市名称时,您可以点击该索引并使用学生和教师的过滤条件来获得正确的结果集。
学生和教师GSI可能需要写分片,因为他们会查询表中的所有学校。为此,添加一个" GSI_Key"插入时,每个项目的属性包含0到N之间的随机整数,并将其用作那些GSI的分区键。为了使符合您条件的学校与索引的相应排序键条件并行查询所有0-N分区,例如: "学生> 100"," tempTeachers> 25&#34 ;.根据需要为其他条件添加过滤条件。
" N"的价值对于GSI_Key属性,由项目添加到表中的速率以及我们期望根据GSI查询的排序键条件生成的结果集的大小来确定。如果您管理印度的所有学校和批量装载,那么您可能有50K或更多的项目。这些项目虽小,但需要多次更新,因此每个项目需要花费3 WCU才能插入,因此您需要150K WCU才能将所有这些项目写入表中。 DynamoDB允许每个分区1K WCU,因此要在10秒内摄取所有这些项目,我们将需要15个分区用于写分片GSI。