Добавьте индекс для статуса заказов

AWSBeginner
Практиковаться сейчас

Введение

Команде упаковки нужны заказы NEW разных клиентов. Первичный ключ клиента и даты не может обслужить этот шаблон доступа одним Query основной таблицы. Вы добавите глобальный вторичный индекс, выберете проекцию, запросите фактическую очередь и увидите переход упакованного заказа между разделами индекса после записи в основную таблицу.

Сначала выполните работу «Запросите заказы по ключам раздела и сортировки». Эта новая VM подготавливает только основную таблицу, синтетические записи, эталонную таблицу и оболочку приложения. Создание индекса и настройка поиска — ваша работа. Используйте /home/labex/project, официальный AWS CLI и AWS View.

Связь с сертификацией

Сертификация Задача экзамена Практика
Solutions Architect – Associate (SAA-C03) Задача 3.3 Вторичные индексы DynamoDB и проекция атрибутов.
Developer – Associate (DVA-C02) Задача 1.3 Вторичные индексы DynamoDB и проекция атрибутов.
Data Engineer – Associate (DEA-C01) Задача 2.4 Базовая практика: Вторичные индексы DynamoDB и проекция атрибутов.

Обзор работы

Концептуальная схема с иконками AWS4, экспортированная в draw.io: GSI создаёт представление тех же заказов по статусу и дате для очереди NEW всех клиентов; записи в базовую таблицу обновляют это производное представление.

Добавьте альтернативный шаблон доступа

На этом шаге вы добавите индекс для очереди упаковки, которой нужны заказы NEW разных клиентов. Подготовленная таблица использует customer_id и order_key; Query основной таблицы не может выбрать всех клиентов по статусу, поскольку status не является её ключом раздела. Глобальный вторичный индекс (GSI) предоставляет другое представление тех же элементов по ключам раздела и сортировки.

Поиск по клиенту и очередь упаковки решают разные бизнес-задачи на одних заказах. GSI позволяет очереди напрямую выбирать раздел по статусу для разных клиентов. Фильтр статуса в Query по клиенту всё равно проверял бы только раздел этого клиента и не создал бы альтернативный путь доступа для очереди.

Выбранные атрибуты тех же элементов, расположенные по ключам основной таблицы и индекса статуса.

Таблица заказов и три синтетические записи подготовлены независимо, чтобы вы сосредоточились на новом шаблоне доступа. Сначала изучите их; оставьте все записи без изменений, кроме изучаемого обновления статуса.

cd /home/labex/project
aws dynamodb describe-table --table-name labex-d03-orders --query 'Table.KeySchema'
aws dynamodb scan --table-name labex-d03-orders --consistent-read

Добавьте StatusDateIndex со status как ключом раздела и order_key как ключом сортировки. Проекция определяет атрибуты, хранимые индексом. INCLUDE добавляет amount; ключи таблицы и индекса включаются автоматически. Неключевой атрибут source останется только в основной таблице. Хранение и записи индекса имеют стоимость в AWS.

aws dynamodb update-table \
  --table-name labex-d03-orders \
  --attribute-definitions AttributeName=status,AttributeType=S AttributeName=order_key,AttributeType=S \
  --global-secondary-index-updates '[{"Create":{"IndexName":"StatusDateIndex","KeySchema":[{"AttributeName":"status","KeyType":"HASH"},{"AttributeName":"order_key","KeyType":"RANGE"}],"Projection":{"ProjectionType":"INCLUDE","NonKeyAttributes":["amount"]}}}]'
aws dynamodb describe-table \
  --table-name labex-d03-orders \
  --query 'Table.GlobalSecondaryIndexes[].{Name:IndexName,State:IndexStatus,Keys:KeySchema,Projection:Projection}'

Продолжайте только когда StatusDateIndex сообщает ACTIVE. Создание может занять время в AWS; повторяйте команду describe, пока индекс создаётся. Команда ожидания table-exists не доказывает готовность нового индекса. AWS View показывает индекс внутри карточки таблицы после сообщения сервиса.

Запросите индекс статуса и изучите его проекцию

На этом шаге вы прочитаете очередь NEW через альтернативные ключи. --index-name выбирает GSI. Условие ключа использует равенство status; фильтр сканирования основной таблицы сначала прочитал бы посторонние элементы.

aws dynamodb query \
  --table-name labex-d03-orders \
  --index-name StatusDateIndex \
  --key-condition-expression '#state = :state' \
  --expression-attribute-names '{"#state":"status"}' \
  --expression-attribute-values '{":state":{"S":"NEW"}}'

Индекс возвращает O100 Ada и O200 Bob, каждый с amount. Атрибут source отсутствует, поскольку не был проецирован. Получение дополнительных атрибутов основной таблицы потребовало бы отдельного чтения по ключу.

Обновления GSI асинхронны в AWS, а чтения GSI имеют итоговую согласованность. Не добавляйте --consistent-read к Query GSI: такой запрос отклоняется с ValidationException. Подождите и повторите чтение, если недавняя запись ещё не достигла индекса; не считайте устаревший результат доказательством отказа записи.

Предоставленное приложение order-lookup из предыдущей работы читает обычные настройки lookup.json. Запишите запрос для выбора этого индекса и очереди NEW. Heredoc с кавычками записывает JSON буквально; ConsistentRead: false явно задаёт выбор чтения индекса.

cat > lookup.json <<'JSON'
{
  "paginate": true,
  "request": {
    "TableName": "labex-d03-orders",
    "IndexName": "StatusDateIndex",
    "KeyConditionExpression": "#state = :state",
    "ExpressionAttributeNames": {
      "#state": "status"
    },
    "ExpressionAttributeValues": {
      ":state": {
        "S": "NEW"
      }
    },
    "ConsistentRead": false
  }
}
JSON
./order-lookup

Приложение возвращает те же два заказа. Раскройте StatusDateIndex в AWS View и сравните фактическую проекцию с результатом поиска. Сохранение обоих клиентов правильно для очереди статуса, хотя представление конкретного клиента потребовало бы другого шаблона ключей.

Наблюдайте переход заказа между очередями статусов

На этом шаге вы упакуете O100 и увидите перемещение его записи индекса. GSI следует записям основной таблицы; напрямую в индекс вы не записываете. Обновление status меняет раздел индекса элемента, а его основной первичный ключ остаётся тем же.

aws dynamodb update-item \
  --table-name labex-d03-orders \
  --key '{"customer_id":{"S":"ada"},"order_key":{"S":"2026-10-01#O100"}}' \
  --update-expression 'SET #state = :state' \
  --expression-attribute-names '{"#state":"status"}' \
  --expression-attribute-values '{":state":{"S":"PACKED"}}' \
  --return-values ALL_NEW
./order-lookup

Теперь очередь NEW содержит только O200 Bob. Запросите PACKED, чтобы подтвердить появление O100 рядом с O101, а не его исчезновение из сервиса.

aws dynamodb query \
  --table-name labex-d03-orders \
  --index-name StatusDateIndex \
  --key-condition-expression '#state = :state' \
  --expression-attribute-names '{"#state":"status"}' \
  --expression-attribute-values '{":state":{"S":"PACKED"}}'

Ожидайте O100 и O101 Ada в PACKED. В AWS повторяйте эти чтения до видимого распространения изменения в индекс. Ответ обновления и согласованное чтение основной таблицы — авторитетное немедленное состояние элемента; GSI — производное представление с итоговой согласованностью. AWS View показывает новый статус O100 и поиск NEW, содержащий только O200.

Активный индекс проецирует альтернативные ключи и amount, а очередь NEW содержит только заказ Bob.

Удалите собственный индекс и таблицу

На этом шаге вы удалите альтернативное представление, затем собственную таблицу. Удаление индекса оставляет элементы основной таблицы целыми; удаление таблицы удаляет элементы и оставшиеся индексы. Называйте только собственные ресурсы.

aws dynamodb update-table \
  --table-name labex-d03-orders \
  --global-secondary-index-updates '[{"Delete":{"IndexName":"StatusDateIndex"}}]'
aws dynamodb describe-table \
  --table-name labex-d03-orders \
  --query 'Table.GlobalSecondaryIndexes'

Продолжайте, когда список индексов пуст. В AWS повторяйте DescribeTable во время удаления. В этот момент таблица всё ещё содержит три элемента.

aws dynamodb scan --table-name labex-d03-orders --consistent-read --select COUNT
aws dynamodb delete-table --table-name labex-d03-orders
aws dynamodb wait table-not-exists --table-name labex-d03-orders
aws dynamodb list-tables
aws dynamodb get-item \
  --table-name labex-d03-reference \
  --key '{"id":{"S":"platform"}}' \
  --consistent-read

Таблица заказов и её индекс отсутствуют; эталонная заметка остаётся keep unchanged. Успешная инвентаризация и чтение эталонного ресурса отличают очистку от отключённого сервиса. AWS View сохраняет только посторонний эталонный ресурс. Временное подключение заканчивается с VM.

Резюме

Вы добавили GSI для очереди статуса разных клиентов, выбрали проецируемые атрибуты и использовали ключи индекса в фактических запросах. Обновление статуса основной таблицы переместило заказ между разделами индекса, не меняя первичный ключ. Вы различили немедленное состояние основной таблицы и итоговое распространение в индекс, затем удалили только собственные индекс и таблицу.

Подробнее см. в документации AWS: Глобальные вторичные индексы, проекции и согласованность.