Моделирование отношения «один ко многим», когда число сторон многих может быть либо слишком маленьким, либо слишком большим

#amazon-dynamodb

#amazon-dynamodb

Вопрос:

Мне нужен совет.

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

У одного издателя может быть несколько интеграций (на основе того факта, что у них может быть несколько сайтов или несколько подсайтов).

Количество статей в интеграции может быть слишком маленьким или слишком большим в зависимости от размера издателя. Доступ к статьям будет осуществляться реже или слишком часто в зависимости от количества ежедневных посетителей сайта.

Таким образом, у пользователя много интеграций. В интеграции много статей. введите описание изображения здесь

Схема доступа к данным выглядит следующим образом:

 getIntegrationByUserId(userId)
getIntgrationById(integrationId)
getContentByIntegrationId(integrationId)
getContentByIntegrationIdBetweenDates(integrationId, from_date, to_date)
getContentByIntegrationIdAndContentId(integrationId, contentId)
  

Ниже приведена диаграмма сущностей, которую я планирую.

введите описание изображения здесь

Для фильтра даты я думаю добавить следующий GSI:

 GSI1PK: CONTENTS#<TimeStamp>
GSI1SK: CONTENT#<ContentId>
  

Ниже приведены мои вопросы:

  1. Как поддерживать getContentByIntegrationIdBetweenDates(integrationId, from_date, to_date) в приведенной выше модели.

  2. Должен ли я использовать интеграцию или пользователя в качестве первичного ключа? Меня беспокоит равномерное распределение содержимого между разделами. Некоторые пользователи или интеграция будут иметь сравнительно большое количество контента и частый доступ к контенту. Приведет ли приведенная выше модель к сценарию с горячими клавишами?

Предложения приветствуются.

Ответ №1:

Я вижу модель следующим образом:

 User 
-----------
user_id: pk; uuid
... user specific attributes ...

Integration
-----------
integration_id: pk, uuid
user_id: uuid, references User:user_id

Content
-----------
content_id: pk, uuid
content: text
created_at: date
integration_id: uuid, references Integration:integration_id

GSI: 
Integration: on user_id
Content: on integration_id, with created_at as sort key
  

Как поддерживать getContentByIntegrationIdBetweenDates(integrationId,
from_date, to_date) в приведенной выше модели.

Используя integration_id с created_at GSI в таблице содержимого. Примените фильтрацию по дате.

Должен ли я использовать интеграцию или пользователя в качестве первичного ключа? Меня беспокоит равномерное распределение содержимого между разделами. Некоторые пользователи или интеграция будут иметь сравнительно большое количество контента и частый доступ к контенту. Приведет ли приведенная выше модель к сценарию с горячими клавишами?

Единственная проблема, которую я вижу при использовании этой модели, — это integration_id GSI в Content таблице. Если на интеграцию приходится слишком много контента (для каждого пользователя безопасно), это может привести к проблемам. Dynamodb имеет ограничение в 10 ГБ на раздел, но в случае, если ваш ключ превысит это значение, он прозрачно создаст новый, поэтому он не выйдет из строя. Для этого разделения необходим ключ сортировки, поэтому created_at он также пригодится для этого.

Комментарии:

1. Иметь отдельные таблицы имеет больше смысла или иметь одну таблицу? Во многих местах они предложили использовать одну таблицу.

2. В NoSQL ваша модель создается на основе запросов, которые вы будете выполнять к ней. Так что это многое зависит, я бы сказал. Вы можете, например, встроить пользователя в интеграцию. Но если вы измените, например, первое имя, вам нужно сделать это вручную для всех объектов интеграции. Это во многом зависит от ваших запросов и обновлений