1. Attribute Pattern • Lý thuyết: Lưu các thuộc tính động (không cố định) dưới dạng cặp key–value thay vì field riêng. • Trường hợp sử dụng: o Website thương mại điện tử, mỗi sản phẩm có thuộc tính khác nhau (áo có “size, màu”, laptop có “CPU, RAM, SSD”). o Hệ thống IoT, mỗi thiết bị báo về thông số khác nhau (sensor nhiệt độ, sensor độ ẩm…). • Mục đích: Giúp query và index dễ dàng trên dữ liệu động. • Ví dụ: • { attributes: [ { k: "color", v: "blue" }, { k: "size", v: "L" } ] } • Ưu điểm o Dễ index hơn khi field không cố định. o Linh hoạt cho dữ liệu động, không biết trước schema. o Cho phép query trên nhiều thuộc tính dễ dàng. • Nhược điểm o Query phức tạp hơn (phải lọc theo k và v). o Tốn chỗ hơn so với field gốc (do thêm key–value wrapper). 2. Extended Reference Pattern • Lý thuyết: Ngoài việc lưu ID tham chiếu, copy thêm các field quan trọng từ document liên quan. • Trường hợp sử dụng: Khi thường xuyên join dữ liệu giữa các collection (quan hệ One-to-Many). • • Trường hợp sử dụng: Hệ thống bán hàng: orders lưu cả thông tin khách hàng (tên, địa chỉ) để tránh join với customers. App di động: lưu thêm tên sản phẩm vào shopping_cart để hiển thị ngay, không cần query products. • • Mục đích: Giảm join, tăng tốc độ đọc cho dữ liệu hay dùng. • Ví dụ: • { order_id: 123, customer_id: 456, customer_name: "Alice", address: "Hanoi" } • Ưu điểm ✅ • Giảm số lần join/lookup → đọc nhanh hơn. • Tránh round-trip giữa nhiều collection. • Hữu ích cho mobile apps, real-time analytics. • Nhược điểm ❌ • Dữ liệu lặp → tốn dung lượng. • Cần cơ chế đồng bộ khi dữ liệu gốc thay đổi. • Nếu copy quá nhiều field có thể mất lợi ích. 3. Subset Pattern • Lý thuyết: Chia dữ liệu lớn thành hai phần: thường dùng và ít dùng. • • Trường hợp sử dụng: Ứng dụng review phim: chỉ hiển thị top 10 review mới nhất, còn hàng ngàn review khác lưu riêng. Mạng xã hội: profile user chỉ hiển thị 10 bài viết gần nhất, các bài cũ nằm ở nơi khác. • • Mục đích: Giảm RAM tiêu thụ, đọc nhanh dữ liệu quan trọng. • Ví dụ: • { movie: "Avengers", top_reviews: [ ...5 reviews... ] } • Ưu điểm ✅ • Giảm working set RAM. • Tăng tốc độ đọc cho dữ liệu hay dùng.
Trang 1Tổng hợp MongoDB Schema Design Patterns
1 Attribute Pattern
Lý thuyết: Lưu các thuộc tính động (không cố định) dưới dạng cặp
key–value thay vì field riêng
Trường hợp sử dụng:
o Website thương mại điện tử, mỗi sản phẩm có thuộc tính khác nhau (áo có “size, màu”, laptop có “CPU, RAM, SSD”)
o Hệ thống IoT, mỗi thiết bị báo về thông số khác nhau (sensor nhiệt độ, sensor độ ẩm…)
Mục đích: Giúp query và index dễ dàng trên dữ liệu động.
Ví dụ:
{ attributes: [ { k: "color", v: "blue" }, { k: "size", v: "L" } ] }
Ưu điểm
o Dễ index hơn khi field không cố định
o Linh hoạt cho dữ liệu động, không biết trước schema
o Cho phép query trên nhiều thuộc tính dễ dàng
Nhược điểm
o Query phức tạp hơn (phải lọc theo k và v)
o Tốn chỗ hơn so với field gốc (do thêm key–value wrapper)
2 Extended Reference Pattern
Lý thuyết: Ngoài việc lưu ID tham chiếu, copy thêm các field quan
trọng từ document liên quan
Trường hợp sử dụng: Khi thường xuyên join dữ liệu giữa các
collection (quan hệ One-to-Many)
Trường hợp sử dụng:
Hệ thống bán hàng: orders lưu cả thông tin khách hàng (tên, địa chỉ)
để tránh join với customers
Trang 2App di động: lưu thêm tên sản phẩm vào shopping_cart để hiển thị ngay, không cần query products
Mục đích: Giảm join, tăng tốc độ đọc cho dữ liệu hay dùng.
Ví dụ:
{ order_id: 123, customer_id: 456, customer_name: "Alice", address:
"Hanoi" }
Ưu điểm ✅
Giảm số lần join/lookup → đọc nhanh hơn
Tránh round-trip giữa nhiều collection
Hữu ích cho mobile apps, real-time analytics.
Nhược điểm ✅
Dữ liệu lặp → tốn dung lượng
Cần cơ chế đồng bộ khi dữ liệu gốc thay đổi
Nếu copy quá nhiều field có thể mất lợi ích
3 Subset Pattern
Lý thuyết: Chia dữ liệu lớn thành hai phần: thường dùng và ít dùng.
Trường hợp sử dụng:
Ứng dụng review phim: chỉ hiển thị top 10 review mới nhất, còn hàng ngàn review khác lưu riêng
Mạng xã hội: profile user chỉ hiển thị 10 bài viết gần nhất, các bài cũ nằm ở nơi khác
Mục đích: Giảm RAM tiêu thụ, đọc nhanh dữ liệu quan trọng.
Ví dụ:
{ movie: "Avengers", top_reviews: [ 5 reviews ] }
Ưu điểm ✅
Giảm working set RAM
Trang 3 Tăng tốc độ đọc cho dữ liệu hay dùng.
Document nhẹ hơn → ít I/O hơn
Nhược điểm ✅
Muốn đọc đủ dữ liệu thì phải query thêm → tăng round-trip
Phải xác định rõ “thường dùng” vs “ít dùng”, nếu sai sẽ giảm hiệu năng
4 Computed Pattern
Lý thuyết: Tính toán trước và lưu sẵn kết quả thay vì tính lại khi đọc.
Trường hợp sử dụng:
Hệ thống bán vé: thay vì tính tổng số vé mỗi lần query → lưu sẵn total_tickets
Website tin tức: lưu sẵn total_views của bài viết thay vì mỗi lần phải count từ logs
Mục đích: Giảm chi phí tính toán lặp lại, tối ưu cho hệ thống đọc
nhiều
Ví dụ:
{ movie: "Avengers", total_tickets: 120000 }
Ưu điểm ✅
Đọc nhanh hơn vì có sẵn dữ liệu tính toán
Giảm chi phí CPU, disk do tránh tính toán lặp đi lặp lại
Phù hợp cho báo cáo, thống kê, IoT, time-series
Nhược điểm ✅
Tăng độ phức tạp khi ghi (phải cập nhật kết quả tính toán)
Có thể làm dữ liệu không đồng bộ nếu update không kịp
5 Bucket Pattern
Trang 4 Lý thuyết: Gom nhiều bản ghi nhỏ vào chung một document (bucket).
Trường hợp sử dụng:
IoT: gom tất cả readings trong 1 ngày của 1 sensor vào một document
Logging: nhóm log server theo 1 giờ thay vì mỗi log là 1 document.
Phân tích dữ liệu: nhóm dữ liệu theo khung thời gian để báo cáo
Mục đích: Giảm số lượng document nhỏ, cân bằng dung lượng và
tốc độ truy vấn
Ví dụ:
{ sensor_id: 101, date: "2025-10-08", readings: [ {time: "10:00", temp: 25}, {time: "11:00", temp: 26} ] }
Ưu điểm ✅
Giảm số document (ít overhead hơn)
Cân bằng giữa quá nhiều document nhỏ và document quá lớn
Quản lý dữ liệu time-series dễ hơn
Nhược điểm ✅
Khó query cross-bucket
Nếu bucket quá lớn → document phình to
Random insert/delete trong bucket phức tạp
6 Schema Versioning Pattern
Lý thuyết: Thêm schema_version để app xử lý nhiều version dữ liệu
song song
Trường hợp sử dụng:
App đã triển khai lâu, version cũ lưu phone: "123", version mới lưu phones: ["123","456"]
Khi migrate database, phải chạy song song nhiều version document để tránh downtime
Trang 5 Mục đích: Hỗ trợ thay đổi schema dần dần mà không làm gián
đoạn hệ thống
Ví dụ:
{ name: "Bob", phones: ["123", "456"], schema_version: 2 }
Ưu điểm ✅
Không cần downtime khi thay đổi schema
Hệ thống đọc được nhiều version cùng lúc
Giảm technical debt khi phát triển lâu dài
Nhược điểm ✅
Code xử lý phức tạp (phải support nhiều version)
Nếu không migrate hết, có thể để lại dữ liệu cũ “không đồng nhất”
7 Tree Patterns
Lý thuyết: Lưu trữ dữ liệu phân cấp bằng nhiều cách khác nhau.
Các biến thể:
o Parent Reference → mỗi node lưu cha
o Child Reference → mỗi node lưu danh sách con
o Array of Ancestors → lưu toàn bộ tổ tiên
o Materialized Path → lưu đường dẫn
Trường hợp sử dụng:
E-commerce: danh mục sản phẩm (Electronics > Laptop > Gaming Laptop)
Tổ chức công ty: CEO → Manager → Staff
Website: cấu trúc menu, thư mục cha–con
Mục đích: Biểu diễn quan hệ phân cấp, hỗ trợ query tìm
cha/con/nhánh dễ dàng
Ví dụ:
Trang 6 { name: "Electronics", parent: "Products" }
Ưu điểm ✅
o Linh hoạt cho dữ liệu phân cấp (org chart, categories)
o Có nhiều lựa chọn mô hình (Parent ref, Child ref, Ancestor array, Materialized path)
o Hỗ trợ query theo tổ tiên, con cháu, di chuyển nhánh
Nhược điểm ✅
o Không có mô hình nào “tối ưu cho tất cả” → phải chọn theo nhu cầu query
o Một số mô hình (Materialized Path) khó khi cần cập nhật nhiều node
o Có thể cần aggregation phức tạp ($graphLookup)
8 Polymorphic Pattern
Lý thuyết: Lưu nhiều loại dữ liệu trong cùng collection với field type.
Trường hợp sử dụng:
Collection vehicles: lưu cả car, bike, boat trong cùng collection → dễ query “tất cả phương tiện”
CMS (Content Management System): lưu article, video, podcast chung collection để dễ quản lý và tìm kiếm
Mục đích: Gom nhiều loại entity khác nhau vào cùng collection để
query tổng hợp dễ dàng
Ví dụ:
{ type: "car", wheels: 4 }
{ type: "boat", propeller: 2 }
Ưu điểm ✅
Cho phép lưu nhiều loại document trong cùng collection
Query tổng hợp dễ dàng hơn
Phù hợp cho product catalog, content management
Nhược điểm ✅
Dữ liệu trong collection không đồng nhất → khó enforce schema
Trang 7 App phải biết cách xử lý từng loại document.
Index phức tạp nếu các loại khác nhau quá nhiều
9 Other Patterns
a Approximation Pattern
Lý thuyết: Lưu số liệu gần đúng thay vì chính xác.
Trường hợp sử dụng:
Bộ đếm lượt view trang web: thay vì update mỗi lần view → chỉ update mỗi 100 views
Thống kê like/share: không cần chính xác từng giây, chỉ cần số liệu gần đúng
Mục đích: Giảm số lần ghi, tăng hiệu năng.
Ví dụ: Chỉ update mỗi khi đạt 100 view.
Ưu điểm ✅
Giảm số lần ghi → tăng hiệu năng
Ít contention trên document (giảm lock)
Nhược điểm ✅
Dữ liệu không chính xác tuyệt đối
Ứng dụng phải chấp nhận sai số
b Outlier Pattern
Lý thuyết: Xử lý riêng những document đặc biệt (quá to/khác biệt).
trường hợp sử dụng:
Mạng xã hội: user bình thường có 100 bạn, nhưng celebrity có 1 triệu
→ tách riêng celebrity ra collection khác
E-commerce: phần lớn sản phẩm có 10–20 review, nhưng vài sản phẩm có 10.000 review → lưu riêng để không làm chậm query
Mục đích: Tránh để dữ liệu ngoại lệ làm ảnh hưởng đến hiệu năng
chung
Trang 8 Ví dụ: User bình thường và celebrity lưu ở 2 nơi khác nhau.
Ưu điểm ✅
Tối ưu cho phần lớn dữ liệu (bỏ qua các ngoại lệ hiếm gặp)
Tránh làm hệ thống chậm vì một số document quá “khác thường”
Nhược điểm ✅
Phải xử lý outlier riêng trong app
Aggregation ad-hoc khó vì phải gộp cả normal + outlier
Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm
1
Attribute
Biến field
độ ng thành cặp key–
value trong mảng
- Product catalog:
mỗi sản phẩm có thuộc tính khác nhau- IoT:
{ attributes:
[{k:"color",v:"blue"}, {k:"size",v:"L"}] }
- Linh hoạt với dữ liệu
độ ng- Giảm
số
index-Dễ query
- Query phức tạp hơn- Tốn dung lượng
do lưu thêm {k,v}
Trang 9Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm
thiết bị báo nhiều thông
số không
cố định
thuộc tính
2
Extended
Reference
Lưu thêm field
quan trọng khi tham chiếu sang collection khác
- orders
↔ custome rs: lưu tên và
đị a chỉ khách hàng trong
đơ n hàng- Giỏ hàng mobile:
lưu
{ order_id:123, customer_id:456, customer_name:"Alic e" }
- Đọc nhanh,
ít join- Hữu ích cho mobile , real-time
- Dữ liệu lặp- Phải
đồ ng bộ khi
dữ liệu gốc thay đổi
Trang 10Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm
thêm tên sản phẩm
3 Subset
Chia document lớn thành phần “hay dùng” và
“ít dùng”
- Movie reviews:
lưu 10 review mới nhất, còn lại riêng- Social profile:
lưu 10 post gần nhất
{ movie:"Avengers", top_reviews:[ 5
reviews ] }
- Giảm RAM-Nhanh khi
đọ c dữ liệu chính
- Muốn toàn
bộ dữ liệu → query thêm-Khó xác
đị nh đâu là
“hay dùng”
4
Compute
d
Lưu sẵn kết quả tính toán
để tránh
- Website tin tức:
lưu
{ movie:"Avengers", total_tickets:120000 }
- Đọc nhanh hơn- Giảm
- Update phức tạp hơn- Nguy
cơ dữ liệu
Trang 11Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm
tính lại nhiều lần
total_vi ews thay vì count- Bán vé:
lưu sẵn tổng vé bán
tải CPU/d isk
sai lệch
5 Bucket
Gom nhiều bản ghi nhỏ vào 1 document (bucket)
- IoT:
gom readings
1 sensor/n gày- Logging:
gom log
1 giờ/serv er
{ sensor_id:101, date:"2025-10-08", readings:
[{time:"10:00",temp:25 }] }
- Giảm
số docum ent nhỏ- Cân bằng dung lượng
và tốc độ
- Query cross-bucket khó- Bucket lớn → doc phình
6 Thêm - App { name:"Bob", - - App phức
Trang 12Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm
Schema
Versionin
g
field schema_v ersion để chạy
nhiều version song song
nâng cấp schema:
phone (v1) → phones:
[] (v2)- Migratio
n dần không downtim e
phones:["123","456"], schema_version:2 }
Không downti
me khi đổi schem a- Quản
lý dữ liệu lâu dài
tạp- Dữ liệu không đồng nhất
7 Tree Biểu diễn
dữ liệu phân cấp (nhiều mô hình:
Parent, Child, Ancestor, Path)
- Categor
y sản phẩm-
Tổ chức công ty- Cấu trúc thư mục
{ name:"Electronics
", parent:"Products"
}
- Nhiều cách phù hợp query khác nhau- Linh
- Không mô hình nào tối
ư u cho tất cả- Update nhánh phức tạp
Trang 13Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm hoạt
8
Polymorp
hic
Lưu nhiều loại
document khác nhau trong 1 collection, phân biệt bằng type
- Collecti
on vehicles:
lưu car, bike, boat- CMS:
article, video, podcast chung collectio n
{ type:"car", wheels:4 } { type:"boat", propeller:2 }
- Query tổng hợp dễ- Quản
lý tập trung
- Dữ liệu không đồng nhất- Index khó tối ưu- App phải phân loại theo type
9a
Approxim
ation
Lưu dữ liệu gần
đ úng để giảm ghi
- Page views:
chỉ update mỗi 100 lần
{ page_id:1, views:10000 } (update theo batch)
- Giảm ghi- Tăng hiệu năng
- Sai số dữ liệu- Không phù hợp nếu cần chính xác tuyệt
đố i
Trang 14Pattern Lý
thuyết
Trường hợp sử dụng
đ iểm Nhược điểm
view- Like/sha
re thống
kê theo lô
9b
Outlier
Tách document
“ngoại lệ”
ra để không
ả nh hưởng phần lớn
dữ liệu
- Social:
celebrit
y có 1M follower
- E-commer ce: vài sản phẩm có 10k
review
Tách user nổi tiếng
ra collection khác
- Tối
ư u hiệu năng cho
dữ liệu thường
- Không
bị
“kẹt”
vì ngoại lệ
- App phải
xử lý riêng ngoại lệ- Aggregation phức tạp hơn
Trang 15Điểm khác biệt chính
Tiêu chí Attribute Pattern Polymorphic Pattern
Bản chất Một loại document, nhiều thuộc
tính động
Nhiều loại document khác nhau trong cùng collection
Mục tiêu Chuẩn hóa dữ liệu động để dễ
index, query
Gom dữ liệu không đồng nhất
để query tổng hợp
Cấu trúc
dữ liệu Mảng {k, v} chứa các attribute
Field type để phân biệt document
Ví dụ
điển hình
Catalog sản phẩm (mỗi sản phẩm có thuộc tính khác nhau)
Collection vehicles chứa cả car, boat, bike
Khi nào
dùng
Thuộc tính thay đổi nhiều, không cố định
Khi muốn lưu trữ nhiều loại entity khác nhau chung 1 nơi
Tóm gọn:
Attribute Pattern = xử lý field động trong một loại document.
Polymorphic Pattern = xử lý nhiều loại document khác nhau
trong một collection.
1 Quan hệ One-to-One
Embed (nhúng):
Thường nhúng trực tiếp trong document chính cho đơn giản
→ Ví dụ: User và Billing Address (chỉ 1)
Reference:
Chỉ nên dùng khi cần tối ưu hóa hoặc thông tin 2 bên ít khi được truy cập cùng nhau
→ Ví dụ: Store và StoreDetail (chỉ khi tách ra để tối ưu)
✅ Khuyến nghị: Embed bên nào cũng được, thường chọn phía “1” vì chỉ
có 1 đối tượng
✅ 2 Quan hệ One-to-Many
Trang 16Có 4 cách chính:
1 Embed ở phía “1”:
o Lưu mảng các đối tượng “nhiều” vào document của “1”
o Dùng khi số lượng “nhiều” ít, cố định, thường cần truy cập
cùng “1”.
→ Ví dụ: Product và Top Reviews (chỉ vài review nổi bật)
⚠️ Không nên dùng nếu “nhiều” có số lượng lớn hoặc thay đổi thường xuyên
2 Embed ở phía “nhiều”:
o Nhúng dữ liệu “1” vào từng document “nhiều”
o Dùng khi dữ liệu “1” ít thay đổi, còn “nhiều” thường xuyên
được truy vấn độc lập
→ Ví dụ: Địa chỉ giao hàng nhúng trong từng Order
(Địa chỉ cũ không cần cập nhật khi khách đổi địa chỉ mới)
3 Reference ở phía “1” (mảng tham chiếu tới nhiều document con):
o Ít dùng hơn, vì phải đồng bộ tham chiếu thủ công khi document con bị xóa/sửa
→ Ví dụ: ZipCode chứa mảng storeID
Dễ phức tạp khi dữ liệu thay đổi
4 Reference ở phía “nhiều” (mỗi document con giữ ID của “1”):
o Phổ biến và dễ quản lý hơn
o Khi xóa document con, không cần xử lý tham chiếu ngược
→ Ví dụ: Mỗi Store lưu zipID để tham chiếu đến ZipCode
✅ Khuyến nghị:
Ít dữ liệu → embed ở phía “1”.
Nhiều dữ liệu → reference ở phía “nhiều” (cách an toàn, dễ quản
lý nhất)
✅ 3 Quan hệ One-to-Zillions
Trang 17 Không thể embed (quá lớn).
Bắt buộc reference ở phía “nhiều” → mỗi document con tham chiếu
đến document “1”
→ Ví dụ: Hàng triệu follower mỗi người dùng
✅ 4 Quan hệ Many-to-Many
Embed:
Chỉ embed trên phía nào được truy vấn nhiều nhất, dữ liệu ít thay đổi, hoặc chấp nhận trùng lặp
→ Ví dụ: Cart embed Items snapshot lúc checkout
Reference:
Thường dùng reference ở cả 2 phía, hoặc chọn phía nào được truy vấn nhiều hơn
→ Ví dụ: Movies – Actors: mỗi Movie có mảng actorID, hoặc mỗi Actor
có mảng movieID
✅ Khuyến nghị:
Embed khi dữ liệu ít và cần đi kèm.
Reference khi dữ liệu lớn, dùng chung, thay đổi nhiều.
✅ Tổng kết nhanh:
One-to-One: thường embed ở phía “1”.
One-to-Many (ít dữ liệu): embed ở phía “1”.
One-to-Many (nhiều dữ liệu): reference ở phía “nhiều”.
One-to-Zillions: chỉ nên reference ở phía “nhiều”.
Many-to-Many: embed phía truy vấn chính hoặc reference ở cả 2
phía