I've spent my entire career working with denormalized relational databases. I am having a hard time un-learning all of that in order to implement a single-table design that can handle a couple specific access patterns on an "App Store"-like personal project.
Here's a quick ERD. There is an App model identified by a platform (iOS, Android) and bundle identifier along with a Defaults map that is used when creating new versions. Each App can have 0 to many Versions which are identified by a version number (which is a sequential numerical value and is unique within the context of an App). A version has an IsReleased attribute along with several others (like Name, Release Notes, Binary Path, etc).
Access Patterns
- List the latest version of every app.
- List the latest version of every app for a given platform.
- List the latest version of every app where IsReleased is 1.
- List the latest version of every app for a given platform where IsReleased is 1.
- Get the latest version of a specific app.
- Get the latest version of a specific app where IsReleased is 1.
- Get all versions of a specific app.
- Get all versions of a specific app where IsReleased is 1.
- Get the Default attribute for a specific app.
I'm having trouble with 1 though 4, this table is where I was headed. I'm having a hard time coming with a GSIs that will give me the all of the app items with a single version by sort order.
pk | sk | Defaults | App Name | Version | IsReleased | Other Attributes |
---|---|---|---|---|---|---|
app_ios_com.app.one |
defaults |
{ ... json ... } |
||||
app_ios_com.app.one |
version_1 |
App One | 1 | 1 | ||
app_ios_com.app.one |
version_2 |
App One | 2 | 1 | ||
app_ios_com.app.one |
version_3 |
App One | 3 | 1 | ||
app_ios_com.app.two |
defaults |
{ ... json ... } |
||||
app_ios_com.app.two |
version_1 |
App Two | 1 | 1 | ||
app_ios_com.app.two |
version_2 |
App Two | 2 | 0 | ||
app_ios_com.app.two |
version_3 |
App Two | 3 | 0 |
For example, for access pattern 1, I want:
pk | sk | Defaults | App Name | Version | IsReleased | Other Attributes |
---|---|---|---|---|---|---|
app_ios_com.app.one |
version_3 |
App One | 3 | 1 | ||
app_ios_com.app.two |
version_3 |
App Two | 3 | 0 |
For example, for access pattern 3, I would want:
pk | sk | Defaults | App Name | Version | IsReleased | Other Attributes |
---|---|---|---|---|---|---|
app_ios_com.app.one |
version_2 |
App One | 3 | 1 | ||
app_ios_com.app.two |
version_1 |
App Two | 1 | 1 |
Some data constraints that I have to keep in mind:
- There are currently only 10 to 20 apps, but I need to be able to support hundreds
- Most apps will have 100 to 200 versions with 20 to 30 released versions. The biggest app has 1000 versions of which 50 are released.
- In the back-end, the IsReleased flag will typically be toggled from 0 to 1, but will occasionally be toggled from 0 to 1.
- The average version item is approximately 2 KB.
- The access pattern variations where IsReleased is 1 are more frequently used by a significant margin.
I feel like the solution is right in front of me, but I can't put my finger on it.