Find the implementation here.
Now that we have the schema ready, let's design the database structure for it!
First, we need a place to store users. This is simple, as these are just keyed entities and there is no need for any indices:
Since users are stored in Cognito, it's a best practice to use its identifiers in the database as well. This makes it easy to connect the users in the two places.
Next, we need a way to store a user's friends. While it could go directly into the User
object, that would add limitations and also increase the size of the object. Instead, create a table that makes it easy to query both a specific user's friends and also whether two users are friends or not.
Notice the redundancy here: when user1
and user2
are friends that adds 2 rows to the table. While this could be the result of a business requirement, such as one row means the user sent a friend request to another user, even in the lack of such requriement it is still beneficial to store friends this way.
To query a user's friends, a simple Query
operation is enough. Due to the duplicated entries, the other user will be returned from both ends. Similarly, to see if two specific users are friends, a GetItem
will return zero or one rows. Without this redundancy, both operations would require an additional call to the database.
And by using DynamoDB transactions to atomically add and remove both rows makes sure that the data is consistent at all times.
Then we need to store posts that the users wrote on their timeline. Here, a post has its ID but we also need to support getting all posts for a given user. For this, we'll use a GSI:
The table with the index supports both use-cases in the schema: to get a post by its ID, use a GetItem
on the table, and to get a list of posts for a user, send a Query
to the GSI.
Finally, define a place to store the comments for a post.