DynamoDB M-M Adjacency List Design Pattern
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Amazon DynamoDB is a powerful NoSQL database service designed to handle large-scale data applications with ease. When dealing with complex relationships, especially many-to-many (M-M) relationships, designing the right data model is crucial to ensure high performance and scalability. The adjacency list design pattern is a common approach for representing hierarchical data in a simple, efficient manner. This article will delve into the details of implementing a many-to-many adjacency list pattern in DynamoDB, complete with technical explanations and examples.
Understanding the Adjacency List Pattern
An adjacency list is a collection of unordered lists used to represent a finite graph. Each list describes the set of neighbors of a particular node. In the context of databases, the adjacency list pattern is used to represent related data entities, such as orders related to customers, employees related to departments, or users related to groups.
Many-to-Many Relationships
In a many-to-many relationship, multiple instances of one entity relate to multiple instances of another entity. For example, many students can enroll in many courses, and each course can have many students. This complexity can be elegantly represented using the adjacency list pattern in DynamoDB.
Implementing M-M Adjacency List in DynamoDB
Table Design
When designing a table in DynamoDB for an M-M adjacency list, we usually consider two main entities. For instance, in a student-course scenario, we'd have a StudentCourse table. Here is an example schema:
- Partition Key:
studentId - Sort Key:
courseId - Attributes:
enrollmentDate,status
This simple table design allows us to query all courses a student has enrolled in or find all students enrolled in a course.
Example Data Model
Let's consider a set of students and courses. Here's how the StudentCourse table might look:
| studentId | courseId | enrollmentDate | status |
| S1 | C1 | 2023-01-12 | enrolled |
| S2 | C1 | 2023-01-15 | enrolled |
| S1 | C2 | 2023-02-10 | dropped |
| S3 | C3 | 2023-03-05 | enrolled |
Query Patterns
- Find all courses a student is enrolled in:
- Use
studentIdas the partition key to query. - Example: Query for
studentId = 'S1'returns:C1- enrolledC2- dropped
- Find all students enrolled in a specific course:
- Scan the table or use a secondary index with
courseIdas the partition key.
Secondary Indexes
In some scenarios, Global Secondary Indexes (GSIs) are beneficial. A GSI can be set up with:
- Partition Key:
courseId - Sort Key:
studentId
This facilitates efficient queries to find all students enrolled in a specific course.
Considerations and Best Practices
- Normalization: DynamoDB encourages denormalization, but the adjacency list is a normalized way of storing relationships which can be useful in many contexts.
- Consistency: Use transactions to maintain strong consistency when updating related entities.
- Scalability: With DynamoDB’s automatic scaling, the adjacency pattern supports a high read and write throughput.
- Limitations: While efficient for many queries, complex joins and aggregations might require additional processing or restructuring.
Summary Table
| Aspect | Details |
| Pattern Type | Many-to-Many Adjacency List |
| Primary Entities | Students, Courses |
| DynamoDB Design | Single Table with studentId, courseId as keys |
| Query Patterns | By Student, By Course |
| Indexes | Main Table: studentId (PK), courseId (SK) GSI: courseId (PK), studentId (SK) |
| Pros | Simple, Efficient, Scalable |
| Cons | Limited complex querying capabilities |
Conclusion
The M-M adjacency list design pattern in DynamoDB is a streamlined, effective approach to manage many-to-many relationships. It leverages DynamoDB’s strengths in scalability and performance while maintaining a simplicity that resonates with its NoSQL roots. Properly implemented, it ensures that complex relationship data is stored efficiently, delivering fast query results and supporting high scalability.
Related reading
- DynamoDB mapper and transactions using java SDK
- DynamoDB Mapper annotation for Object which has list of another object
- DynamoDB mapper update only not-null properties
- DynamoDB multi-tenant IAM policy sharing documents with other users
- DynamoDB ordered list
- DynamoDB pagination - last evaluated key is not null on last page
- DynamoDB Scan with filter, matching ''is-in-set'' conditions
- DynamoDB SET list_append not working using aws sdk

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.