Skip to content

Cbonif/single-table-design #7659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

Conversation

chrisbonifacio
Copy link
Member

Description of changes:

Adds page that goes over single table design in DynamoDB with an Amplify Gen 2 schema example and code snippets

Related GitHub issue #, if available:

Instructions

If this PR should not be merged upon approval for any reason, please submit as a DRAFT

Which product(s) are affected by this PR (if applicable)?

  • amplify-cli
  • amplify-ui
  • amplify-studio
  • amplify-hosting
  • amplify-libraries

Which platform(s) are affected by this PR (if applicable)?

  • JS
  • Swift
  • Android
  • Flutter
  • React Native

Please add the product(s)/platform(s) affected to the PR title

Checks

  • Does this PR conform to the styleguide?

  • Does this PR include filetypes other than markdown or images? Please add or update unit tests accordingly.

  • Are any files being deleted with this PR? If so, have the needed redirects been created?

  • Are all links in MDX files using the MDX link syntax rather than HTML link syntax?

    ref: MDX: [link](https://docs.amplify.aws/)
    HTML: <a href="https://docs.amplify.aws/">link</a>

When this PR is ready to merge, please check the box below

  • Ready to merge

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@chrisbonifacio chrisbonifacio changed the base branch from cbonif/add-max-depth-flag to main May 24, 2024 18:22
@printSamuel
Copy link

Past me (1 week ago) would have loved this!
I'm not sure if this is an officially supported feature, but I think it would be interesting to learn how to use functions like begins_with, greater_than, and between on the sort key.
It works with the "old schema", like this:

export function request(ctx) {
  return {
    version: '2017-02-28',
    operation: 'Query',
    query: {
      expression: 'PK = :PK and begins_with(SK, :SK)',
      expressionValues: util.dynamodb.toMapValues({
        ':PK': ctx.arguments.PK,
        ':SK': ctx.arguments.SK
      }),
    },
  };
}

Thanks for your effort. :)

export function request(ctx) {
const { racerId } = ctx.args;

return ddb.query({
Copy link
Member Author

@chrisbonifacio chrisbonifacio Jun 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange. .query should be a valid method based on the AppSync docs:

https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-dynamodb-resolvers-js.html#configure-query

I didn't run into issues deploying or invoking it in a request from the client side

@chrisbonifacio chrisbonifacio marked this pull request as ready for review June 10, 2024 16:30
@chrisbonifacio chrisbonifacio enabled auto-merge (squash) June 13, 2024 03:28
entry: "./getBestPerformanceByClassId.js",
})
)
.authorization((allow) => [allow.publicApiKey()]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just .public()? In general I don't like the idea of using api keys in our examples / docs because they're a time bomb that causes customer projects to break in the future. Since the default npx create amplify includes the auth category, I think it's safe to use everywhere in our docs.

4. Get the list of top scores by race ID.
5. Get the second-by-second performance by racer for all races.

While implementing this design with multiple DynamoDB tables is possible, it's unnecessary and inefficient. A key goal in querying DynamoDB data is retrieving all required data in a single query request. This is a core concept in NoSQL databases, and single-table design simplifies data management and maximizes query throughput.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The language makes me wonder why typical Amplify UX does it the "unnecessary and inefficient" way. It might be worth exploring the tradeoffs of taking this approach. Or, if we really believe this is a superior approach, we should consider adding this feature more natively into our L3 constructs and client libraries.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not widely used partly because:

  1. Few people know it exists; Amazon, for whatever reason, hasn't made a huge effort to promote it despite using it themselves on amazon.com.
  2. You must define your access patterns upfront; many new projects prefer flexibility over efficiency.
  3. It can cause problems if you don't know what you're doing. Having everything on one table is undeniably better, but for novices, wrapping their heads around partitions and profile details, sharing the same virtual space as order history, for example, might be confusing.
  4. Denormalisation: This pattern sometimes requires repeated data, which can be challenging considering most people are familiar with relational normalised data.

That being said, it would be nice to see some native code for it, most people who follow this pattern currently define a table externally and use ElectroDB within a lambda.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants