🌐
GitHub
github.com › aws-samples › amazon-dynamodb-design-patterns
GitHub - aws-samples/amazon-dynamodb-design-patterns: This repo contains sample data models to demonstrate design patterns for Amazon DynamoDB. · GitHub
This repo contains sample data models to demonstrate design patterns for Amazon DynamoDB. - aws-samples/amazon-dynamodb-design-patterns
Starred by 249 users
Forked by 46 users
🌐
AWS
docs.aws.amazon.com › amazon dynamodb › developer guide › data modeling for dynamodb tables › best practices for modeling relational data in dynamodb › example of modeling relational data in dynamodb
Example of modeling relational data in DynamoDB - Amazon DynamoDB
4 weeks ago - This example demonstrates how to model relational data in Amazon DynamoDB using entity types, compound primary keys, and global secondary indexes to support various access patterns efficiently.
Discussions

amazon web services - How to design a DynamoDB table schema - Stack Overflow
I am doing my best to understand DynamoDB data modeling but I am struggling. I am looking for some help to build off what I have now. I feel like I have fairly simple data but it's not coming to me... More on stackoverflow.com
🌐 stackoverflow.com
Simplest dynamodb schema for modeling a very basic account balance sheet?
Hello and welcome to the world of DynamoDB and NoSQL databases! I'm gonna walk you through a schema that I've given at least some thought to that might work for such a scenario. Before I begin, I should preface this by saying that I am by no means a NoSQL design expert--I hardly even consider myself a novice. What that means is that the schema I come up with almost certainly isn't the best schema to use (and is probably on the lower end of the quality scale); regardless, it makes sense to me so it's what I'll use. NoSQL databases are really good at certain queries but otherwise terrible at others. Thus, you absolutely need to know your access patterns before designing your schema. After looking up what a balance sheet is, I determined these probable access patterns: Current company assets Current company liabilities Current company owner equity Notice how I say "current" in all of these access patterns; recording historical data would effectively require snapshotting the data (at least based on the schema I came up with) in some way; how you achieve this would be up to you. Regardless, assuming this is all for one company (i.e., the company is making an internal tool for tracking their financials), we'll be using a Composite Primary Key. A Primary Key is basically the one and only actually unique value of your DynamoDB table, and it serves as the identifier for any given record within your DynamoDB table. A Composite Primary Key basically means that instead of containing only one attribute that must be unique (the Partition Key), the Primary Key is made up of two attributes that together must be unique (a Partition Key and Sort Key). Your Primary Key is going to consist of a Partition Key that is the "type" of the transaction (whether it is an asset, liability, or owner/shareholder equity) and a Sort Key that consists of the following: Transaction category (i.e., current assets, other assets, etc.) Transaction subcategory (i.e., cash within current assets, etc.) Transaction date and time (for this you can go as granular as you wish, but I would suggest at least hourly because otherwise you severely limit yourself in when transactions can happen, which you can't control; for my purposes, I will go down to the minute.) As an example, if I have a current cash asset that I added on November 5th, 2020 at 21:05 (9:05 PM), it's Primary Key would look like this: Primary Key: Asset Sort Key: Current Asset#Cash#2020#11#05#21#05 In my Sort Key, notice how I've divided each part of the Sort Key using hashtags/pound symbols ("#"). When used in a Sort Key, these are akin to the "/" (or "\") symbol used to designate each level within a file directory (i.e., C:\Users\tycoon\Desktop\hello world.txt). Technically speaking, I don't need to use the hashtags to separate each part of the Sort Key, but doing so makes it much easier to identify each part of the Sort Key (and allows you to use the Sort Key as part of your actual data storage, simply by splitting the string on each hashtag). Because I've used a Primary Key that's structured like this, it allows me to "natively" do the following queries: All transactions of a certain type (i.e., all assets or all liabilities) All transactions of a certain category within a certain type (i.e., all "current assets" within our assets) All transactions of a certain subcategory that are within a certain category and certain type (i.e., all cash transactions that deal with our current assets and are a part of our assets.) All transactions of a certain date and/or time (though the time must include the date; you cannot query for all transactions that occurred at 11:00 on any day of the month) that are within a certain subcategory, category, and type (i.e., all transactions that have occurred between 21:00 and 21:59 on November 5th, 2020, that have to do with cash within our current assets). Since this is storing transactions, I'll assume you at the very least want to store the following attributes: Payer (the entity sending the asset) Payee (the entity receiving the asset; aka the recipient) Asset Value Asset Type Assets Transferred (this can be an internal ID, a name; basically, a thing that help you identify what exactly was transferred) With the previous in mind, you can create two Global Secondary Indexes for your DynamoDB table. Global Secondary Indexes (aka "GSI"s) allow you to query any value stored as the GSI's Primary Key similarly to the actual DynamoDB table; this is at the cost of increased storage usage and increased read and write capacity usage. GSIs function similarly to root DynamoDB tables, but aren't entirely the same as creating a second DynamoDB table. Regardless, you can create a few GSIs, depending on what you'll likely need to access: One GSI with the Payer as its Primary Key and Payee as its Sort Key One GSI with the Payee as its Primary Key and Payer as its Sort Key One GSI with the Asset Type as its Primary Key (optionally, GSIs with Asset Type as its Partition Key and then Payer and Payee (individually) as their Sort Keys would also be an option, if you predict you'd need to get all assets where you were the payer, etc.) Assuming you create at least the first two GSIs I told you about, you can now also do the following queries: Transactions where you were the Payer Transactions where you were the Payer and "Company A" was the Payee Transactions where you were the Payee Transactions where you were the Payee and "Company A" was the Payer You might notice in our GSIs that records are probably not going to be unique, and that's OK. Unlike the root DynamoDB table, records in GSIs do not need to have unique Primary Keys. If you query for a Primary key that would result in multiple records under that GSI, then the GSI will simply return all the records it has that fit the Primary Key you provided. Due to our GSI schema, this does have the side effect that you can't query for specific transactions between two entities. If you wanted to add the balance before and after any given transaction, you'll want to implement data aggregation. I won't get into the specifics of how to accomplish this, but one way of doing this is basically you start at $0 of assets and every time a transaction is completed, you take your total asset count and, if the transaction is an asset, add the value of the asset to the total, otherwise if the transaction is a liability, subtract the value of the asset from the total, and then store these values in the table under, for example, the "Total" Partition Key and "Total" Sort Key (remember, this is a NoSQL database, so no need to store the same things in each record). Alrighty, well, assuming I didn't miss anything, that's how I approached the problem you proposed. As much as this is a learning experience for you, this was (despite the fact that I typed this out for about an hour) quite fun for me to do as I love DynamoDB and have rather recently figured out better ways of data modeling and schema design within DynamoDB (though I still don't even consider myself a novice really). This was a great challenge for me to do that I hope you learn something from. NoSQL is really very different from a traditional relational database and associated RDBMS, and it definitely takes some learning to realize the power of NoSQL databases, as you basically have to "unlearn" everything you learned whilst figuring out traditional relational databases. However, NoSQL databases can be great for many projects and many use cases; it's just a matter of choosing the right one for the job. If you're curious about me, I have started with NoSQL databases, specifically DynamoDB since I went straight into AWS (as much as I probably shouldn't have...especially now that I say that "I love AWS a little too much"); thus, most of my experience is with DynamoDB and I have comparatively little experience with traditional SQL databases. Regardless, if you have any questions for me, feel free to ask them in a reply to this comment! I'll do my best to answer them as best I can. Happy coding, and happy learning! P.S. If you're wondering how many of these absolutely ridiculously long posts I've made (all in my attempt to help people learn AWS), then that number is more than I'd like to admit. You're free to look at my post history to see just how many times I've posted giant comments like this. :3 More on reddit.com
🌐 r/aws
5
1
November 6, 2020
Dynamo DB Schema
DynamoDb requires that you set up the key-schema and the attribute-definitions for those fields. Here you can see the required fields and how to provide them: https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html#synopsis One thing I should caution, if you're just getting started, definitely check out the talks by Rick Houlihan https://www.youtube.com/watch?v=6yqfmXiZTlM More on reddit.com
🌐 r/aws
7
1
November 16, 2020
DynamoDB Single Table Deign: Simple Guide To Modeling & Querying On To Many Relationships. (Using Excel to plan out the queries)
One of the things that I hear about single table design is that you need to understand all your access patterns up front. But rarely do requirements come up front. Agile (putting aside the cargo cult) is often executed in a way that reacts to changing demands and this seems to be an admission of flawed requirements, or information that only comes later. With the extra cognitive load of planning a single table design I feel like it’s going to optimise RCU at the cost of refactoring exercises down the track. But I’d be happy to understand opposing points of view. More on reddit.com
🌐 r/aws
12
66
October 3, 2022
🌐
GitHub
github.com › aws-samples › aws-dynamodb-examples › blob › master › schema_design › README.md
aws-dynamodb-examples/schema_design/README.md at master · aws-samples/aws-dynamodb-examples
Designing an efficient and scalable data model is crucial when working with Amazon DynamoDB. This folder contains a collection of schema design patterns and best practices that you can leverage in your DynamoDB table implementations.
Author   aws-samples
🌐
AWS
docs.aws.amazon.com › amazon dynamodb › developer guide › dynamodb appendix › example tables and data for use in dynamodb
Example tables and data for use in DynamoDB - Amazon DynamoDB
This section presents sample tables and data for the DynamoDB Developer Guide, including the ProductCatalog, Forum, Thread, and Reply tables with their primary keys. It also includes information on a global secondary index for the Reply table and references to the Getting Started section for ...
🌐
AWS
aws.amazon.com › blogs › database › amazon-dynamodb-schema-from-the-prism-of-sql
Amazon DynamoDB schema from the prism of SQL | AWS Database Blog
November 1, 2022 - In this post, you learned a way ... that into DynamoDB schema design. You also learned some ways to map a SQL query to a DynamoDB table and GSI partition and sort keys. I showed you schema design using NoSQL workbench and corresponding SQL-like queries using PartiQL This approach can help you design your DynamoDB schema from the perspective of SQL. Soumyadeep Dey is a Database Specialist Solutions Architect with Amazon Web Services (AWS)...
🌐
GitHub
github.com › aws-samples › aws-dynamodb-examples
GitHub - aws-samples/aws-dynamodb-examples: DynamoDB Examples · GitHub
📂 examples: Includes sample scripts and integrations, with subfolders for each category, such as SDK examples. 🗁 infrastructure_as_code: Contains templates for deploying DynamoDB resources to AWS. 🗂 schema_design: A collection of schema design patterns for DynamoDB table implementations.
Author   aws-samples
🌐
OneUptime
oneuptime.com › home › blog › how to design dynamodb table schemas
How to Design DynamoDB Table Schemas
January 26, 2026 - Single table design is a pattern where you store multiple entity types in one table. This reduces the number of round trips to the database and simplifies your application. erDiagram SINGLE_TABLE { string PK "Partition Key" string SK "Sort Key" string GSI1PK "GSI1 Partition Key" string GSI1SK "GSI1 Sort Key" string entityType "USER|ORDER|ITEM" json attributes "Entity-specific data" } const { DynamoDBClient, PutItemCommand, QueryCommand } = require('@aws-sdk/client-dynamodb'); const { marshall, unmarshall } = require('@aws-sdk/util-dynamodb'); const client = new DynamoDBClient({ region: 'us-eas
Find elsewhere
🌐
AWS
docs.aws.amazon.com › amazon dynamodb › developer guide › data modeling for dynamodb tables › data modeling schema design packages in dynamodb › social network schema design in dynamodb
Social network schema design in DynamoDB - Amazon DynamoDB
Learn how to design a social network system using DynamoDB. Learn about its use case, access patterns, how to achieve the access patterns, and then what the final schema will look like. The design leverages DynamoDB's single-table approach to address various access patterns efficiently.
🌐
AWS
docs.aws.amazon.com › amazon dynamodb › developer guide › data modeling for dynamodb tables
Data modeling for DynamoDB tables - Amazon DynamoDB
Explore best practices for designing flexible and optimized DynamoDB schemas, including single vs. multiple table design, key schema patterns, and secondary indexes. Discover schema design approaches for various use cases and industries.
🌐
AWS
docs.aws.amazon.com › amazon dynamodb › developer guide › best practices for designing and architecting with dynamodb
Best practices for designing and architecting with DynamoDB - Amazon DynamoDB
1 month ago - Learn about best practices for designing and architecting with Amazon DynamoDB, a NoSQL database service. This page covers key differences between relational and NoSQL design, two key concepts for NoSQL design, and a general approach to NoSQL design. Receive specific guidance on partitions, ...
🌐
DbSchema
dbschema.com › blog › design › visual dynamodb design and documentation with dbschema
Visual DynamoDB Design and Documentation with DbSchema
January 12, 2026 - Amazon DynamoDB is fast and scalable, ... see the schema visually. DbSchema brings a new perspective: you can design DynamoDB visually, edit data directly, and even generate HTML5 documentation or work in teams using Git. ... Connect DbSchema to your AWS DynamoDB account, and it automatically reads your existing tables, showing them as clear diagrams with key icons and attribute types. You can also start from scratch, creating new tables visually without writing any JSON. Here’s an example database for ...
Top answer
1 of 1
3

Looking at your access patterns, this is a possible table design. I'm not sure if it's going to really work with your TimeId, especially for the Local Secondary Index (see note below), but I hope it's a good starting point for you.

# Table
-----------------------------------------------------------
pk       | sk                   | value | other attributes
-----------------------------------------------------------
TimeId   | GAME#TEAM{teamname}  | true  | ...
TimeId   | STATS#TEAM{teamname} |       | ...
GameId   | GAME                 |       | general game data (*)
TeamName | TEAM                 |       | general team data (*)
 
# Local Secondary Index
-------------------------------------------------------------------------------
pk from Table as pk | value from Table as sk | sk from Table + other attributes
-------------------------------------------------------------------------------
TimeId              | true                   | GAME#Team{teamname} | ...

With this Table and Local Secondary Index you can satisfy all access patterns with the following queries:

  1. Retrieve all games by timeId:

    Query Table with pk: {timeId}

  2. Retrieve all games per timeId and by TeamName

    Query table with pk: {timeId}, sk: GAME#TEAM{teamname}

  3. Retrieve all games per timeId and if value = true

    Query LSI with pk: {timeId}, sk: true

  4. Retrieve all teamStats per timeId

    Query table with pk: {timeId}, sk: begins with 'STATS'

  5. Retrieve all teamStats by timeId and TeamName

    Query table with pk: {timeId}, sk: STATS#TEAM{teamname}

*: I've also added the following two items, as I assume that there are cases where you want to retrieve general information about a specific game or team as well. This is just an assumption based on my experience and might be unnecessary in your case:

  1. Retrieve general game information

    Query table with pk: {GameId}

  2. Retrieve general team information

    Query table with pk: {TeamName}

Note: I don't know what value = true stands for, but for the secondary index to work in my model, you need to make sure that each combination of pk = TimeId and value = true is unique.

To learn more about single-table design on DynamoDB, please read Alex DeBrie's excellent article The What, Why, and When of Single-Table Design with DynamoDB.

🌐
Amazonaws
rh-web-bucket.s3.amazonaws.com › index.html
DynamoDB Data Modeler
See 'Editing Schema' section below for details. Click the sliders '' control to switch back to 'values view' and edit attribute values. ... The following image shows a data model for tracking patients, room assignments, and treatments for a hospital resource scheduling service originally created in NoSQL Workbench for DynamoDB (Hospital.json):
🌐
DynamoDB
dynobase.dev › dynamodb-table-schema-design-tool
DynamoDB Table Schema Design Tool [Free to Use]
Most popular ways include AWS Console, AWS SDKs, AWS CLI, CloudFormation, Terraform, Serverless Framework, AWS SAM (Serverless Application Model) and of course Dynobase. The tool on this page is also available inside Dynobase. When using SDK or CLI, you need to use it as the table definition parameter when calling CreateTable operation. When using CloudFormation, SAM or Serverless Framework, paste this into your 'infrastructure-as-code' DynamoDB::Table.Properties value
🌐
Reddit
reddit.com › r/aws › simplest dynamodb schema for modeling a very basic account balance sheet?
r/aws on Reddit: Simplest dynamodb schema for modeling a very basic account balance sheet?
November 6, 2020 -

I have a little experience with postgres, but none with document or noSQL databases, and want to dip my toes in the dynamodb pond. I've skimmed some docs/online resources, but it's not obvious to me what is the simplest but still "proper" way to build out something like a very basic balance sheet tracker. Could it be as basic as a bunch of identically shaped "transaction" items with attributes for id, transaction amount, new balance, date, type, memo section (and possibly others)? Ideally I'd like to sort/search transactions by date, and amount, but probably other attributes as well. Would the search/sorting of additional attributes involve significantly more complexity?

Top answer
1 of 2
4
Hello and welcome to the world of DynamoDB and NoSQL databases! I'm gonna walk you through a schema that I've given at least some thought to that might work for such a scenario. Before I begin, I should preface this by saying that I am by no means a NoSQL design expert--I hardly even consider myself a novice. What that means is that the schema I come up with almost certainly isn't the best schema to use (and is probably on the lower end of the quality scale); regardless, it makes sense to me so it's what I'll use. NoSQL databases are really good at certain queries but otherwise terrible at others. Thus, you absolutely need to know your access patterns before designing your schema. After looking up what a balance sheet is, I determined these probable access patterns: Current company assets Current company liabilities Current company owner equity Notice how I say "current" in all of these access patterns; recording historical data would effectively require snapshotting the data (at least based on the schema I came up with) in some way; how you achieve this would be up to you. Regardless, assuming this is all for one company (i.e., the company is making an internal tool for tracking their financials), we'll be using a Composite Primary Key. A Primary Key is basically the one and only actually unique value of your DynamoDB table, and it serves as the identifier for any given record within your DynamoDB table. A Composite Primary Key basically means that instead of containing only one attribute that must be unique (the Partition Key), the Primary Key is made up of two attributes that together must be unique (a Partition Key and Sort Key). Your Primary Key is going to consist of a Partition Key that is the "type" of the transaction (whether it is an asset, liability, or owner/shareholder equity) and a Sort Key that consists of the following: Transaction category (i.e., current assets, other assets, etc.) Transaction subcategory (i.e., cash within current assets, etc.) Transaction date and time (for this you can go as granular as you wish, but I would suggest at least hourly because otherwise you severely limit yourself in when transactions can happen, which you can't control; for my purposes, I will go down to the minute.) As an example, if I have a current cash asset that I added on November 5th, 2020 at 21:05 (9:05 PM), it's Primary Key would look like this: Primary Key: Asset Sort Key: Current Asset#Cash#2020#11#05#21#05 In my Sort Key, notice how I've divided each part of the Sort Key using hashtags/pound symbols ("#"). When used in a Sort Key, these are akin to the "/" (or "\") symbol used to designate each level within a file directory (i.e., C:\Users\tycoon\Desktop\hello world.txt). Technically speaking, I don't need to use the hashtags to separate each part of the Sort Key, but doing so makes it much easier to identify each part of the Sort Key (and allows you to use the Sort Key as part of your actual data storage, simply by splitting the string on each hashtag). Because I've used a Primary Key that's structured like this, it allows me to "natively" do the following queries: All transactions of a certain type (i.e., all assets or all liabilities) All transactions of a certain category within a certain type (i.e., all "current assets" within our assets) All transactions of a certain subcategory that are within a certain category and certain type (i.e., all cash transactions that deal with our current assets and are a part of our assets.) All transactions of a certain date and/or time (though the time must include the date; you cannot query for all transactions that occurred at 11:00 on any day of the month) that are within a certain subcategory, category, and type (i.e., all transactions that have occurred between 21:00 and 21:59 on November 5th, 2020, that have to do with cash within our current assets). Since this is storing transactions, I'll assume you at the very least want to store the following attributes: Payer (the entity sending the asset) Payee (the entity receiving the asset; aka the recipient) Asset Value Asset Type Assets Transferred (this can be an internal ID, a name; basically, a thing that help you identify what exactly was transferred) With the previous in mind, you can create two Global Secondary Indexes for your DynamoDB table. Global Secondary Indexes (aka "GSI"s) allow you to query any value stored as the GSI's Primary Key similarly to the actual DynamoDB table; this is at the cost of increased storage usage and increased read and write capacity usage. GSIs function similarly to root DynamoDB tables, but aren't entirely the same as creating a second DynamoDB table. Regardless, you can create a few GSIs, depending on what you'll likely need to access: One GSI with the Payer as its Primary Key and Payee as its Sort Key One GSI with the Payee as its Primary Key and Payer as its Sort Key One GSI with the Asset Type as its Primary Key (optionally, GSIs with Asset Type as its Partition Key and then Payer and Payee (individually) as their Sort Keys would also be an option, if you predict you'd need to get all assets where you were the payer, etc.) Assuming you create at least the first two GSIs I told you about, you can now also do the following queries: Transactions where you were the Payer Transactions where you were the Payer and "Company A" was the Payee Transactions where you were the Payee Transactions where you were the Payee and "Company A" was the Payer You might notice in our GSIs that records are probably not going to be unique, and that's OK. Unlike the root DynamoDB table, records in GSIs do not need to have unique Primary Keys. If you query for a Primary key that would result in multiple records under that GSI, then the GSI will simply return all the records it has that fit the Primary Key you provided. Due to our GSI schema, this does have the side effect that you can't query for specific transactions between two entities. If you wanted to add the balance before and after any given transaction, you'll want to implement data aggregation. I won't get into the specifics of how to accomplish this, but one way of doing this is basically you start at $0 of assets and every time a transaction is completed, you take your total asset count and, if the transaction is an asset, add the value of the asset to the total, otherwise if the transaction is a liability, subtract the value of the asset from the total, and then store these values in the table under, for example, the "Total" Partition Key and "Total" Sort Key (remember, this is a NoSQL database, so no need to store the same things in each record). Alrighty, well, assuming I didn't miss anything, that's how I approached the problem you proposed. As much as this is a learning experience for you, this was (despite the fact that I typed this out for about an hour) quite fun for me to do as I love DynamoDB and have rather recently figured out better ways of data modeling and schema design within DynamoDB (though I still don't even consider myself a novice really). This was a great challenge for me to do that I hope you learn something from. NoSQL is really very different from a traditional relational database and associated RDBMS, and it definitely takes some learning to realize the power of NoSQL databases, as you basically have to "unlearn" everything you learned whilst figuring out traditional relational databases. However, NoSQL databases can be great for many projects and many use cases; it's just a matter of choosing the right one for the job. If you're curious about me, I have started with NoSQL databases, specifically DynamoDB since I went straight into AWS (as much as I probably shouldn't have...especially now that I say that "I love AWS a little too much"); thus, most of my experience is with DynamoDB and I have comparatively little experience with traditional SQL databases. Regardless, if you have any questions for me, feel free to ask them in a reply to this comment! I'll do my best to answer them as best I can. Happy coding, and happy learning! P.S. If you're wondering how many of these absolutely ridiculously long posts I've made (all in my attempt to help people learn AWS), then that number is more than I'd like to admit. You're free to look at my post history to see just how many times I've posted giant comments like this. :3
2 of 2
1
The first rule is that you always want to know your access patterns in advance. The second rule is that you never want to query on any attribute (database field) that isn’t part of either a primary key, a local secondary index or a global secondary index. The third rule is that if you want to do any type of aggregations - sum, average, group by, etc. you don’t want to use DynamoDB.
🌐
Simple AWS
newsletter.simpleaws.dev › simple aws › dynamodb database design
Database Design in Amazon DynamoDB
January 12, 2026 - You can read more on LSIs and GSIs on our previous Simple AWS issue on DynamoDB. Use model ECommerce-6.json for this step. An example query would be (on GSI1): PK="p#99887" and SK between "2023-04-25T00:00:00" and "2023-04-25T23:59:00"
🌐
Reddit
reddit.com › r/aws › dynamo db schema
r/aws on Reddit: Dynamo DB Schema
November 16, 2020 -

Hiya

So I'm looking at Dynamo DB because it's a requirement for a project we're working on.

As I understand it - Dynamo is NoSQL/Schemaless which is cool and what we want.

What doesn't make sense is that when creating a table I have to specify a schema and definitions.

ie -

aws dynamodb create-table --table-name blah

returns

the following arguments are required: --attribute-definitions, --key-schema

Anyone able to shed some light on what's up here?

Cheers!