Эффективно ли использовать несколько глобальных индексов в одной таблице DynamoDB?
Выход из набора данных, как описано в таблице ниже. Sr.no используется в таблице ниже только для справки
|sr.no| id | tis |data-type| b.id |idType_2| var_2 |
|-----|----------|-----|---------|----------|--------|--------|
| 1 |abc-def-gi|12345| a-type |1234567890| 843023 | NULL |
|-----|----------|-----|---------|----------|--------|--------|
| 2 |1234567890|12346| b-type | NULL | NULL |40030230|
|-----|----------|-----|---------|----------|--------|--------|
| 3 |abc-def-gj|12347| a-type |1234567890| 843023 | NULL |
Типы запросов
- вход
id
и еслиdata-type
являетсяa-type
возврат полейtis,b.id,id_type2
ссылкаsr.no=1
- вход
id
и еслиdata-type
являетсяb-type
возвратное полеvar_2
ссылкаsr.no=2
- вход
id_type2
возврат полейid,tis,b.id
изsr.no=1,3
- вход
data-type
вернутьid
основанный наtis between 12345 and 12347
Заметка
sr.no=1,3
или жеa-type
данных вставляется 100к раз в день с уникальнымid
sr.no=2
или жеb-type
данных является фиксированным набором данных.
Является ли приведенный ниже ключевой подход эффективным для такого набора данных? Есть ли какой-то другой подход, который можно использовать для хранения и извлечения данных из DynamoDB?
Partition Key = id
позаботиться о Query 1,2.
GSI1=id_type2 and GSI1SK=id
позаботиться о Query 3
GSI2=data-type and GSI2SK=tis
позаботиться о Query 4
1 ответ
Вот мои мысли:
1) если у вас есть данные, которые имеют разные шаблоны доступа, вам следует рассмотреть возможность разделения данных на разные таблицы
2) если к данным обращаются вместе, храните их вместе - это означает, что если вы когда-либо читаете данные типа a для некоторой моделируемой сущности, вам также необходимо прочитать одну или несколько записей типа b для одной и той же сущности, это выгодно поместить все эти записи в одну таблицу под одним и тем же ключом раздела
Чтобы привести все это домой, в вашем примере, идентификатор для данных типа a и типа b отличается. Это означает, что вы получаете 0 преимуществ от хранения обоих типов a и b в одной таблице. Используйте две разные таблицы.
3) данные, к которым нет совместного доступа, вообще не выигрывают от размещения в одной таблице и фактически могут стать проблемой в более экстремальных обстоятельствах
Основное различие между реляционными и нереляционными базами данных состоит в том, что в нереляционных хранилищах нет перекрестных объединений, поэтому одним из принципов реляционных баз данных является нормализация данных, а в нереляционных случаях наблюдается обратное.
Это было решено с помощью следующей инструкции DynamoDB без создания GSI.
Когда создается GSI, все данные, записанные в основной таблице, копируются в таблицу GSI, так что WriteCost равна x Число GSI. Если у вас 1 GSI, это PrimaryWrite+GSIWrite, если у вас 2 GSI, то это Primary + GSI1 + GSI2. Кроме того, запись в GSI такая же, как и в первичном, поэтому, если вы подключаетесь к первичному серверу на 1000 WCU, то же самое будет применяться к GSI, так что всего будет 2000 WCU для 1GSI и 3000WCU для 2 GSI.
Что мы сделали
application_unique_id as hash key
timestamp as sort key
Остальные ключи хранились как атрибуты (DynamoDB поддерживает динамический JSON при наличии действующего хэш-ключа и ключа сортировки).
Мы использовали лямбда-функцию, присоединенную к потоку DynamoDB таблицы, для записи данных в кластер ElasticSearch.
Мы сделали ежедневный индекс последних данных моментальных снимков, так как DynamoDB содержит все точки трассировки и является лучшим местом для их хранения и запросов.
Таким образом, мы знали, какие данные были отправлены в какой день (поскольку Dynamodb не позволяет пользователю экспортировать список хеш-ключей). А все остальные спроецированные и сравнительные запросы мы могли бы выполнять внутри ElasticSearch.
DynamoDB решил запрос данных временных рядов на уровне задержки менее миллисекунды. ElasticSearch решил проблему всех операций сравнения и фильтрации поверх данных.
Установите DynamoDB ttl на 30 дней, ElasticSearch не поддерживает ttl, однако мы удаляем дневной индекс, когда день создания индекса пересекает 30 дней.