Skip to content

DynamoDB Indexes, All About Primary and Secondary Indexes.

Indexes in DynamoDB make querying the data more efficient and faster than scanning the whole table. There are two types of indexes that can be created in a table, one is the Partition key and the other one is the Sort key. These indexes are used to improve the data access from DynamoDB.

When a new table is created, it is mandatory to select a column as the primary Partition key which will be the table’s default primary key. We can run queries on the table based on this default Partition key. But if we need another key to be added to sort the data or to be added in the queries along with the Partition key, we can also add the Sort key in the primary index. Syntax for adding these indexes in serverless.yml will be:

    TableNameDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
          - AttributeName: created_at
            AttributeType: N
        KeySchema:
          - AttributeName: id
            KeyType: HASH
          - AttributeName: created_at
            KeyType: RANGE
        TableName: ${file(./aws/dynamodb_tables.json):TABLENAME}

The above code creates two indexes in the table, one is id, which is the Partition key and the datatype is going to be string, and the other one is created_at, which is the Sort key, and the datatype will be Integer.

And then, DynamoDB supports two types of indexes:

  • Global Secondary Index
  • Local Secondary Index

Global Secondary Indexes(GSIs)

When we define a Global Secondary Index, it creates a separate indexed table, where we can run our queries using the indexes mentioned in the GSI. GSIs have a partition key and a sort key that can be different from the keys in the base table. GSIs can be created on tables with simple key schemas and don’t share throughput for read and write with the base table.

With GSI queries and scans, you can only fetch the attributes that are projected in that particular index. For simplicity, we can consider GSI as a secondary table with the same data which has its own Partition and Sort keys. In serverless.yml, if we need to add GSI, the code will be like:

    TableNameDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
          - AttributeName: created_at
            AttributeType: N
          - AttributeName: cat_id
            AttributeType: S
          - AttributeName: is_deleted
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
          - AttributeName: created_at
            KeyType: RANGE
        GlobalSecondaryIndexes:
          - IndexName: category_info
            KeySchema:
              - AttributeName: cat_id
                KeyType: HASH
              - AttributeName: is_deleted
                KeyType: RANGE
            Projection:
              ProjectionType: "ALL"
        TableName: ${file(./aws/dynamodb_tables.json):TABLENAME}

Here we have defined a new Global Secondary Index named category_info, which has its own Hash and Range keys.

Local Secondary Indexes(LSIs)

LSIs have a partition key that must be the same as the partition key of its table, but the sort key can be any other attribute. Local indexes are only useful for different sorting patterns. Local Indexes can be used to add an extra Sort key to the table along with the Global Secondary Index and also with the base table indexes.

Local indexes limit data volume to 10 GB for any given partition key value.

    TableNameDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
          - AttributeName: created_at
            AttributeType: N
          - AttributeName: is_deleted
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
          - AttributeName: created_at
            KeyType: RANGE
        LocalSecondaryIndexes:
          - IndexName: is_delete-index
            KeySchema:
              - AttributeName: id
                KeyType: HASH
              - AttributeName: is_deleted
                KeyType: RANGE

Here we have created an LSI named is_delete-index, which has the same Partition key id as the base table and is_deleted as the Range key. An LSI lets us query over a single partition, as specified by the partition key value in the query.

Also read about, DynamoDB, When and How to Use.

Learn more about service quotas: AWS DynamoDB Service Quotas

Leave a Reply

Your email address will not be published. Required fields are marked *