Я создаю приложение DynamoDB, которое в конечном итоге будет обслуживать большое количество (миллионы) пользователей.В настоящее время схема элемента приложения проста:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
email: "foo@foo.com",
... other attributes ...
}
Когда новый пользователь регистрируется или если пользователь хочет найти другого пользователя по адресу электронной почты, мы должны вместо этого искать пользователей по email
из userId
.С текущей схемой это просто: просто используйте глобальный вторичный индекс с email
в качестве ключа раздела.
Но мы хотим включить несколько адресов электронной почты для каждого пользователя и DynamoDB Query
операция не поддерживает List
-тип KeyConditionExpression
.Поэтому я взвешиваю несколько вариантов, чтобы избежать дорогостоящей операции Scan
каждый раз, когда пользователь регистрируется или хочет найти другого пользователя по адресу электронной почты.
Ниже приведено то, что я планирую изменить, чтобы включить дополнительные электронные письма.на пользователя.Это хороший подход?Есть ли лучший вариант?
- Добавить столбец ключа сортировки (например,
itemTypeAndIndex
), чтобы разрешить несколько элементов для userId
.
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
itemTypeAndIndex: "main", // sort key
email: "foo@foo.com",
... other attributes ...
}
Если пользователь добавляет второе, третье и т. Д. Электронное письмо, а затем добавляет новый элемент для каждого электронного письма, например:
{
userId: "08074c7e0c0a4453b3c723685021d0b6", // partition key
itemTypeAndIndex: "Email-2", // sort key
email: "bar@bar.com"
// no more attributes
}
Один и тот же глобальный вторичный индекс (с email
в качестве ключа раздела) все еще можно использовать для поиска как первичных, так и неосновных адресов электронной почты.
Если пользователь хочет изменить свой основной адрес электронной почты, мы поменяем значения email
на «основной» и «неосновной» элементы.(Теперь, когда DynamoDB поддерживает транзакции , делать это будет безопаснее, чем раньше!)
Если нам нужно удалить пользователя, нам придется удалить всепредметы для этого userId
.Если нам нужно объединить двух пользователей, то нам придется объединить все элементы для этого userId
.
Тот же подход (новые элементы с одинаковыми userId
, но разными ключами сортировки)может использоваться для других данных «1 пользователь имеет множество значений», которые должны быть Query
-able
Это хороший способ сделать это?Есть ли лучший способ?