Single-table vs multi-table DynamoDB design patterns with GraphQL APIs and AWS AppSync
This article was written by Joe Tronolone, Program Manager Intern, AWS
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, giving clients the power to ask for exactly what they need and nothing more. AWS AppSync is a fully managed GraphQL and Pub/Sub API service that provides users the ability to connect to different data sources such as AWS Lambda, Amazon Aurora, Amazon OpenSearch and Amazon DynamoDB. DynamoDB is a fully managed, serverless, key-value NoSQL database designed to run high-performance applications at any scale. It is commonly used for serverless applications due to its consistent performance, pay-per-use billing model, and HTTP-based connection model. There are two approaches when integrating DynamoDB with GraphQL: multi-table and single-table. In this article we provide a quick summary on these approaches.
As a NoSQL database, DynamoDB opens up the possibility of using data modeling patterns that are different from those commonly used with traditional RDBMS databases. One such pattern is to include multiple different types of entities in a single DynamoDB table, which is often referred to as “single-table design.” The answer to if single-table design or multi-table design is the best one for you really comes down to your business’ needs. Let’s break down the positives and negatives for each, as well as how they work.
- More flexible and straight forward (+)
- Higher Latency due to sequential requests (-)
When you are building a new application and are not yet settled on defined data access patterns, a strategy with multiple tables is more flexible. With multi-table designs, a separate DynamoDB table is created for each core object type in the GraphQL schema. This means that each resolver only focuses on retrieving one object at a time in sequential requests. Structurally, this is more similar to a traditional RDBMS table structure. Note, however, that DynamoDB does not include RDBMS operations like joins that allow you to combine multiple tables in a query.
If you find that a specific object needs to be retrieved independent of other data, then a multi-table design could be the right choice for you. For more information watch a 10 minute multi-table video walk-through here: How to use multiple DynamoDB tables with GraphQL
- Lower Latency (+)
- More Complexity in the GraphQL Resolver Logic (-)
With Single-table designs, all objects are contained within one table. By combining multiple object types in a single table, you can emulate a SQL join operation by grouping related items together with the same partition key. In this way, you get the consistent performance of DynamoDB while still retrieving heterogeneous items in a single request. It is the best option if you know well the data access patterns, settled on a data model, and have certain scale requirements that need to be optimized.
If you find that your data is mostly retrieved together, then a single-table design could be the best option. Watch a 10 minute single-table video walk-through here: How to use single-table DynamoDB design with GraphQL
Combination of single and multi-table
Even though these designs differ from each other, it is possible to combine them to increase simplicity, flexibility, and latency for your application. Take for example a multi-table user who has a large number of entities. They may want to bundle a few related entities into multiple single tables to reduce latency. But as stated before, it all comes down to how well-known the data access patterns are and your specific business needs.
To find examples and in-depth details on these different options, check out the full guide on How to design an Amazon DynamoDB data model for a GraphQL API.