Question: I am finding it difficult to understand the best attribute(s) to use as a partition key for my application as I am new to DynamoDB. I am trying to use DynamoDB for a simple application where pairs of users are randomly selected to meet up and get introduced with one another. I need to choose appropriate tables and partitioning strategies that would help with the following query:

> 
> Retrieve the meetup (introduction) the user has been invited to. It should show all
>  the details of the meetup including the other invited user.
> 
> 
> 

From what I have understood from the docs, to "query" an item, I can only use the keys in the query expression. In addition, a good partition key is one that that has high cardinality and promotes equal distribution in read/write throughput activity. I was thinking of creating a `Meetup` table but im struggling with choosing a partition key especially when the meetup is "owned" by 2 users and the event item will expire(be non-active) after the meetup occurs so I'm not sure that using the `meetupID` is a good idea. But I was thinking of using two tables as such:

**Invitation Table:**

* userId (partition key)
* eventId (sort Key)
* some attribute
* another attribute

**MeetUp Table:**

* meetupId (partition key) -> I'm hesitant about this
* invitedUsers (this is going to be an array of user objects)
* cancelled
* meetDate

With this solution, 2 requests would need to be done to firstly get the latest eventId and then to get the event details. Does this seem like a good approach? Is the meetupId a good partition key? is there a better solution to this?

Answer: 
If the number of meetups per users follows a normal distribution, you should be able to safely have something like this:

* A *users* table :: Partition key = user\_id (some UUID)
* A *meetups* table :: Partition key = meetup\_id (some UUID)
* A *meetup\_invites* table: Partition key = user\_id, Sort key = meetup\_id

At large scale, the above could only become problematic, if, say, you had some users with a million invites when the average invite per user would be very small.
You can use this schema.

```
| ID (PK)   | SortKey          | MeetupId (GSI1) | 
| User1234  | metadata         |                 | age:28 | nationality: US | interestedIn:Economics | name:Tim  | ...
| User1234  | meetup#meet1234  |      meet1234   | ...
| meet1234  | metadata         |      meet1234   | location:Central Park | time:122323223 | ...
| User4567  | metadata         |                 | age:27 | nationality: US | interestedIn:Arts | name:Kira  | ...
| User4567  | meetup#meet1234  |      meet1234   | ...
...
Id is sortkey for GSI1

```

this will solve use cases like

1. Get all meetups User1234 is invited to
`Select * where id=User1234 and SortKey startswith meetup`
2. Get all meetups User1234 is invited to in 10 days
`Select * where id=User1234 and SortKey startswith meetup filter eventDate < today +10`
3. Get userInfo for user1234 `Select where id=User1234 and SortKey=metadata`
4. Get all invitees for meet1234 `Select * where MeetupId=meet1234 and SortKeystarts with User From Table GSI1`
5. Get all details about event meet1234 `Select * where MeetupId=meet1234 From Table GSI1`

Unsolved use cases:

1. Get all meetups happening today.

In NoSql schema should be driven from use cases.