DynamoDB
Global Secondary Index
DynamoMapper
Class Annotation
Database Management

Create table with Global secondary index using DynamoMapper and class Annotation

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Amazon DynamoDB is a fully managed, highly scalable NoSQL database service that provides fast and predictable performance. When working with DynamoDB, you often need to perform complex queries that might not fit well with a primary key. This is where Global Secondary Indexes (GSIs) come into play. GSIs allow you to query your data flexibly, more akin to SQL databases, while still maintaining the NoSQL structure. In this article, we will explore the creation of a DynamoDB table with a Global Secondary Index (GSI) using DynamoMapper and class annotations.

Overview of DynamoMapper and Annotations

DynamoMapper: An object mapper for domain-object interaction with DynamoDB, which provides an easy way to convert Java objects into data format suitable for DynamoDB operations.

Annotations: Annotations are a form of metadata and are used in DynamoMapper to define the table schema and indexing configuration directly in the Java class.

Steps to Create a Table with Global Secondary Index Using DynamoMapper

  1. Setup AWS SDK for Java: Ensure that you have the AWS SDK installed. You can include it in your project with a build tool like Maven or Gradle.
xml
1   <!-- Example for Maven dependency -->
2   <dependency>
3       <groupId>com.amazonaws</groupId>
4       <artifactId>aws-java-sdk</artifactId>
5       <version>1.12.500</version> <!-- Use the latest stable version -->
6   </dependency>
  1. Define Your Domain Model with Annotations: To create a table, define a Java class to represent the table's schema. Use annotations to specify attributes, primary keys, and GSIs.
java
1   import com.amazonaws.services.dynamodbv2.datamodeling.*;
2
3   @DynamoDBTable(tableName = "MyTable")
4   public class MyItem {
5
6       private String primaryKey;
7       private String rangeKey;
8       private String secondaryIndexValue;
9
10       @DynamoDBHashKey(attributeName = "PrimaryKey")
11       public String getPrimaryKey() {
12           return primaryKey;
13       }
14
15       public void setPrimaryKey(String primaryKey) {
16           this.primaryKey = primaryKey;
17       }
18
19       @DynamoDBRangeKey(attributeName = "RangeKey")
20       public String getRangeKey() {
21           return rangeKey;
22       }
23
24       public void setRangeKey(String rangeKey) {
25           this.rangeKey = rangeKey;
26       }
27
28       @DynamoDBAttribute(attributeName = "SecondaryIndexValue")
29       @DynamoDBIndexHashKey(globalSecondaryIndexName = "SecondaryIndex")
30       public String getSecondaryIndexValue() {
31           return secondaryIndexValue;
32       }
33
34       public void setSecondaryIndexValue(String secondaryIndexValue) {
35           this.secondaryIndexValue = secondaryIndexValue;
36       }
37   }

In this example, MyItem represents a table with a primary key composed of PrimaryKey and RangeKey attributes. A GSI SecondaryIndex is defined on the SecondaryIndexValue attribute.

  1. Use DynamoDBMapper to Create Tables: With the domain model defined, use the DynamoDBMapper class to perform database operations, including table creation.
java
1   import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
2   import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
3   import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
4   import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig;
5   import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTableMapper;
6   import com.amazonaws.services.dynamodbv2.model.*;
7
8   public class DynamoDBOperations {
9
10       private AmazonDynamoDB client;
11       private DynamoDBMapper mapper;
12
13       public DynamoDBOperations() {
14           client = AmazonDynamoDBClientBuilder.standard().build();
15           mapper = new DynamoDBMapper(client);
16       }
17
18       public void createTableWithGSI() {
19           CreateTableRequest tableRequest = mapper.generateCreateTableRequest(MyItem.class);
20
21           GlobalSecondaryIndex gsi = new GlobalSecondaryIndex()
22                   .withIndexName("SecondaryIndex")
23                   .withProvisionedThroughput(new ProvisionedThroughput(5L, 5L))
24                   .withProjection(new Projection().withProjectionType(ProjectionType.ALL));
25
26           tableRequest.withGlobalSecondaryIndexes(gsi);
27
28           client.createTable(tableRequest);
29       }
30   }

Here, generateCreateTableRequest creates the necessary configuration. The createTableWithGSI method adds a GSI and configures it with desired throughput and projection settings, which in this case include all the attributes.

Considerations for Using Global Secondary Indexes

  • Read and Write Capacity: When creating a GSI, you must specify provisioned throughput that can be scaled independently from the main table. This flexibility allows optimizations based on query needs.
  • Projection Type: Determines the attributes copied to the index. Options include ALL (all attributes), KEYS_ONLY (only keys), and a custom list of attributes.
  • Constraints: Ensure that GSIs align with your application's read patterns, as they incur additional costs and can affect write operations when heavily loaded.

Table: Key Points of Creating Table with GSI

Key ElementDescription
DynamoDBMapperFacilitates Java domain-object and DynamoDB table interactions
Primary Key DefinitionUses @DynamoDBHashKey and @DynamoDBRangeKey annotations for primary key definition
GSI Definition@DynamoDBIndexHashKey annotation used to define an attribute as part of a GSI
Attribute ProjectionOptions include ALL, KEYS_ONLY, or custom attributes
Provisioned ThroughputSeparate configuration for each GSI, set to manage read and write capacity independently
Projection ConfigurationUtilized for determining the non-key attributes that can be queried from the GSI

Conclusion

Creating tables with Global Secondary Indexes in DynamoDB using DynamoMapper and annotations provides a robust method for managing complex query patterns in a NoSQL architecture. By integrating GSIs effectively into your data model, you can achieve scalable, high-performing applications while maintaining the flexibility of querying non-primary key attributes. As always, consider your application's specific workload and access patterns when designing GSIs to ensure optimal use of resources.


Course illustration
Course illustration

All Rights Reserved.