MongoDB
1. Tổng quan
A. Định nghĩa
MongoDB là cơ sở dữ liệu NoSQL hướng tài liệu (Document-oriented) tiêu biểu, lưu trữ dữ liệu dưới dạng tài liệu tương tự JSON (Document, định dạng lưu trữ nội bộ là BSON), xử lý dữ liệu linh hoạt mà không cần schema cố định, và mặc định cung cấp khả năng mở rộng ngang thông qua sharding cùng tính sẵn sàng cao thông qua replica set.
Ý tưởng cốt lõi của MongoDB là "xử lý dữ liệu như các tài liệu tự hoàn chỉnh thay vì các hàng của bảng". Cơ sở dữ liệu quan hệ (RDB) chuẩn hóa dữ liệu, chia vào nhiều bảng rồi kết nối bằng join; cách này mạnh về tính nhất quán và loại bỏ trùng lặp, nhưng có hạn chế là schema cứng nhắc và khó mở rộng ngang quy mô lớn. Ngược lại, MongoDB hướng tới việc gói trọn dữ liệu liên quan vào trong một tài liệu. Ví dụ, không tách người dùng và địa chỉ, lịch sử đơn hàng của họ ra các bảng riêng, mà lưu lồng nhau dưới dạng mảng và đối tượng trong một tài liệu người dùng. Khi đó có thể tra cứu bằng một lần đọc mà không cần join nên nhanh, có thể tự do thêm·thay đổi trường nên linh hoạt (schemaless), và dễ chia dữ liệu lưu trên nhiều máy chủ (sharding) để mở rộng quy mô lớn.
Các đặc tính này đặc biệt góp phần vào năng suất phát triển vì giảm khoảng cách giữa mô hình dữ liệu và đối tượng của ứng dụng, tức là cái gọi là "sự không tương thích trở kháng (impedance mismatch)". Cấu trúc đối tượng lồng nhau trong ngôn ngữ hướng đối tượng khớp nguyên vẹn với dạng tài liệu, nên có thể lưu·tra cứu đúng như cách mã ứng dụng xử lý mà không cần ánh xạ ORM phức tạp hay truy vấn join nhiều tầng. Nhờ đó, MongoDB được áp dụng rộng rãi trong các dịch vụ web, di động, IoT xử lý dữ liệu lớn, bán cấu trúc với yêu cầu thay đổi thường xuyên, phân tích thời gian thực, quản lý nội dung, v.v. Tuy nhiên, cần nhận thức rõ rằng nó tương đối kém phù hợp với các nghiệp vụ như kế toán, quyết toán, nơi tính nhất quán mạnh trải trên nhiều tài liệu (join phức tạp·giao dịch nhiều bảng) là cốt lõi.
B. Bối cảnh xuất hiện và sự cần thiết
MongoDB xuất hiện năm 2009, với bối cảnh là sự tăng trưởng bùng nổ của các dịch vụ web cuối thập niên 2000. Khi lưu lượng và dữ liệu vượt quá giới hạn của mở rộng dọc (scale-up), nhu cầu gom nhiều máy chủ thương mại giá rẻ để mở rộng ngang (scale-out) tăng lên. Đồng thời, khi phát triển agile lan rộng, sự cứng nhắc của mô hình quan hệ — phải migrate schema mỗi lần thay đổi — bị chỉ ra là nút thắt làm giảm tốc độ phát triển. Tức là sự cần thiết của MongoDB bắt nguồn từ việc ba yêu cầu "schema linh hoạt + mở rộng ngang quy mô lớn + năng suất phát triển" cùng tăng lên. Xét theo định lý CAP, MongoDB về cơ bản ưu tiên tính nhất quán (C) và khả năng chịu phân mảnh (P), nhưng áp dụng sự thỏa hiệp linh hoạt cho phép điều chỉnh mức độ sẵn sàng·nhất quán bằng cấu hình.
2. Mô hình dữ liệu và cấu trúc lưu trữ
Cấu trúc logic của MongoDB sẽ rõ ràng khi đối chiếu với mô hình quan hệ. Database là đơn vị cao nhất chứa nhiều collection, và collection tương ứng với bảng trong mô hình quan hệ nhưng không áp đặt schema. Collection chứa nhiều document, và document tương ứng với hàng (Row) trong mô hình quan hệ. Mỗi document là tập hợp các cặp trường-giá trị, được lưu nội bộ dưới định dạng BSON (Binary JSON). BSON là định dạng nhị phân hóa JSON, hỗ trợ không chỉ chuỗi, số nguyên, boolean mà cả các kiểu bổ sung như ngày (Date), dữ liệu nhị phân, ObjectId, đồng thời nâng cao tốc độ phân tích cú pháp và hiệu quả lưu trữ.
flowchart LR
DB[("Database")] --> C1["Collection<br/>(VD: users)"]
DB --> C2["Collection<br/>(VD: orders)"]
C1 --> D1["Document<br/>(JSON/BSON)"]
C1 --> D2["Document<br/>(JSON/BSON)"]
D1 --> F1["_id: ObjectId"]
D1 --> F2["name, email ..."]
D1 --> F3["address: đối tượng lồng nhau"]
D1 --> F4["orders: mảng"]
style DB fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px
style D1 fill:#eef7ee,stroke:#2f8f2f,stroke-width:2px
Mọi document bắt buộc có trường _id; nếu không chỉ định, MongoDB tự động sinh ObjectId 12 byte (timestamp + định danh máy + bộ đếm) để bảo đảm tính duy nhất toàn cục. Trường _id này tự động được gắn chỉ mục mặc định. Kích thước tối đa của một document bị giới hạn ở 16MB, và các tệp dung lượng lớn hơn (hình ảnh, video, v.v.) được chia thành các chunk và lưu theo một quy ước riêng gọi là GridFS. Giới hạn kích thước document cũng đóng vai trò hướng dẫn thiết kế ngăn các trường mảng phình to vô hạn (unbounded array).
Thế mạnh của mô hình hướng tài liệu là "tính cục bộ (locality) của dữ liệu liên quan". Nếu dữ liệu được đọc cùng lúc nằm vật lý trong một document thì I/O đĩa giảm và tra cứu nhanh. Ngược lại, nếu cố nhúng dữ liệu được cập nhật thường xuyên hoặc dùng chung ở nhiều nơi thì document phình to và chi phí cập nhật tăng. Vì vậy, lựa chọn nhúng (embedding) hay tham chiếu (referencing) sẽ được bàn ở phần sau trở thành quyết định cốt lõi trong mô hình hóa MongoDB.
A. Đặc điểm chính
| Đặc điểm | Nội dung | Nguyên lý·hiệu quả |
|---|---|---|
| Hướng tài liệu | Lưu dưới dạng tài liệu JSON/BSON, biểu diễn lồng nhau·mảng | Giảm không tương thích trở kháng giữa đối tượng và tài liệu |
| Schema linh hoạt | Không có schema cố định (tự do thêm trường) | Đáp ứng phát triển agile·thay đổi thường xuyên |
| Mở rộng ngang | Lưu trữ·mở rộng phân tán bằng sharding | Xử lý dữ liệu lớn bằng scale-out |
| Sẵn sàng cao | Dự phòng bằng replica set | Chuyển đổi dự phòng tự động (failover) |
| Chỉ mục·tổng hợp | Nhiều loại chỉ mục, aggregation pipeline | Xử lý truy vấn·phân tích phức tạp ngay trong DB |
Không dừng lại ở việc liệt kê đặc điểm, nếu xem "vì sao có được các đặc điểm đó", sẽ thấy gốc rễ của tất cả đều nằm ở mô hình tài liệu. Tính linh hoạt schema xuất phát từ việc collection không áp đặt cấu trúc document; mở rộng ngang khả thi vì có thể gắn shard key vào document để phân phối lên máy chủ theo khoảng hoặc hash; và sẵn sàng cao dễ tự động hóa vì sao chép theo đơn vị document tương đối đơn giản. Tức là các đặc điểm của MongoDB không phải là các chức năng độc lập mà là hệ quả phái sinh từ một lựa chọn thiết kế duy nhất là mô hình tài liệu.
3. Kiến trúc: Replica set và Sharding
Kiến trúc vận hành của MongoDB gồm hai trục chính: replica set đảm nhiệm tính sẵn sàng cao và sharding đảm nhiệm mở rộng ngang. Hai trục này được dùng kết hợp, và trong môi trường production thực tế, cấu trúc chuẩn là mỗi shard tự nó là một replica set.
flowchart TB
App["Ứng dụng"] --> R["mongos<br/>(bộ định tuyến truy vấn)"]
R --> CFG["Config Server<br/>(metadata·vị trí chunk)"]
R --> S1["Shard A"]
R --> S2["Shard B"]
subgraph RS_A["Shard A = Replica Set"]
P1["Primary"] --> Sec1["Secondary"]
P1 --> Sec2["Secondary"]
end
S1 --- RS_A
style R fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px
style P1 fill:#fde8e8,stroke:#d64545,stroke-width:2px
A. Replica set và tính sẵn sàng cao
Replica set là cấu trúc sao chép cùng một dữ liệu lên nhiều node, gồm một primary nhận ghi và nhiều secondary sao chép lại. Thao tác ghi của client được xử lý tại primary, lịch sử thay đổi được ghi vào một collection đặc biệt gọi là oplog (operation log) và lan truyền bất đồng bộ đến các secondary. Nếu primary không phản hồi do sự cố, các node còn lại bầu chọn primary mới bằng thuật toán đồng thuận (election). Việc chuyển đổi dự phòng tự động (failover) này thường hoàn tất trong vài giây đến vài chục giây, giảm thiểu gián đoạn dịch vụ.
Các khái niệm quan trọng trong replica set là "Write Concern" và "Read Preference". Write Concern quy định cần bao nhiêu node xác nhận thì thao tác ghi được coi là thành công. Ví dụ, w:1 chỉ cần primary xác nhận, còn w:majority cần đa số node xác nhận nên an toàn hơn nhưng độ trễ lớn hơn. Tức là chính ứng dụng trực tiếp điều chỉnh sự thỏa hiệp giữa tính nhất quán và hiệu năng. Read Preference quy định chỉ đọc từ primary hay cho phép đọc cả từ secondary để phân tán tải đọc. Tuy nhiên, secondary có thể trả về dữ liệu hơi cũ do độ trễ sao chép (replication lag), nên các truy vấn cần dữ liệu mới nhất phải đọc từ primary.
B. Sharding và mở rộng ngang
Sharding là kỹ thuật chia một collection lớn và lưu trên nhiều shard dựa theo shard key. Dữ liệu được chia theo đơn vị chunk và phân tán cho từng shard, và khi chunk dồn vào một shard cụ thể, balancer tự động phân phối lại. Ứng dụng không cần biết về sự phân tán này; bộ định tuyến mongos chuyển truy vấn đến shard phù hợp, và Config Server quản lý metadata về chunk nào nằm ở shard nào.
Thành bại của sharding phụ thuộc vào việc chọn shard key. Nếu dùng khóa tăng đơn điệu (VD: timestamp) làm shard key, các thao tác ghi mới nhất luôn dồn vào một shard duy nhất tạo ra "điểm nóng (hotspot)", làm mất hiệu quả mở rộng. Vì vậy phải chọn khóa có cardinality cao, giá trị phân tán đều và phù hợp với mẫu truy vấn. Để giảm nhẹ vấn đề này, MongoDB cung cấp hash sharding, shard key phức hợp gom nhiều trường, và phân tán dựa trên hash để làm tản mát các khóa tăng nhanh. Vì chọn sai shard key thì sau này rất khó sửa, nên việc phân tích kỹ mẫu truy cập ngay từ đầu giai đoạn thiết kế là quan trọng.
4. Chỉ mục và Aggregation pipeline
Lý do MongoDB mạnh mẽ vượt xa một kho khóa-giá trị đơn thuần nằm ở các chức năng chỉ mục và tổng hợp phong phú. Không có chỉ mục, truy vấn phải thực hiện quét toàn bộ collection (collection scan) và trở nên chậm đi nhanh chóng khi dữ liệu tăng. MongoDB hỗ trợ không chỉ chỉ mục đơn trường mà còn chỉ mục phức hợp gom nhiều trường, chỉ mục multikey đánh chỉ mục từng phần tử của mảng, chỉ mục tìm kiếm văn bản, chỉ mục không gian địa lý (2dsphere) cho truy vấn theo vị trí, và chỉ mục TTL tự động xóa document sau một khoảng thời gian nhất định. Chỉ mục TTL hữu ích để tự động hết hạn các dữ liệu có vòng đời xác định như session, log, cache.
Aggregation pipeline là framework nối tuần tự nhiều giai đoạn (stage) để biến đổi và tổng hợp dữ liệu. Bằng cách lọc với $match, tổng hợp theo nhóm với $group, sắp xếp với $sort và join với collection khác bằng $lookup (tương ứng join trong mô hình quan hệ), các truy vấn phân tích phức tạp được xử lý bên trong DB. Vì cấu trúc giống pipe của Unix — đầu ra của giai đoạn trước là đầu vào của giai đoạn sau — dữ liệu lớn được xử lý phía máy chủ thay vì kéo về ứng dụng, giúp giảm chi phí mạng.
5. So sánh với DB quan hệ: Lý do tạo nên khác biệt
Khi so sánh hai mô hình, hiểu "vì sao có sự khác biệt đó" quan trọng hơn là liệt kê các hạng mục. Khác biệt căn bản bắt nguồn từ mô hình dữ liệu. Mô hình quan hệ chuẩn hóa dữ liệu để loại bỏ trùng lặp và kết hợp bằng join nên có lợi cho tính nhất quán, nhưng phải chấp nhận chi phí join và sự cứng nhắc của schema. MongoDB gom dữ liệu liên quan vào document để giảm join, đổi lại chấp nhận một phần trùng lặp và giao phó nhiều hơn việc quản lý tính nhất quán cho ứng dụng.
| Hạng mục | Quan hệ (RDB) | MongoDB | Lý do khác biệt |
|---|---|---|---|
| Mô hình dữ liệu | Bảng·hàng (có cấu trúc) | Tài liệu (linh hoạt) | Chuẩn hóa vs ưu tiên tính cục bộ |
| Schema | Cố định trước (schema-on-write) | Linh hoạt (schema-on-read) | Collection không áp đặt cấu trúc |
| Quan hệ | Join | Lồng nhau·tham chiếu trong tài liệu ($lookup) | Lưu cùng nhau dữ liệu được đọc cùng nhau |
| Mở rộng | Chủ yếu dọc (scale-up) | Ngang (sharding) | Có thể phân tán bằng shard key trên tài liệu |
| Tính nhất quán | ACID mạnh | Tính nguyên tử theo tài liệu + giao dịch nhiều tài liệu (4.0+) | Ban đầu nới lỏng tính nhất quán để mở rộng |
| Truy vấn | SQL chuẩn | MQL·aggregation pipeline | Ngôn ngữ truy vấn phù hợp cấu trúc tài liệu |
Hàm ý thực tiễn không phải là "cái nào tốt hơn" mà là "phù hợp với workload nào". Ví dụ, trong thương mại điện tử, dữ liệu như danh mục sản phẩm — mỗi mục có thuộc tính khác nhau và thay đổi thường xuyên — thì schema linh hoạt của MongoDB có lợi, nhưng nghiệp vụ như thanh toán, quyết toán phải cập nhật nguyên tử số dư của nhiều tài khoản thì giao dịch mạnh của mô hình quan hệ an toàn hơn. MongoDB cũng đã hỗ trợ giao dịch nhiều document trên replica set từ 4.0 và giao dịch phân tán trong môi trường sharding từ 4.2 nên khoảng cách này đã được thu hẹp, nhưng lạm dụng giao dịch sẽ làm mất lợi thế hiệu năng của mô hình tài liệu, nên nguyên tắc là chỉ dùng "ở nơi cần thiết".
A. Nhúng vs Tham chiếu (trường hợp cụ thể)
Hãy xem lựa chọn cốt lõi trong mô hình hóa là nhúng (embedding) và tham chiếu (referencing) qua ví dụ dịch vụ blog. Trong quan hệ giữa bài viết và bình luận, nếu số bình luận ít và luôn được tra cứu cùng bài viết thì nhúng bình luận thành mảng bên trong document bài viết là có lợi. Đọc một lần mà không cần join, và cập nhật nguyên tử theo document cũng được bảo đảm. Ngược lại, nếu bài viết nổi tiếng có thể có hàng chục nghìn bình luận, sẽ chạm giới hạn document 16MB và document phình to, mỗi lần cập nhật phải ghi lại một document lớn. Trường hợp này, tham chiếu — tách bình luận ra collection riêng và tham chiếu bằng _id của bài viết — là tốt hơn. Tức là mẫu truy cập "có đọc cùng nhau không, có thể lớn đến đâu, được cập nhật thường xuyên đến mức nào" là tiêu chí lựa chọn, và phán đoán này chi phối hiệu năng đến hàng chục lần.
6. Chuyên sâu: Xu hướng mới và ứng dụng thực tế
MongoDB đã vượt qua hình ảnh NoSQL thuần túy ban đầu, tiến hóa thành nền tảng dữ liệu đa dụng bằng cách tăng cường tính nhất quán và chức năng phân tích. Việc hỗ trợ giao dịch ACID nhiều document (4.0/4.2) nêu ở trên là bước ngoặt tiêu biểu, phá vỡ quan niệm "NoSQL không có giao dịch". Các phiên bản sau đó đưa vào collection chuỗi thời gian (Time Series) để lưu·nén hiệu quả dữ liệu IoT và giám sát, và tăng cường chức năng mã hóa theo trường (Client-Side Field Level Encryption, Queryable Encryption) cho phép lưu·truy vấn thông tin nhạy cảm trong trạng thái được mã hóa từ phía client. Storage engine cũng chuyển chuẩn từ MMAPv1 trước đây sang WiredTiger hỗ trợ kiểm soát đồng thời theo document và nén, cải thiện hiệu năng ghi và hiệu quả lưu trữ.
Về mặt đám mây, dịch vụ được quản lý MongoDB Atlas đã trở thành xu hướng chủ đạo. Ngoài sao lưu, mở rộng, giám sát tự động, Atlas còn tích hợp Atlas Search (dựa trên Lucene) cho tìm kiếm toàn văn và tìm kiếm vector (Atlas Vector Search). Đặc biệt, tìm kiếm vector được chú ý với vai trò lưu embedding và tìm kiếm tương đồng trong pipeline RAG (sinh tăng cường truy xuất) của AI tạo sinh, tạo nên xu hướng "xử lý dữ liệu vận hành và vector trong cùng một DB". Về trường hợp thực tế, các doanh nghiệp lớn về truyền thông, trò chơi, thương mại điện tử đã áp dụng MongoDB cho dữ liệu có schema đa dạng và quy mô lớn như hồ sơ người dùng, session thời gian thực, danh mục sản phẩm, với các mẫu ứng dụng tiêu biểu như xây dựng Single View hay backend gợi ý cá nhân hóa thời gian thực. Mặt khác, giấy phép đã chuyển sang SSPL (Server Side Public License) năm 2018, tạo ra ràng buộc đối với việc bán lại trên đám mây, và đây là điểm cần lưu ý trong thực tiễn vì cần rà soát giấy phép khi áp dụng.
7. Các điểm cần lưu ý và hàm ý
Từ góc nhìn Kỹ sư chuyên nghiệp (Professional Engineer), việc áp dụng MongoDB phải là quyết định kiến trúc đánh giá tổng hợp đặc tính workload và yêu cầu nhất quán, vượt ra ngoài nhận thức đơn thuần là "DB nhanh và linh hoạt".
Mô hình hóa dữ liệu chi phối hiệu năng. Thay vì áp dụng nguyên các quy tắc chuẩn hóa như mô hình quan hệ, cần phân tích trước mẫu truy cập thực tế của ứng dụng (đọc và ghi những gì cùng nhau) để quyết định nhúng hay tham chiếu. Schemaless không có nghĩa là không cần thiết kế; ngược lại, thiết kế dựa trên mẫu truy cập càng trở nên quan trọng. Mô hình hóa sai dẫn đến document phình to và tra cứu kém hiệu quả, khó bù đắp ngay cả bằng phần cứng.
Chọn shard key là quyết định khó đảo ngược. Phải tổng hợp cardinality, độ phân tán và độ phù hợp với mẫu truy vấn để chọn thận trọng ngay từ đầu, và tránh điểm nóng do khóa tăng đơn điệu. Thay đổi shard key sau khi đã cần mở rộng kéo theo di chuyển dữ liệu quy mô lớn, nên với hệ thống dự kiến có dung lượng lớn phải lập chiến lược sharding ngay ở giai đoạn thiết kế.
Điều chỉnh mức độ nhất quán phù hợp với workload. Thông qua Write Concern, Read Preference và giao dịch có thể thỏa hiệp tinh tế giữa tính nhất quán với hiệu năng·tính sẵn sàng. Chính sách phân biệt theo cấp độ dữ liệu là phù hợp: dữ liệu tài chính·quyết toán bảo đảm an toàn bằng
w:majorityvà giao dịch, còn dữ liệu cho phép chút độ trễ như log·thống kê thì dùng cấu hình nới lỏng để đạt hiệu năng.Tiếp cận theo polyglot persistence. Thay vì giải quyết mọi thứ bằng một DB, cách tiếp cận hiện đại là kết hợp theo đặc tính dữ liệu: linh hoạt·dung lượng lớn·bán cấu trúc dùng MongoDB, nhất quán mạnh·join phức tạp dùng RDB, cache·session dùng Redis, v.v. Việc MongoDB mở rộng sang chuỗi thời gian·tìm kiếm vector làm rộng thêm biên độ kết hợp này, nhưng năng lực cốt lõi là thiết kế kết hợp thế mạnh của từng kho lưu trữ trên tiền đề không có giải pháp vạn năng.
Rà soát đồng thời rủi ro vận hành·bảo mật·giấy phép. Vận hành replica set·sharding có nhiều node hơn mô hình quan hệ nên độ phức tạp vận hành cao, do đó cần cân nhắc dùng dịch vụ được quản lý như Atlas, bảo vệ thông tin nhạy cảm bằng mã hóa theo trường·kiểm soát truy cập, và kiểm tra trước ảnh hưởng của giấy phép SSPL đến mô hình kinh doanh của công ty (đặc biệt là bán lại SaaS).
Tài liệu tham khảo
- Tài liệu chính thức của MongoDB: https://www.mongodb.com/docs/manual/
- MongoDB Data Modeling: https://www.mongodb.com/docs/manual/data-modeling/
- MongoDB Sharding: https://www.mongodb.com/docs/manual/sharding/
- MongoDB Transactions: https://www.mongodb.com/docs/manual/core/transactions/
Tóm tắt một câu: MongoDB là NoSQL hướng tài liệu lưu dữ liệu dưới dạng tài liệu tương tự JSON (BSON), có thế mạnh là schema linh hoạt, mở rộng ngang bằng sharding và sẵn sàng cao bằng replica set; mô hình hóa nhúng/tham chiếu và lựa chọn shard key chi phối hiệu năng, và dù đã tiến hóa với giao dịch nhiều tài liệu, chuỗi thời gian, tìm kiếm vector, các nghiệp vụ cần nhất quán mạnh nên được vận hành song song với mô hình quan hệ theo hướng polyglot.