AWS Bites Podcast

123. What do you need to know about DynamoDB?

In this episode, we provide a comprehensive overview of DynamoDB, including how it compares to relational databases, when to use it, how to get started, writing and querying data, secondary indexes, and single table design. We share our experiences using DynamoDB and discuss the pros and cons compared to traditional SQL databases.

AWS Bites is brought to you by fourTheorem. If you need someone to work with you to build the best-designed, highly available database on AWS, give us a shout. Check us out on fourtheorem.com!

In this episode, we mentioned the following resources.

Let's talk!

Do you agree with our opinions? Do you have interesting AWS questions you'd like us to chat about? Leave a comment on YouTube or connect with us on:

00:03:50

And one of the main points of most NoSQL products is that they are schema-less. So that means that when you store data, you store it in a set, for lack of a better word, let's just call it a set, like one place where you put all your data and different records in that set can contain a different structure of data. So you can have different fields. That's what we mean by schema-less. You don't have to think in advance about a schema that will fulfill all the records that you want to put in that particular set, but every single item can have its own properties. And another interesting point is that generally NoSQL products will be a little bit more relaxed when it comes to ACID compliance. With ACID, we mean atomic consistent, isolated, and durable, which is a property that most relational database will try to guarantee. In NoSQL databases, generally, the producers are concerned about performance and making sure that the data can be easily distributed across multiple nodes. So there are some trade-offs that are made where generally, for instance, what NoSQL producers will do, they will give up on the idea of consistency and favor eventual consistency so that it's easier for them to be able to distribute the data in a durable way across multiple partitions. And the final point is that with NoSQL databases, you generally worry a lot less about storage cost. And this is probably because it's a much modern version of databases. So storage is a bit less of a problem since the 70s. So there is a lot more freedom to use storage in ways where you might end up duplicating data. But once you do that, you might be able to access that data much faster in some access patterns. If you want to think about what is the simplest NoSQL database that you can imagine, you can just think about a key value storage. So imagine you have a map in any programming language where you can start key value pairs. And you can imagine that the key is basically the thing that allows you to access records univocally. And then inside the value, you can store complex objects of any kinds with multiple attributes. And they can all be different between every record. And it's also worth mentioning that this is not necessarily the same thing when we mentioned document databases. You might have heard of MongoDB, which is generally classified as a document database because document-oriented databases are more of an extension of the key value concept. They tend to have a little bit of a more structured format and a more expressive query language. So when we talk about NoSQL, and especially in the context of DynamoDB, we are talking about something that maybe can be a little bit simpler than products like MongoDB. Hopefully that gives you a good introduction to the world of NoSQL and what we mean by NoSQL and how does it compare with relational databases. So let's now talk about specifically DynamoDB. Eoin, where do we start?

00:07:46

So that's your key. And then your value is composed of attributes. You can have multiple attributes in each item, as you mentioned already, and an attribute has a name and a value. It's a little bit different to the document storage option or just a simple key value storage option, where you have a single value or you have a document with awareness of the structure. In DynamoDB, you can have multiple attributes and each of those could be like a little document, but in a very unstructured way. There's a number of different types supported. It's worthwhile understanding what types are supported, especially when it gets into the multi-value types. So the simple values types, the literals you can store are string, number. You can also store binary data as a type. And then you have lists, maps, and sets. If you just write kind of JSON type data into an attribute, that's a map, a list is an array, and then you have sets where you don't get duplicate values. And you have three different types of sets supported. So you have string sets, number sets, and binary sets. And we'll talk a little bit more about how you use those. There is also a null type that's quite rarely used. Now it is important to note that unlike a lot of databases, the maximum item size in DynamoDB is 400 kilobytes. It's important to note that this is per item, right? For the whole record, not just per attribute. You might think this is a small comparison to like Cassandra or MongoDB, which lets you store gigabytes in records, but there's a lot of limitations like this in DynamoDB, which are there for a very good reason. And they're there because it helps them to deliver on the massive performance and scalability guarantees that they provide. So it seems sometimes working with DynamoDB that it's almost like working with a low level database engine because they're strict about giving you a limited set of features so that they can give you those guarantees in return. So if you want more data than 400 KB per item, it's difficult to offload that into an S3 object. So maybe before we start diving into more technical details, let's go up a level. Why and when would you use DynamoDB?

00:13:44

Conversely, we say that DynamoDB is really good for startup environments because the pricing dynamics will scale with the growth of your company. But on the other end, you have to consider that DynamoDB requires you to understand really, really well the way you'd need to access the data. And when you're building a startup, sometimes you need to pivot multiple times before you figure out exactly what's your product market fit, what's the product that is really solving a problem for your customers. So you're going to go through significant different iterations of your product. And as such, you're probably going to change the way you use the data in your database multiple times. DynamoDB might not be the best database for that. It will require you a lot of hard work to always adjust changes to the structure of your database, change it to the way you query the data. Something like a relational database might be much more suitable for that kind of thing because with the flexibility of SQL, as long as you're keeping your data normalized, then you can easily adjust for different access patterns. So definitely worth considering if you don't really think you understand well your current and future access patterns, DynamoDB might create a little bit of friction for the evolution of your product. Other reasons why you might not want to use DynamoDB is, for instance, when you need to integrate with other systems that expect a SQL interface. DynamoDB is not going to give you a SQL interface or at least not a traditional one. So definitely it will make your life much harder if you need to integrate with something that is expecting SQL as a language. Another case is when you might have lots of relational data by nature. So you really need to use features like join and join data across multiple tables. That's not even something that is supported in DynamoDB natively. So you will need to do your own joins with code inside your application. And that's something that is not going to be very efficient and it's going to be very tricky to do well and to scale it. And finally, if you, for whatever reason, need to manage a database by yourself, like you need to host it yourself and run it yourself in your data center or even inside your own cloud account, DynamoDB doesn't offer that option. DynamoDB is only a managed service. Amazon will give you a single node local version that you can use and run it yourself, but that's meant to be used only for local testing and development, not to be run in production. Now, I think at this point, it might be very beneficial to try to explain a little bit more how DynamoDB works, because I think that is going to demystify why there are so many constraints, but at the same time also why DynamoDB can be so effective and performant in certain use cases.

00:17:37

One RCU will allow you a strongly consistent or two eventually consistent reads per second, and they can be up to four kilobytes. And a write capacity unit allows you to write one item up to one kilobyte. You have two pricing options. You've got provisioned mode where you can say, okay, I'm going to need 500 RCUs and 500 WCUs. And then you pay a fixed amount per hour as long as the table exists. The newer mode, which is more serverless is the on demand capacity. And that will scale the WCUs and RCUs up and down for you. If you don't use them, you don't pay. But if you do use them, the cost is generally higher than provisioned capacity. So you need to measure your own workload and decide which one works. Generally, we'd say start with on demand capacity, measure how much you're using, look at your bill and optimize accordingly. And the good news there actually is that I think just last week, AWS released a new feature, which will allow you to cap the maximum on demand capacity. So you can manage that maximum cost and don't have to lie awake at night worrying about it. Now, when we talk about partitions, you might have heard the concept of hot partitions, especially if you're reading older blog posts or content where your throughput could suffer if you didn't actually evenly distribute the partition keys across your whole data set. And if you do read anything like that, don't worry, because Amazon has since added an adaptive capacity feature a few years ago that automatically solves that for you. So they'll manage capacity according to the size of the partition keys on different nodes. But it is still important to note that each partition does have a maximum throughput. So it's 3000 RCUs or 1000 WCUs. So if you are going to have a lot of traffic, you should make sure that you're not just using a small number of partition keys. And that will allow you to ensure that you get consistent performance across all of your data. So I think partitions, they're basically the fundamental concept to understand. We've talked about strong consistency and eventual consistency. Let's talk more practically, how do you get started and what you do to start using DynamoDB?

00:20:00

When it comes to the SDK, there are actually two different types of client. And this is something that sometimes can be a little bit confusing, but the idea is that you have clients at two different levels. You have the main DynamoDB client where you still need to understand a little bit what is the protocol when it comes to specifying the different types of values that you need to read and write. Instead, when you use the Document client, that type of client is generally a little bit more integrated with your programming language of choice. It can understand the types directly from the type that you express in your programming language, and it's going to do an implicit conversion behind the scenes for you. So if you are trying to put a string, for instance, in an attribute, it's going to automatically create the correct shape of the object that the underlying client expects to say that that value is going to be persisted in DynamoDB as a string and not, for instance, as another data type. So generally speaking, I would recommend to use the Document client because it will make your life a little bit easier, and it will abstract some details that you don't necessarily have to worry about when it comes to the underlying protocol of DynamoDB. Let's talk a little bit more about how do you write data, what kind of options do you have there, and all the right actions that you need to do, as Eoin, you mentioned before, force you to provide the full primary key. So you need to explicitly say, this is the primary key that I'm going to be used to store this particular record or to update a particular record.

00:23:14

And finally, you can also use the transact write item, which allows you to write data as part of a transaction. And the other thing is that when you write something into DynamoDB, so when you do an update operation, you might be interested in receiving a response from DynamoDB, and you can actually specify what kind of response you want to get back from DynamoDB. So different options are, for instance, if you don't really care about anything, you can just say, no, just write the data, I don't care about the result of that operation. Then, for instance, when you're doing updates, it can be very interesting to know what was updated. So you have options like all old, or updated old, or all new, or updated new, that will allow you to select a subset of the data that was actually updated and compare it with the previous data. And going back to the case of the counter, if you want to say, for instance, increase this particular attribute by one, you don't necessarily know what's going to be the final value, because maybe you didn't read the value in the first place, or maybe the value that you have right now in memory in your program is outdated, because meanwhile, there have been other increases from other concurrent executions, you can get the new value as a response from your update operation when you select one of these attributes. So that can be a convenient use case. For instance, if you are building some kind of counter, increase the value, and you want to know what's the most recent count in your program.

00:26:31

So you need to be very careful depending on the type of queries that you expect to do in structuring your keys so that the query operation allows you to do the queries that you need to do. And you can also use filter expressions, which are a little bit more flexible and they can be applied to any attribute, not just the primary key and the secondary key. And these filters are a little bit funny. They work in a way that you might not expect the first time you use them, because if you're using again to SQL, the filtering happens at the database level where the database is just going to give you the data that matches the conditions that you are looking for and ignore everything else. While here with DynamoDB, when you use filter expressions, you are actually still getting all the data, effectively discarding the records that don't match that particular filter expression. Finally, each query has one megabyte read limit. If you need to read more, you need to use pagination. Thankfully, the SDK these days makes that much easier than it used to be, especially in dynamic programming languages like JavaScript, you can use async-atorators and that's a relatively easier experience to go through all the different pages. But of course, you need to be aware that you are making multiple requests to DynamoDB. You're sending multiple HTTP requests. So the more data you read, the more time is going to be required to read the entire dataset. Now we should probably talk a little bit about indices because that's such another interesting topic in DynamoDB and it's something that can allow for other access patterns.

00:34:13

In a way, if you're using AWS, it makes sense to adopt DynamoDB, but you always need to look at your requirements and make sure you make it a conscious decision. Definitely, there are many advantages in using DynamoDB, but also we can say the same when it comes to traditional relational databases and SQL. So don't be feeling like you are missing out if you prefer to use a relational database rather than DynamoDB. I think there are still many ways to use relational databases and make them scale in the cloud even at very high scale. So I think we will love to hear more from you if you're using DynamoDB, if you totally ditch relational databases, or if you are still feeling more attached to relational databases than to DynamoDB. And maybe hear about the stories that you might have, if you have any scar from DynamoDB or any scar from relational databases. It would be nice to put these ideas into context because I think the context is really the key here. It's not really like one technology is better than the other. Different use cases might be more suitable for different types of technologies. With that, we will leave you some additional resources in the show notes. We will link the DynamoDB book that we mentioned by Alex DeBrie, but we will also link Alex's podcast and YouTube channel where you can find additional content and we will share some of the talks we mentioned about Rick Houlihan. So thank you very much for being with us and we look forward to seeing you in the next episodes.

Help us to make this transcription better! If you find an error, please submit a PR with your corrections.