AWS Cloud Practitioner Study Notes · Part 44

Amazon DynamoDB Attribute Types: Scalar, Document, and Set

AWS Cloud Practitioner study notes explaining all 10 DynamoDB attribute types, API descriptors, lists versus sets, maps, and common data-modeling traps.

Amazon DynamoDB supports 10 attribute data types. They are grouped into scalar types, document types, and set types. Understanding the groups makes it easier to choose the right representation for a DynamoDB item and answer common AWS certification questions.

This is Part 44 of the AWS Cloud Practitioner Study Notes. The complete type map is:

Scalar types (5)
→ String, Number, Binary, Boolean, Null

Document types (2)
→ List, Map

Set types (3)
→ String Set, Number Set, Binary Set

The 10 DynamoDB types

GroupTypeAPI descriptorExample idea
ScalarStringSUser name or email
ScalarNumberNPrice, quantity, or score
ScalarBinaryBRaw bytes or encoded file data
ScalarBooleanBOOLtrue or false
ScalarNullNULLExplicit null value
DocumentListLOrdered values
DocumentMapMNamed nested attributes
SetString SetSSUnique string values
SetNumber SetNSUnique numbers
SetBinary SetBSUnique binary values

The low-level DynamoDB API uses descriptors such as S, N, L, and M to identify the type. High-level AWS SDK clients often let you use native language values and perform the conversion for you.

Scalar types

Scalar types represent one value at a time.

String (S)

String stores UTF-8 text. Common examples include names, email addresses, country codes, UUIDs, product names, and status values.

{
  "UserId": "USER123",
  "Name": "Alice",
  "Country": "Malaysia"
}

In the low-level API representation, the value is wrapped with the S descriptor:

{
  "Name": {"S": "Alice"}
}

String is also commonly used for partition keys and sort keys. Key values must meet the key-design rules for the table, and the attribute type must remain consistent for a given key definition.

Number (N)

Number stores positive numbers, negative numbers, integers, and decimals.

{
  "Age": 28,
  "Price": 29.99,
  "Balance": -5
}

The low-level API sends DynamoDB numbers as strings, such as {"N":"29.99"}, to preserve numeric precision across programming languages and libraries. DynamoDB still treats them as numbers for comparisons and mathematical operations.

Use Number for quantities, prices, scores, timestamps represented numerically, counters, and measurements. Do not store a value as a String if you need DynamoDB numeric comparison or arithmetic behavior.

Binary (B)

Binary stores raw binary data, such as bytes used for encrypted data, compressed data, certificates, or small binary payloads. When represented in the low-level JSON API, binary values are base64-encoded strings.

{
  "DocumentBytes": {"B": "dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk"}
}

For large images, audio files, and videos, Amazon S3 is generally a better storage choice. DynamoDB can store binary attributes, but item size and access-pattern considerations still apply.

Boolean (BOOL)

Boolean stores only true or false.

{
  "IsActive": true,
  "EmailVerified": false
}

Typical uses include feature flags, enabled or disabled status, verification status, and premium membership.

The low-level API representation is:

{
  "IsActive": {"BOOL": true}
}

Null (NULL)

Null represents an explicit null attribute value. In the low-level API, NULL uses the Boolean value true to indicate the attribute is null:

{
  "MiddleName": {"NULL": true}
}

An explicit null attribute is different from an attribute that does not exist. This distinction matters when using expressions that test attribute existence or update an item.

Document types

Document types allow nested structures. A document can contain scalar values, other documents, and sets.

List (L)

A List is an ordered collection. It can contain different DynamoDB types in the same list, and duplicate values are allowed.

{
  "Values": [
    "AWS",
    100,
    true,
    {"Country": "Malaysia"}
  ]
}

List values have positions such as index 0, 1, and 2. Use a List when order matters, duplicates are meaningful, or the elements do not all have the same type.

Common examples include:

  • Ordered purchase history
  • Shopping-cart lines
  • Comments in display order
  • An ordered workflow or event sequence

The low-level representation uses L and wraps every element in its own AttributeValue descriptor:

{
  "Values": {
    "L": [
      {"S": "AWS"},
      {"N": "100"},
      {"BOOL": true}
    ]
  }
}

Map (M)

A Map is a collection of named attributes, similar to a JSON object, dictionary, or hash map. Each value can itself be a scalar, List, Map, or set.

{
  "Address": {
    "Street": "Jalan Ampang",
    "City": "Kuala Lumpur",
    "Postcode": "50450"
  }
}

Nested Maps are allowed:

{
  "Profile": {
    "Personal": {
      "Age": 28,
      "Gender": "Female"
    },
    "Work": {
      "Company": "Example Corp"
    }
  }
}

Use a Map for structured attributes such as an address, profile, application settings, or configuration. Use a List when the primary meaning is sequence; use a Map when the primary meaning is named fields.

Set types

Sets contain unique values of one type. They do not preserve order, and a set cannot contain duplicate members. DynamoDB set attributes also cannot be empty.

String Set (SS)

String Set stores unique strings:

{
  "Skills": ["AWS", "Go", "Terraform"]
}

Low-level API representation:

{
  "Skills": {"SS": ["AWS", "Go", "Terraform"]}
}

Use SS for skills, roles, categories, interests, or labels when uniqueness matters and order does not.

Number Set (NS)

Number Set stores unique numbers:

{
  "Scores": [80, 95, 100]
}

Low-level API representation:

{
  "Scores": {"NS": ["80", "95", "100"]}
}

The API sends number-set members as strings, just like ordinary Number values. DynamoDB still treats them as numbers.

Use NS when duplicate numbers and ordering are not meaningful, such as unique ratings, years, or numeric labels.

Binary Set (BS)

Binary Set stores unique binary values. The low-level API represents each member as a base64-encoded string:

{
  "Certificates": {
    "BS": [
      "U3Vubnk=",
      "UmFpbnk=",
      "U25vd3k="
    ]
  }
}

Use BS only when the application genuinely needs a unique, unordered collection of binary values. For large binary objects, use S3 and store object keys or URLs in DynamoDB.

List versus set

This is one of the most common DynamoDB type comparisons:

RequirementListSet
Preserve orderYesNo
Allow duplicatesYesNo
Mixed element typesYesNo; members share the set type
Empty valueSupported subject to API rulesEmpty sets are not supported
Good examplePurchase historyUnique user roles

Example List:

[Apple, Orange, Apple, Banana]
→ Order preserved; duplicate Apple is allowed

Example String Set:

{Apple, Orange, Banana}
→ Duplicate Apple is removed; order is not meaningful

Choose a List for an ordered history and a Set for unique membership. Do not choose a Set merely because its JSON-looking syntax resembles an array.

Map versus List

The difference is the shape of the data:

Map
→ named fields
→ {"City": "Kuala Lumpur", "Country": "Malaysia"}

List
→ ordered elements
→ ["AWS", "Go", "Terraform"]

Use a Map for an address or profile because each value has a name. Use a List for a sequence of skills or events when position matters.

A complete DynamoDB item

Here is a user-profile item using several types:

{
  "UserId": "USER001",
  "Name": "Alice",
  "Age": 28,
  "Premium": true,
  "MiddleName": null,
  "Skills": ["AWS", "Go", "Terraform"],
  "Address": {
    "City": "Kuala Lumpur",
    "Country": "Malaysia"
  },
  "Scores": [80, 95, 100]
}

Conceptually:

AttributeTypeReason
UserIdStringIdentifier
NameStringText
AgeNumberNumeric comparison or calculation
PremiumBooleanTwo-state flag
MiddleNameNullExplicitly no value
SkillsList or String SetList if order matters; set if uniqueness matters
AddressMapNamed nested fields
ScoresList or Number SetList if order or duplicates matter; set otherwise

The correct type depends on access patterns and meaning, not just on the shape of the input JSON.

Important API representation details

When using the low-level DynamoDB API, every value is wrapped with a type descriptor:

{
  "UserId": {"S": "USER001"},
  "Age": {"N": "28"},
  "Premium": {"BOOL": true},
  "MiddleName": {"NULL": true},
  "Skills": {"SS": ["AWS", "Go"]}
}

Remember these details:

  • Numbers use strings in the low-level JSON wire format to preserve precision.
  • Binary values use base64-encoded strings in that JSON representation.
  • BOOL uses a JSON Boolean.
  • NULL is represented as {"NULL": true}.
  • Lists contain AttributeValue objects.
  • Maps contain attribute names mapped to AttributeValue objects.
  • Sets contain unique members of one set type and do not preserve order.

High-level SDK document clients often hide these wrappers. Do not confuse the SDK’s native-language representation with the low-level API representation.

Common exam and interview questions

How many DynamoDB attribute types are there?

10: five scalar, two document, and three set types.

Which type preserves order and allows duplicates?

List (L).

Which type stores unique strings without order?

String Set (SS).

Can a DynamoDB Set contain duplicate values?

No.

Can a Set preserve insertion order?

No. Use a List if order matters.

Which type represents nested JSON objects?

Map (M).

How is a number represented in the low-level API?

As an N value whose JSON payload is a string, such as {"N":"99.95"}.

Which type represents true or false?

Boolean (BOOL).

How is an explicit null represented?

NULL, with a Boolean value of true in the low-level API.

Final memory map

Scalar
S     String
N     Number
B     Binary
BOOL  Boolean
NULL  Null

Document
L     List
M     Map

Set
SS    String Set
NS    Number Set
BS    Binary Set

The exam shortcut is: List means ordered and duplicate-friendly; Set means unique and unordered; Map means named nested fields.

Sources

Back to the journal