2
votes

I am new to dynamodb and serverless, and I have read about composite sort keys. I think they could be a solution to my problem, but I am not completely sure how to implement them. In my case I have a table with a Post entity that has the following fields, it looks like this:

post_id <string> | user_id <string> | tags <string[]> | public <boolean>| other post data attributes...

The queries that I need to do are:

  1. Get all posts that are marked public
  2. Get posts filtered by tags
  3. Get all posts filtered by user, both public and not public
  4. Get a single post

I could set the public attribute only to the entities that are marked with public. How does one define composite sort keys with servless framework.

So, for example:

sort key: tag#public

This is what I have set up previously.

PostsDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          - AttributeName: postId
            AttributeType: S
          - AttributeName: userId
            AttributeType: S
          - AttributeName: createdAt
            AttributeType: S
        KeySchema:
          - AttributeName: postId
            KeyType: HASH
          - AttributeName: userId
            KeyType: RANGE
        BillingMode: PAY_PER_REQUEST
        TableName: ${self:provider.environment.POSTS_TABLE}
        GlobalSecondaryIndexes:
          - IndexName: ${self:provider.environment.USER_ID_INDEX}
            KeySchema:
              - AttributeName: userId
                KeyType: HASH
              - AttributeName: public
                KeyType: RANGE
            Projection:
              ProjectionType: ALL
1

1 Answers

6
votes

Composite sort keys refer to how you use your sort keys.

The only thing you need to do in your serverless.yml is to define the sort key name (which you've done here). Whether or not you use that sort key as a composite sort key (or not) is up to your application. You'd either set the value of the sort key to a composite value (e.g. CA#BEVERLYHILLS#90210) or not (e.g. BEVERLYHILLS). Neither DynamoDB or Serverless Framework really care, it's more about how you use the keys in your application logic.

Keep in mind that DynamoDB allows you to store multiple entities in a single table. These entities may have different primary keys (partition keys and sort keys). For that reason, I'd recommend naming your partition key PK and your sort key SK.

For example, lets say you define your Post and User entities to have the following primary keys:

             Partition Key            Sort Key
Post        POST#<post_id>           <timestamp>
User        USER#<user_id>           USER#<user_id>

In the case of the Post, your sort key could be a timestamp (the time the post was made). For Users, the sort key could be the ID of the user. So what do you name the sort key field when defining your table?

I like naming the sort key SK as a reminder that you are using that field to organize your data. Of course, you can name it whatever you'd like, but if you name it userId, as you've done in your serverless.yml file, you may forget that the field can hold something other than user IDs!