Существует практическое занятие по aws, посвященное аналогичной проблеме - «мобильное приложение, включающее социальную сеть»: https://aws.amazon.com/getting-started/hands-on/design-a-database-for-a-mobile-app-with-Dynamodb/4/
Краткое описание:
- Пользователи будут загружать фотографии через ваше приложение
- пользователи захотят найти друзей и подписаться на них
- Подписавшись на друга, пользователь будет получать уведомления о новых фотографиях друга.
- пользователь сможет отправлять сообщения своим друзьям
- друзья могут просматривать свои фотографии
- пользователи могут реагировать на фотографию одним из четырех смайликов - сердечком, смайликом, большим пальцем вверх или парой солнцезащитных очков.
- При просмотре фотографии пользователи должны видеть количество реакций каждого типа на фотографию.
Модель имеет следующие сущности: User
, Photo
, Reaction
, Friendship
.
User
может иметь много Photos
, а Photo
может иметь много Reactions
. Наконец, сущность Friendship
представляет отношение «многие ко многим» между пользователями, поскольку пользователь может следовать за несколькими пользователями, а за ним могут следовать несколько других пользователей.
Шаблоны доступа
Исходя из бизнес-требований, были определены следующие шаблоны доступа:
Пользователь
- Создать профиль пользователя (Написать)
- Обновить профиль пользователя (Написать)
- Получить профиль пользователя (Читать)
Фото
- Загрузить фото для пользователя (Написать)
- Просмотр последних фотографий пользователя (Читать)
- Реагировать на фото (Написать)
- Посмотреть фото и реакции (Читать)
Дружба
Пользователи могут подписываться на друзей, просматривать обновления о действиях своих друзей и получать рекомендации о других друзьях, за которыми они, возможно, захотят подписаться.
Дружба - это односторонние отношения, как в Твиттере. Один пользователь может выбрать подписку на другого пользователя, и этот пользователь может подписаться на него в ответ. Для нашего приложения мы будем называть пользователей, которые следят за пользователем, «подписчиками», и мы будем называть пользователей, на которых подписан пользователь, «отслеживаемыми».
Основываясь на этой информации, у нас есть следующие шаблоны доступа:
- Следить за пользователем (Написать)
- Просмотреть подписчиков для пользователя (Читать)
- Просмотр для пользователя (чтение)
В сущности «Дружба» у нас есть шаблон доступа, который должен найти всех пользователей, которые следуют за конкретным пользователем, а также шаблон доступа, чтобы найти всех пользователей, за которыми следует данный пользователь.
Дизайн стола
По этой причине мы будем использовать составной первичный ключ со значением PK и SK. Составной первичный ключ даст нам возможность запроса на PK для удовлетворения одного из необходимых нам шаблонов запросов:
Entity PK SK
User USER#<USERNAME> #METADATA#<USERNAME>
Photo USER#<USERNAME>. PHOTO#<USERNAME>#<TIMESTAMP>
Reaction REACTION#<USERNAME>#<TYPE> PHOTO#<USERNAME>#<TIMESTAMP>
Friendship USER#<USERNAME> #FRIEND#<FRIEND_USERNAME>
Сущность «Дружба» использует тот же ПК, что и сущность «Пользователь». Это позволит вам получить как метаданные для пользователя, так и всех его подписчиков в одном запросе:
KeyConditionExpression="PK = :pk AND SK BETWEEN :metadata AND :photos",
ExpressionAttributeValues={
":pk": { "S": "USER#{}".format(username) },
":metadata": { "S": "#METADATA#{}".format(username) },
":photos": { "S": "PHOTO$" },
},
Вторичный (инвертированный) индекс полезен для запроса «другой» стороны отношения «многие ко многим». Так обстоит дело с вашей сущностью Дружбы. С помощью структуры первичного ключа вы можете запрашивать всех подписчиков конкретного пользователя с помощью запроса по первичному ключу таблицы. Когда вы добавляете инвертированный индекс, вы сможете найти пользователей, за которыми подписан пользователь («отслеживаемые»), запросив инвертированный индекс:
KeyConditionExpression="SK = :sk",
ExpressionAttributeValues={
":sk": { "S": "#FRIEND#{}".format(username) }
},
Расширения
Было бы интересно настроить дизайн для поддержки мега-популярных пользователей (имеющих миллионы подписчиков).
Еще один интересный шаблон доступа, о котором здесь не упоминается, - это пользовательский канал - просмотр всех фотографий, которые недавно опубликовали их друзья. Это можно сделать с другой таблицей, содержащей этот поток данных, который обновляется всякий раз, когда друг что-то публикует (найти его подписчиков, обновить их ленты ...).
person
milan
schedule
12.05.2020