Контекст
Я создаю форум и изучаю моделирование данных с помощью DynamoDB и списков смежности. Некоторые объекты верхнего уровня (например, пользователи) могут иметь несколько типов отношений с другими объектами верхнего уровня (например, комментарии).
Требования
Например, допустим, мы хотим сделать следующее:
- Пользователям могут понравиться комментарии
- Пользователи могут следить за комментариями
- Комментарии могут отображать пользователей, которым это нравится
- Комментарии могут отображать пользователи, которые следуют за ним
- Профили пользователей могут показывать комментарии, которые им нравятся
- Профили пользователей могут отображать комментарии, за которыми они следят
Итак, по сути, у нас есть многие ко многим (пользовательские комментарии <=>) ко многим (например, или подписчикам).
Примечание: этот пример намеренно сокращен, и на практике будет гораздо больше связей с моделью, поэтому я пытаюсь придумать что-то расширяемое здесь.
Базовый
Следующие данные верхнего уровня, вероятно, будут общими в любом представлении списка смежности:
First_id(Partition key) Second_id(Sort Key) Data
------------- ---------- ------
User-Harry User-Harry User data
User-Ron User-Ron User data
User-Hermione User-Hermione User data
Comment-A Comment-A Comment data
Comment-B Comment-B Comment data
Comment-C Comment-C Comment data
Кроме того, для каждой таблицы ниже будет эквивалентный глобальный вторичный индекс с заменой ключей раздела и сортировки.
Пример данных
Это то, что я хотел бы смоделировать в DynamoDB:
- Гарри нравится комментарий A
- Гарри нравится комментарий B
- Гарри следует за комментарием A
- Рону нравится комментарий B
- Гермионе нравится комментарий C
Вариант 1
Используйте третий атрибут для определения типа отношения:
First_id(Partition key) Second_id(Sort Key) Data
------------- ---------- ------
Comment-A User-Harry "LIKES"
Comment-B User-Harry "LIKES"
Comment-A User-Harry "FOLLOWS"
Comment-B User-Ron "LIKES"
Comment-C User-Hermione "FOLLOWS"
Недостатком этого подхода является то, что в результатах запроса содержится избыточная информация, поскольку они будут возвращать дополнительные элементы, которые могут вас не волновать. Например, если вы хотите запросить всех пользователей, которым нравится данный комментарий, вам также придется обрабатывать всех пользователей, которые следуют за данным комментарием. Аналогично, если вы хотите запросить все комментарии, которые пользователь любит , вам нужно обработать все комментарии, которые пользователь подписывает .
Вариант 2
Измените ключи для представления отношения:
First_id(Partition key) Second_id(Sort Key)
------------- ----------
LikeComment-A LikeUser-Harry
LikeComment-B LikeUser-Harry
FollowComment-A FollowUser-Harry
LikeComment-B LikeUser-Ron
FollowComment-C FollowUser-Hermione
Это позволяет эффективно запрашивать независимо:
- Комментирует лайки
- Комментарий следует
- Мне нравится
- Пользователь следует
Недостатком является то, что одна и та же сущность верхнего уровня теперь имеет несколько ключей, что может усложнить ситуацию при добавлении новых связей.
Вариант 3
Пропустить списки смежности в целом и использовать отдельные таблицы, возможно, одну для Users
, одну для Likes
и одну для Follows
.
Вариант 4
Традиционная реляционная база данных. Хотя я не планирую идти по этому пути, потому что это личный проект, и я хочу изучить DynamoDB, если этот является правильным способом думать о вещах, мне бы хотелось услышать почему.
Заключение
Спасибо, что прочитали это далеко! Если я могу что-то сделать, чтобы упростить вопрос или что-то прояснить, пожалуйста, дайте мне знать:)
Я ознакомился с рекомендациями AWS и с этой публикацией SO-многие-ко-многим , и ни один из них, по-видимому, не касается отношения «многие-ко-многим (со многими)», поэтому любые ресурсы или рекомендации с благодарностью.