Part 2: Planning the Data Model
Tags: aws, cloud, serverless, database
Published: 2021-01-17 18:48:21

<p>As the first step to creating our blog, we need to create our DynamoDB table that will store all of our content. To prepare to create our DynamoDB table, we will list out all of our data access patterns, so we can select our partition key(s) and sort key(s), and determine if we need to create any additional indexes.</p><p>This is Part 2 of our series on creating a Computeless Blog. &nbsp;If you did not read the introduction, it can be found <a target='_blank' href='https://www.jonholman.com/ComputelessBlog/part-1-introduction'>here</a>.</p><p>To do this, I brainstormed the access patterns I anticipate and came up with this list:</p><ol><li>Get all articles sorted by date</li><li>Get all articles for a category sorted by date</li><li>Get one specific article</li><li>Get all comments for an article</li><li>Get the number of comments for each article</li></ol><p>We will then put these in a table with pk (partition key) and sk (sort key) to identify what keys we will need to query that data.</p><figure class='table'><table><tbody><tr><td><strong>Access Pattern</strong></td><td><strong>PK</strong></td><td><strong>SK</strong></td></tr><tr><td>Get all articles sorted by date</td><td>article</td><td>date</td></tr><tr><td>Get all articles for a category sorted by date</td><td>article</td><td>article path begins with category name</td></tr><tr><td>Get one specific article</td><td>article</td><td>article path</td></tr><tr><td>Get all comments for an article</td><td>comment</td><td>begins with article path</td></tr><tr><td>Get the number of comments for each article</td><td>comment</td><td>&nbsp;</td></tr></tbody></table></figure><p>To satisfy these access patterns, we will create a single DynamoDB table with a partition key and sort key. &nbsp;To avoid locking our partition key and sort key into a specific use case, we will name them generically as pk and sk. &nbsp;That still leaves us without a way to solve the first access pattern 'Get all articles sorted by date' as the articles will have its PK as article and its SK as the article path. &nbsp;We will then add a Local Secondary Index (LSI) to satisfy that access pattern.</p><p>To learn more about data modeling for DynamoDB I recommend:</p><ol><li><a target='_blank' href='https://youtu.be/DIQVJqiSUkE'>Watching Alex DeBrie's talk from AWS re:Invent 2019: Data modeling with Amazon DynamoDB (CMY304)</a></li><li><a target='_blank' href='https://www.alexdebrie.com/posts/dynamodb-single-table/'>Reading Alex DeBrie's post The What, Why, and When of Single-Table Design with DynamoDB</a></li></ol><p>Now let's discuss ReadCapacityUnits (RCU) and WriteCapacityUnits (WCU) on the DynamoDB table. &nbsp;We could set the <code>BillingMode: PAY_PER_REQUEST</code> on our DynamoDB table, to have it scale based on demand, but I do not like not being able to set an upper limit of how high it may go. &nbsp;Like I said in the introduction, I am a very cost conscious person, so I like to have control of these settings. &nbsp;I also really like how DynamoDB's burst capacity works, it's like rollover minutes on a cell phone plan, but instead of last month we're looking at the last 5 minutes. &nbsp;Accumulating the last 5 minutes of unused RCU and WCU we can get some great burst capacity, with a very small RCU and WCU set on the table. &nbsp;With that said, I am going to set each of these to 1 to start and then I'll keep an eye on it.</p><p>Now that we have ironed out the configuration for our DynamoDB table we can move on to defining our DynamoDB table in CloudFormation. &nbsp;Since this will be the first resource we are defining, we will start by creating a folder for our project with a new file named template.yaml. &nbsp;This will be the main file in our AWS SAM project, which will be read first every time we run <code>sam deploy</code>. When reviewing this CloudFormation definition of the DynamoDB table, note that partition key is also known as hash key and sort key is also known as range key.</p>

{% gist https://gist.github.com/JonHolman/930ae48c451679d306ec43a7b55715f1.js %}

<p>Now that the template.yaml file is created, open a terminal and browse to the folder you created for this project. &nbsp;Then run <code>sam deploy --guided</code> and the guided deploy wizard will walk you through all of the settings needed for your deployment. &nbsp;I recommend to answer yes to the prompt 'Save arguments to configuration file', when that configuration file is saved future stack updates can be done by just running <code>sam deploy</code>, the guided wizard will only need to be run again if we add a new parameter or need to change a setting in the saved configuration.</p><p>Now let the SAM deployment run and when it's complete, it will return a message like 'Successfully created/updated stack - [Stack Name] in [AWS Region]'. &nbsp;Our table is now created, to prepare for the next part of this series where we will create an API Gateway endpoint to display a blog post, lets create a sample blog post directly in the DynamoDB table we just created. &nbsp;Open your web browser and log into the AWS console, then browse to DynamoDB (ensure you have the region selected that you specified in <code>sam deploy</code>), select tables on the left sidebar, and then select your new table that will be named the same as the stack name you provided to <code>sam deploy</code>. Now that the new table is selected, on the right side (main content) area select the items tab, and then click the button to Create Item. &nbsp;In the modal window that opens up, in the upper left select the drop down that currently has Tree selected and change the selection to Text, then copy and paste in the sample below and click Save.</p>

{% gist https://gist.github.com/JonHolman/16d7601918348d20bcdcc156a881d48b.js %}

<p>We now have an AWS SAM project that defines a DynamoDB table, we have deployed one stack of this template and created a sample blog post in that table. &nbsp;That's all for this post, thank you for taking the time to read it. &nbsp;Next we will create the article page that will display the sample blog post in to a web browser. &nbsp;If you have any questions or have any suggestions to make this better please leave a comment or reach out via Twitter or LinkedIn and let me know.</p><p>Our project directory at the end of this post is available <a target='_blank' href='https://github.com/JonHolman/ComputelessBlog/tree/part-2-planning-the-data-model'>here</a>.</p><p><a target='_blank' href='https://www.jonholman.com/ComputelessBlog/part-3-adding-api-gateway-and-article-page'>Continue with the next article in this series.</a></p>