DynamoDb is a very different world from the SQL world. There are trade-offs for getting unlimited scalability.
Do not rush to model your Db if the following appears absurd or new to you. Take your time to read more to understand.
DynamoDb Tables have Partitions Keys which are used to automatically determine which physical partition data will be stored in. Do not mistake these with Primary Keys (also called PK). Partitions Keys are not generally unique.
Single table is supposed to have store multiple entities (unlike SQL world). For example, user profile and user orders can be stored like this.
PK: User#1 , SK: PROFILE# , username:dixitsandeep , addresses:[]
PK : User#1 , SK: ORDER#109, items:["ITEM#1122","ITEM#9977]
PK : User#1 ,SK: ORDER#2090, items:["ITEM#2288","ITEM#6655]
When data is accessed using, Combination of Partition Key and Sort Key it results in a unique item.
There is NO concept of JOIN ACROSS TABLES. Joins take place within multiple entities stored in a Single Table. You need to keep traditional normalization out of consideration.
There are many patterns to simulate joins. One of them is to fetch data using Partition Key only (without specifying a Sort key) or with some filter on the Sort key. For example, you can use PK User#1 to fetch both PROFILE and ORDERS in a single query.
In other words, When data is accessed using, Combination of Partition Key and Sort Key it results in a unique item. When you broaden the Sort Key, you get multiple items. You simulate join by broadening the Sort Key filter.
You almost always need to specify a partition key for your queries. Queries without partition keys could return partial data.
You can create up to 20 indexes on a table. When you create an Index you generally make an attribute a PK, SK of the index. Unlike SQL world, in DynamoDb you specify the index when you want to fetch data using that index. You do not need to specify an index while inserting data. Indexes may help you to filter data based on attributes other than PK, SK of the main table.
With the above points in mind, the Partition Key choice should be such that it has lots of possible values. One way to think may be as follows: If you are having millions of users firing 1 million queries per second, then these queries should be landing to different Partition Keys. During high load cases, Partition Key may become a performance bottleneck if too many queries want to access data with the same partition key. That means the choice of Partition Key largely depends on how the application accesses the data: access patterns.
UserRole for example is a bad choice of PartitionKey because it is likely to group lots of data in a single partition.
AWS resources on DynamoDb Data modeling.
https://youtu.be/KYy8X8t4MB8
https://youtu.be/0uLF1tjI_BI