[MUSIC] A lot of times, we also want to optimize for writes, as well as reads. So, let's say that we have that same page that we're going to display all of the comments. And we decide that at the top of the page we want to in one place display the total number of comments or reviews or whatever it is. At the top of the page so that the person knows without even having to go scroll through the list how many comments have been, put in on that particular product. Now one way that we could do this is we could have a, let's say this is a product page, we're going to say number of comments, per product. Now this would be really good from a read perspective because we can just look up the particular product and we'll get the number of comments. Now you can imagine though if this is a really hot product and you have hundreds of people who are simultaneously commenting on this particular product, what that means is is that we have simultaneous writes to this particular object. So what's going to happen is, is that writing is going to become a bottleneck because each of the writers is going to have to lock this particular object, is going to update it. And then release that lock before the next writer can get in and, and update it. So, this becomes a bottleneck for writing. This is not ideal if we are going to have heavy write contention. Now one way we could deal with this is, we could go back to the model where we have multiple, product entity, entries or entities. And then we have all these different products and we can simply, you know, query and count how many there are. But obviously, that's not as fast as we'd like it to be. Another interesting way that we can do this, so we can start with here. We could also try something like this. Another way that we can do it, is we would like, lets say to increase the number of, of writes that can go through simultaneously. So we'd like to allow to parallel writes. Is rather than having this, we can move to a model where we have, number of comments, product, and we'll call this shard one. I'll say what a shard is in a minute. And then, we have number, comments, product, shard N, and the idea is, is that, we create multiple copies of this number of comments per product. And then when we want to write an updated value what we do is we come in here and we randomly choose, one of the particular entities that's in here, or we have some selection scheme, but we can just randomly choose. And if we know, for example, that there are N different shards, and basically what a shard in this case is is we're going to take the counter, and we're going to split it up into multiple counts. So, if we want to split this counter into ten different shards, what we would do. As we would create ten different entities that are entires that count that have a partial count inside of them. And at any point in time, if we want to go and get the true count then we query and count up to, N entries. So where is this one, over here, we're going to query and count all entries, of the products. Alright this should actually be comment of the product comment. Rather than going and querying all cont, counts, of the product comments, over here, all we have to do is go and query up to n entries of comment products. I mean, comments for produc, for a particular product. And we get back all of these different shards, we basically query for all of them, and then we sum up their values. So, rather than having just a single value, we will get all of these and add them together. Basically, we will sum values, to get the count. So, when a, a comment is added, basically what will happen is, if we add a new comment here, when we go to write to the database we will randomly select one of the shards. That we are going to update the count for. We'll pick that shard, we will increment its count, and then save it back in the database. If another writer comes in, they at ex, exactly the same time, and they randomly choose, hopefully they will get a different shard. So, we can control the contention that we have on our different shards by, deciding how many different shards we have. And we can also balance how much effort it is to go and read the count, by determining how much, how many shards we have. The more shards we have, the more expensive it is to read the count back out. But, the more shards we have the greater the greater number of writers that can come in and write concurrently to the count. So, we can balance and basically trade off reads and writes by determining how many times we duplicate and have partial counts in here. So, we are essentially duplicating data we're basically taking an object breaking it apart, in this case taking a count, breaking it apart into multiple entries. And then allowing writers to select any of the entries to update and then when we go and actually get the true value, we're getting all of the entries and summing them. But, whereas over here when we had individual product comment entries and we were counting all of them, we had just a, our work was proportional to the number of product comment entries. Over here, our work to sum is proportional to the number of shards we create. So we can flexibly balance out the number of shards that we have. Now how does this work in terms of randomly choosing? Well, when we go to get the key, let's say that product ID is the first part of the key. The second part of the key can be a number between zero and the number of shards. So if you want to randomly select a particular entity, you put in the product ideas the first part of the key, and then you randomly choose a number between zero and the number of shards, and you provide it as a second point part of the key. And then you simply grab that object, update it, and save it. And then if you want all of the product entities, and you want to sum them up, you simply go and get all of the entities that have a particular product ID, and then the number of shards you get product ID one, product ID two. And depending on your database, it may even support Some type of prefixed based query across the keys. Where you can ask for all of the keys that have a particular prefix.