Как запросить карту списка смежности n: n в DynamoDB без использования сканирования - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь смоделировать систему каталогизации в DynamodDB. У этого есть "Каталоги", который содержит "Коллекции". Каждая «Коллекция» может быть помечена многими «Тегами».

В СУБД я бы создал таблицу "Каталоги" с отношением 1: n с "Коллекциями". «Коллекции» будут иметь n: n с «Тегами», поскольку Коллекция может иметь несколько тегов, а тег может принадлежать нескольким коллекциям.

Запросы, которые я хочу выполнить:

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» и добавить «Catalog_1», когда PK - это cat-1, а SK - это cat-1, «Catalog_2», когда PK - это cat-2 и SK. это кот-2. Я никогда не видел, чтобы это было сделано, поэтому я не уверен, стоит ли идти этим путем, и мне нужно какое-то обслуживание, если я когда-нибудь захочу изменить ID.

Есть идеи, как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

В этом случае вы можете указать, что PK будет типом объекта, а SK - UUID. Запись будет выглядеть так { PK: "Catalog", SK: "uuid", ...other catalog fields }. Затем вы можете получить все каталоги, выполнив запрос к PK = Catalog.

Для хранения ассоциаций у вас может быть GSI в двух полях sourcePK и relatedPK, где вы можете хранить записи, которые связывают вещи. Чтобы связать объект, вы должны создать такую ​​запись, как, например, { PK: "Association", SK: "uuid", sourcePK: "category-1", relatedPK: "collection-1", ... other data on the association }. Чтобы найти объекты, связанные с «Каталогом» с идентификатором 1, вы должны выполнить запрос в GSI, где sourcePK = catalog-1.

При такой настройке вы должны быть осторожны с горячими клавишами и должны убедиться, что у вас никогда не будет более 10 ГБ данных под одним ключом разделения в таблице или индексе.

0 голосов
/ 07 сентября 2018

Давайте пройдемся по нему. Я буду использовать 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 и т. Д. Для включения нумерации страниц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...