#node.js #aws-lambda #amazon-dynamodb
#node.js #aws-lambda #amazon-dynamodb
Вопрос:
У меня есть таблица Dynamodb под названием «Пользователи»:
Первичный ключ: идентификатор пользователя (уникально сгенерированный внутри) Ключ сортировки: Атрибут электронной почты: Друзья (тип M) —> Идентификатор пользователя, статус
Итак, для одной записи пользователя это может выглядеть так:
Идентификатор пользователя: 000001
Электронная почта: myname@domain.com
Friends
-------
UserId: 00008 Status: Active
UserId: 00010 Status: Active
Если я хотел бы запросить и изменить статус для данного идентификатора пользователя в атрибуте «Друзья» и не зная значения первичного ключа, каков наилучший практический способ изменить структуру таблицы или метод запроса? Мне сказали, что «Сканирование» не рекомендуется для больших таблиц.
Любая помощь приветствуется, поскольку этот NoSQL для меня очень новый.
Комментарии:
1. Если вы хотите выполнить запрос в dynamodb и избежать «сканирования», вам необходимо создать глобальный (или локальный) вторичный индекс. к сожалению, вы не можете создать индекс для атрибута карты, если хотите запросить идентификаторы пользователей в атрибуте карты «друзья». Вам нужно подумать, как реструктурировать схему вашей базы данных.
2. @gijoe спасибо за ваш ответ. Да, это то, что меня сейчас беспокоит о том, как создать множественный список «друзей» для данного идентификатора пользователя
3. это личное архитектурное решение, но самым простым способом было бы создать новую таблицу, в которой будут храниться друзья пользователя с именем => Users_Friends, и у нее будет глобальный вторичный индекс с хэш-ключом userId (и, возможно, вы также можете использовать ключ диапазона в поле «Статус», чтобы вы моглинайдите одним запросом всех друзей пользователя, которые активны или неактивны)
4. @gijoe Я думал о создании еще одного стола для друзей, но руководство считает, что им сойдет с рук только один стол. И да, вторая таблица для хранения друзей будет проще для запроса
5. друг — это двунаправленные отношения, верно?
Ответ №1:
Похоже, вы хотите обновить статус друга пользователя, но вы знаете только идентификатор друга. Судя по вашему вопросу, похоже, что ваши данные хранятся следующим образом:
В этой таблице вы выбрали модель отношения «один ко многим» между пользователем и его друзьями в виде карты. Это правильный способ моделирования этого отношения «один ко многим». Однако, как вы обнаруживаете, этот подход имеет ограничения.
Если все, что вам нужно было сделать, это перечислить друзей пользователя, этого может быть достаточно. Однако, если у вас есть какие-либо шаблоны доступа, которые требуют поиска по элементам внутри карты друзей, вы обнаружите, что этот шаблон довольно ограничен.
Один из способов исправить это — смоделировать отношения пользователя с друзьями в коллекциях элементов:
В этом примере я представляю коллекции элементов, которые группируют более одного типа отношений под одним и тем же ключом раздела. Я также переименовал ключ раздела и ключ сортировки в PK и SK соответственно, поскольку теперь я использую эти поля более обобщенно. Несколько вещей, на которые я хотел бы обратить внимание:
- PK = 000001 представляет коллекцию пользовательских элементов. Эта коллекция содержит информацию о пользователе и его друзьях.
- PK = 000001 SK = user1@gmail.com является пользовательским элементом.
- PK = 000001 SK = FRIEND00002 — это элемент, который представляет дружбу между пользователями 000001 и 000002.
- Вы можете получить всех друзей пользователя 000001, выполнив
query
операцию, в которой PK = 000001 иbegins_with
ДРУГ SK.
Теперь, когда у нас есть данные, упорядоченные таким образом, мы можем более легко обратиться к вашему шаблону доступа. Например, мы могли бы создать вторичный индекс, который меняет местами поля PK и SK вашей основной таблицы. Это называется «инвертированным индексом». Используя приведенный выше пример, ваш вторичный индекс логически будет выглядеть следующим образом.
Имейте в виду, что это те же данные, просто другой вид данных.
С помощью этого вторичного индекса вы можете выполнить одну операцию updateItem для обновления status
любого конкретного friendship.
Комментарии:
1. Это отличное объяснение всего. Я обязательно постараюсь переварить это. Я исхожу из разума RDS, поэтому для понимания этого требуется некоторое переключение мозга. Я не могу отблагодарить тебя за этот ответ, Сет.
2. Рад слышать! Если это помогло, рассмотрите возможность принятия его в качестве ответа на вопрос (или отметьте ответ как полезный). DDB полностью отличается от систем RDS, к нему определенно нужно привыкнуть.
3. Привет, Сет, используя коллекции в приведенном выше примере, как бы вы создали свои параметры в лямбде, чтобы добавить новую запись пользователя с помощью PutItem? Мой текущий поток заключается в том, что друзья могут приходить позже после создания пользователя.
4. параметры = { «Имя_таблицы»: «Пользователи», «Элемент»: { «PK»: {«S»: «<идентификатор пользователя здесь>»}, «SK»:{ «S»: «<адрес электронной почты пользователя здесь>»} } }
5. Большое тебе спасибо, Сет. Думаю, теперь я понял идею.