дизайн индекса таблицы dynamodb, глобальный индекс или локальный

#amazon-dynamodb

#amazon-dynamodb

Вопрос:

У меня есть 3 таблицы dynamodb, например:

   companies:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:provider.region}.${opt:stage}.companies
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST
      Tags:
        - Key: Name
          Value: ${self:provider.region}.${opt:stage}.${self:custom.customDomain.domainName}
  addresses:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: ${self:provider.region}.${opt:stage}.addresses
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST
      Tags:
        - Key: Name
          Value: ${self:provider.region}.${opt:stage}.${self:custom.customDomain.domainName}
  users:
    Type: AWS::DynamoDB::Table
    DependsOn: companies
    Properties:
      TableName: ${self:provider.region}.${opt:stage}.users
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
        - AttributeName: email
          AttributeType: S
        - AttributeName: upload_id
          AttributeType: S
        - AttributeName: company
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
        - AttributeName: email
          KeyType: RANGE
      LocalSecondaryIndexes:
        - IndexName: LSI-${self:provider.region}-${opt:stage}-companyId-by-userId-index
          KeySchema:
            - AttributeName: company
              KeyType: HASH
            - AttributeName: id
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      GlobalSecondaryIndexes:
        - IndexName: GSI-${self:provider.region}-${opt:stage}-uploadId-by-userId-index
          KeySchema:
            - AttributeName: upload_id
              KeyType: HASH
            - AttributeName: id
              KeyType: RANGE
          Projection:
            ProjectionType: ALL
      Tags:
        - Key: Name
          Value: ${self:provider.region}.${opt:stage}.${self:custom.customDomain.domainName}
  

в принципе, запись о компании будет иметь много адресов, а пользователь будет принадлежать только одной компании, этот пользователь был загружен с использованием уникального upload_id, который мог загрузить много пользователей, поэтому:

если я хочу получить всех пользователей, у которых есть определенный upload_id , глобальный индекс лучше?

и если я хочу получить всех пользователей из одной компании, будет ли локальный вторичный индекс лучше?

Ответ №1:

Вы должны использовать локальный вторичный индекс (LSI) только в том случае, если вам требуется, чтобы индекс был строго согласованным. Если вас устраивает конечный согласованный индекс, тогда вам следует использовать глобальный вторичный индекс (GSI), потому что у LSI много ограничений.

  • LSI нельзя изменить или удалить без удаления и воссоздания всей таблицы. GSI могут быть созданы / удалены в любое время без какого-либо воздействия на основную таблицу.
  • Из-за LSI у вас будет ограничение в 10 ГБ данных на ключ раздела. Без LSI существует ограничение в 10 ГБ на раздел, но вы этого не заметите, потому что DynamoDB при необходимости может разделить ваши данные для одного ключа раздела на несколько разделов.
  • При использовании LSI ограничение на размер элемента в 400 КБ применяется к элементу плюс ко всем его проекциям LSI. Элемент в GSI учитывается отдельно от элемента в основной таблице.
  • Выделенная емкость GSI может масштабироваться независимо от основной таблицы, тогда как LSI используют ту же емкость, что и базовая таблица.

Более подробную информацию см. в разделе Улучшение доступа к данным с помощью вторичных индексов.