我试图在DynamodDB中建立一个编目系统的模型。它有包含“藏书”的“目录”。每个“收藏”都可以用许多“标签”标记。
在RDBMS中,我会创建一个与“Collection”的1:n关系的“目录”表。“Collection”将有一个n:n,带有“标记”,因为Collection可以有多个标记,一个标记可以属于多个集合。
我想要运行的查询是:
1)获取所有目录
2)按ID获取目录
3)按目录ID获取集合
我在AWS上阅读,我可以使用邻接列表地图设计(因为我有n:n和“标记”)。这是我的桌子结构:
PK SK name
cat-1 cat-1 Sales Catalog
cat-1 col-1 Sales First Collection
cat-1 col-2 Sales Second Collection
cat-2 cat-2 Finance Catalog
tag-1 tag-1 Recently Added Tag
col-1 tag-1 (collection, tag relationship)这里的问题是,为了获得所有的“目录”,我必须使用我理解为效率低下的扫描,因为查询的PK必须是'=‘而不是’开始‘。
我唯一能想到的就是创建另一个属性,如"GSI_PK“,并在PK为cat-1,SK为cat-1,而PK为cat-2,SK为cat-2时添加"Catalog_1”。我从来没有真正看到这样做,所以我不确定这是否可行,如果我想要更改ID,就需要进行一些维护。
知道我该怎么做吗?
发布于 2018-09-07 20:53:38
在这种情况下,您可以让PK是对象的类型,而SK是uuid。一个记录应该像这个{ PK: "Catalog", SK: "uuid", ...other catalog fields }。然后,您可以通过对PK = Catalog执行查询来获取所有目录。
要存储关联,可以在两个字段( sourcePK和relatedPK )上存储GSI,在这两个字段中可以存储与事物相关的记录。要关联一个对象,您需要创建一个类似于{ PK: "Association", SK: "uuid", sourcePK: "category-1", relatedPK: "collection-1", ... other data on the association }的记录。要查找与id 1的"Catalog“关联的对象,您需要在GSI上执行一个查询,其中sourcePK = catalog-1。
使用此设置时,您需要小心热键,并应确保表或索引中同一分区键下的数据不超过10 or。
发布于 2018-09-07 19:19:26
我们走过去吧。我将使用GraphQL SDL来布局数据模型的设计&查询,但您只需将相同的概念直接应用于DynamoDB。
首先,考虑数据模型,我们将有如下内容:
type Catalog {
id: ID!
name: String
# Use a DynamoDB query on the **Collection** table
# where the **catalogId = $ctx.source.id**. Use a GSI or make catalogId the PK.
collections: [Collection]
}
type Collection {
id: ID!
name: String
# Use a DynamoDB query on the **CollectionTag** table where
# the **collectionId = $ctx.source.id**. Use a GSI or make the collectionId the PK.
tags: [CollectionTag]
}
# The "association map" idea as a GraphQL type. The underlying table has a collectionId and tagId.
# Create objects of this type to associate a collection and tag in the many to many relationship.
type CollectionTag {
# Do a GetItem on the **Collection** table where **id = $ctx.source.collectionId**
collection: Collection
# Do a GetItem on the **Tag** table where **id = $ctx.source.tagId**
tag: Tag
}
type Tag {
id: ID!
name: String
# Use a DynamoDB query on teh **CollectionTag** table where
# the **tagId = $ctx.source.id**. If collectionId is the PK then make a GSI where this tagId is the PK.
collections: [CollectionTag]
}
# Root level queries
type Query {
# GetItem to **Catalog** table where **id = $ctx.args.id**
getCatalog(id: ID!): Catalog
# Scan to **Catalog** table. As long as you don't care about ordering on a filed in particular then
# this will likely be okay at the top level. If you only want all catalogs where "arePublished = 1",
# for example then we would likely change this.
allCatalogs: [Catalog]
# Note: You don't really need a getCollectionsByCatalogId(catalogId: ID!) at the top level because you can
# use `query { getCatalog(id: "***") { collections { ... } } }` which is effectively the same thing.
# You could add another field here if having it at the top level was a requirement
getCollectionsByCatalogId(catalogId: ID!): [Collection]
}注意:无论我在哪里使用
[Collection]或[Catalog]等,您都应该使用CollectionConnection、CatalogConnection等包装类型来启用分页。
https://stackoverflow.com/questions/52175216
复制相似问题