Flattening data
If you come from a SQL background, and you need create relationships between items, or parent/child relations you might initially think that with NoSQL databases you do not need to create relationships between fields, and can nest your data the same way you represent it in your application.
Let's look at two-approaches of modeling and representing the same data :
#
Nested layout items (the bad approach)#
Table model#
Queried record#
Moving the item3 from the item2 children's to the item1 children'sIn order to move an item, we need to physically move it. We can accomplish that by removing the field we are interested in (the field will be deleted, and we will retrieve the deleted value, see delete_field), and if there was in did an item that we have been able to remove, we will re-insert the entirety of the item in our target field.
Which means, that we first fully removed the item from the database, which both consume a lot of writing capacity and brings some latency in your application if you are moving big fields. Then, you re-write the entirety of your item to your database, which will consume double the amount of writing capacity and bring twice the latency.
This approach also bring risks if your application crashes or stops after you remove the field you want to move, but before your re-insert it, in which case, your data will be lost if you have not taken appropriate measures in your application towards this issue.
This approach also makes your sensible to the DynamoDB nesting limit of 32 levels. Notice that if you count the number of indentations in the queried record before reaching the 'item3', you will see there is 6 indents, which means that the 'item3' key is at a depth level of 6. You still have a lot of room before reaching the maximum depth of 32 levels, yet, this means that you will not be able to infinitely nest fields into each others (read more at The depth limit).
#
Flattened layout items (the good approach)#
Table model#
Queried record#
Moving the item3 from the item2 children's to the item1 children'sWith this second approach, all our items are present in same dict, which means you should not consider using counter ids and instead use unique identifiers for example uuid's (read more at Unique ids). Each item has a new non-required field, the parentId, which should contain the id of another item that should act as the parent for your item.
This allows you to only modify a single field in your item to change its relationship, no matter the size of the item, or even if there are other items that consider as their parent the item you are modifying.
This also gives you the ability to not be constrained by the DynamoDB depth limit of 32 (read more at The depth limit) since all of your items start at the same depth level.
It is then your responsibility to reconstruct your data from the flattened data either server side, or better, client
side. You will find below two examples, one in Python
and one in Typescript
to efficiently reconstruct
nested data from flattened data.