Modeling data - embed or reference

DP-420 · Design and implement data models · Updated

Azure Cosmos DB for NoSQL stores JSON items, and there are no server-side joins between containers. The model you choose decides how many requests and request units (RUs) each read costs, so modeling is the most tested design skill.

Think in access patterns

Do not start from entities and tables. Start from the list of queries and writes the app runs most often, then shape items so the common reads are answered by one point read or one single-partition query. A point read (ReadItemAsync with id and partition key) costs about 1 RU for a 1 KB item, which is cheaper than any query.

Embed or reference

ChooseWhenResult
Embed (nested object or array)Data is read together, changes rarely, and is bounded in sizeOne read, atomic update of the item
Reference (store the id of another item)Data is unbounded, changes often, or is used by many parentsSmaller items, but you need a second read

An item can be at most 2 MB, so never embed an array that grows without limit. Many-to-many relationships (books and authors) are often modeled with a link item or with a copy of the few fields you need.

Denormalize on purpose

Copy fields you read often, such as an author name inside each book. Reads become cheap, and writes must update the copies. To keep copies in sync automatically, use the change feed (covered in another lesson), not manual code.

Several entity types in one container

A container is not a table. You can store customers and orders together, give both the same partition key value (for example customerId), and add a type property. One query on that partition returns both, and a transactional batch or stored procedure can change them atomically because they share a logical partition.

NoSQL query basics

The query language is SQL-like and always runs against one container. The alias refers to each item.

SELECT f.id, c.givenName
FROM Families f
JOIN c IN f.children
WHERE f.address.state = "WA"
  • JOIN is a self-join within an item and expands arrays. It never joins containers.
  • Use VALUE to return raw values, and TOP, ORDER BY and OFFSET LIMIT as usual.
  • System functions such as GetCurrentDateTime() return an ISO 8601 UTC string, so you do not need a UDF for that.

Time to live (TTL)

TTL deletes items automatically. A container setting of -1 means items never expire unless the item has its own ttl. A container setting of null or off disables TTL completely, even if items have ttl. An item value overrides the container default.

Exam traps

  • There is no cross-container join. Choose embedding or a same-container model instead.
  • Unbounded child data must be referenced, not embedded, because of the 2 MB limit.
  • A point read beats a query. Query by id plus partition key when you can.
  • Container TTL off (null) differs from -1: with -1 item-level ttl still works.
  • Normalizing like SQL Server is usually the wrong answer on this exam.

Practice questions

Choose an answer, then review the explanation to check your understanding.

1. An order always shows its line items, and line items are never read without the order. Each order has fewer than 100 lines. How should you model them?

Show answer

Answer: B.Data that is read together and is bounded in size should be embedded. One read returns everything and costs fewer RUs.

2. A blog post has thousands of comments that grow without limit. What is the best model?

Show answer

Answer: B.Unbounded arrays make items grow toward the 2 MB item limit and make every update expensive. Use references for unbounded data.

3. You need to return the given names of children from a Family item that has a children array. Which query fits?

Show answer

Answer: A.In the NoSQL language JOIN is a self-join inside one item. It expands the array so you can project its elements.

4. Related entities of different types must be read with a single query and the lowest RU cost. What should you do?

Show answer

Answer: B.Storing different entity types in one container that share a partition key value lets one in-partition query return them all.

DP-420 course outline

All 8 lessons · Course overview
  1. Modeling data - embed or referenceDesign and implement data models Free
  2. Choosing partition keysDesign and implement data distribution Free
  3. Consistency levels and global distributionDesign and implement data distribution Full access
  4. Change feed and Azure FunctionsIntegrate an Azure Cosmos DB solution Full access
  5. Stored procedures, triggers and UDFsIntegrate an Azure Cosmos DB solution Full access
  6. Indexing policies and query costOptimize an Azure Cosmos DB solution Full access
  7. Throughput, RU/s and 429 errorsOptimize an Azure Cosmos DB solution Full access
  8. Security, backup and monitoringMaintain an Azure Cosmos DB solution Full access