11.1: Denormalization by using a complex attribute
Database normalization is a key component of relational database modeling and one of the hardest habits to break when moving to DynamoDB.
The first way we’ll use denormalization with DynamoDB is by having an attribute that uses a complex data type, like a list or a map.
For example, a single Customer can have multiple shipping addresses to which they may ship items. We will have a ShippingAddresses attribute on the Customer item. This attribute is a map and contains all addresses for the given customer.
You can add a new customer here.
import { QueryCommand } from "@aws-sdk/lib-dynamodb";
import ddbDocClient from "@/lib/clients/dynamoDBClient";
import { dbName } from "@/lib/constants";
const dbCommand = new QueryCommand({
TableName: dbName,
KeyConditionExpression: "#pk_key = :pk_value",
ExpressionAttributeNames: {
"#pk_key": "pk",
},
ExpressionAttributeValues: {
":pk_value": "CUSTOMERS",
},
});
const dbResponse = await ddbDocClient.send(dbCommand);
Primary Key | Attributes | ||||||||
---|---|---|---|---|---|---|---|---|---|
Partition key: pk | Sort key: sk | firstName | lastName | phone | zipcode | shippingAddresses |
There are two factors to consider when deciding whether to handle a one-to-many relationship by denormalizing with a complex attribute:
1: Do you have any access patterns based on the values in the complex attribute?
All data access in DynamoDB is done via primary keys and secondary indexes. You cannot use a complex attribute like a list or a map in a primary key. Thus, you won’t be able to make queries based on the values in a complex attribute.
2: Is the amount of data in the complex attribute unbounded?
A single DynamoDB item cannot exceed 400KB of data. If the amount of data that is contained in your complex attribute is potentially unbounded, it won’t be a good fit for denormalizing and keeping together on a single item.
If the answer to either of the questions above is "Yes", then denormalization with a complex attribute is not a good fit to model that one-to-many relationship.