Tài liệu ôn thi CUỐI KỲ môn Mô hình hóa dữ liệu MongoDB Trường Đại học Công Nghiệp Thành phố Hồ Chí Minh (IUH) Tài liệu Ôn thi CUỐI KỲ môn Mô hình hóa dữ liệu NoSQL MongoDB (IUH - 2101720) Tài liệu tổng hợp các dạng bài tập trọng tâm và hướng dẫn giải chi tiết cho kỳ thi cuối kỳ môn Mô hình hóa dữ liệu NoSQL, tập trung vào hệ quản trị MongoDB với thời gian làm bài 60 phút: Câu 1: Thiết kế mô hình vật lý: Hướng dẫn xây dựng các collection và xác định mối quan hệ giữa các trường tham chiếu dựa trên đặc tả dữ liệu thực tế. Câu 2: Áp dụng Design Patterns: Phân tích chuyên sâu cách áp dụng các mẫu thiết kế tối ưu như: Extended Reference Pattern: Giảm thiểu việc sử dụng $lookup bằng cách nhúng các thông tin thường dùng trực tiếp vào tài liệu (ví dụ: thông tin khách hàng trong hợp đồng bảo hiểm). Computed Pattern: Tính toán và lưu sẵn các kết quả (như tổng số tiền bảo hiểm) để giảm tải cho CPU và tăng tốc độ truy vấn. Bucket Pattern: Tối ưu hóa việc lưu trữ các mảng dữ liệu lớn trong cùng một tài liệu. Câu 3 & 4: Nâng cao hiệu suất hệ thống: Tổng hợp lý thuyết và giải pháp thực tế cho Working Set, thiết kế Schema, tối ưu hóa Index, Query và kỹ thuật Sharding để xử lý dữ liệu lớn. Tài liệu có hình ảnh minh họa cấu trúc collection và lý do lựa chọn các giải pháp tối ưu, rất phù hợp cho sinh viên cần nắm vững tư duy thiết kế database hiện đại.
Chương 4
Attribute Pattern
- Được sử dụng để tổ chức các thuộc tính ( fields ) linh hoạt trong 1 tài liệu
+ Các thuộc tính này không cố định or hiểm gặp
+ Có nhiều thuộc tính chung giữa các tài liệu nhưng không phải tài liệu nào cũng có đầy đủ tất cả các thuộc tính
+ Cần tối ưu hóa việc tìm kiếm và lập chỉ mục ( indexing )
2.1.2 Khi nào nên dùng Attribute Pattern
1 Thuộc tính không cố định (Dynamic Attributes): o Khi các tài liệu có thể có các trường khác nhau giữa các bản ghi hoặc có nhiều thuộc tính không phổ biến. o Ví dụ: Dữ liệu sản phẩm thương mại với các thuộc tính như màu sắc, kích thước, loại vật liệu.
2 Giảm số lượng chỉ mục: o Khi không muốn tạo chỉ mục riêng biệt cho từng thuộc tính và cần sử dụng một chỉ mục duy nhất cho tất cả các thuộc tính.
3 Trường hợp cần tìm kiếm dựa trên nhiều thuộc tính: o Khi cần tìm kiếm hoặc lọc dữ liệu theo các thuộc tính khác nhau mà không biết trước tất cả các trường có thể tồn tại.
4 Khi dữ liệu không đồng nhất: o Ví dụ: Hệ thống lưu trữ dữ liệu đa quốc gia, nơi các thuộc tính có thể thay đổi tùy theo khu vực hoặc yêu cầu khách hàng.
2.1.3 Khi nào không nên dùng Attribute Pattern
Khi dữ liệu ổn định và có cấu trúc cố định:
+ Nếu tất cả tài liệu có các trường giống nhau, không cần dùng Attribute Pattern.
+ Ví dụ: Cơ sở dữ liệu lưu trữ thông tin nhân viên với các trường cố định như tên, tuổi, phòng ban.
Khi yêu cầu truy vấn phức tạp và hiệu năng cao:
+ Truy vấn Attribute Pattern có thể chậm với tập dữ liệu lớn hoặc nhiều thuộc tính.
2.1.4 Lợi ích của Attribute Pattern
1 Giảm số lượng chỉ mục
+ Thay vì tạo chỉ mục riêng cho mỗi thuộc tính, bạn chỉ cần một chỉ mục chung cho mảng chứa các cặp giá trị ( key – value )
2 Linh hoạt o Hỗ trợ lưu trữ các thuộc tính không cố định hoặc hiếm gặp mà không ảnh hưởng đến cấu trúc tổng thể của tài liệu. o Dễ dàng thêm các thuộc tính mới mà không cần thay đổi schema hiện tại.
3 Tối ưu hóa tìm kiếm và chỉ mục: o Chỉ cần một chỉ mục chung cho cặp k (key) và v (value), thay vì tạo chỉ mục riêng cho từng thuộc tính. o Dễ dàng truy vấn và sắp xếp dựa trên các thuộc tính khác nhau trong cùng một cấu trúc.
4 Giảm phức tạp trong thiết kế schema: o Giải quyết vấn đề tài liệu có nhiều trường (fields) không giống nhau hoặc không phổ biến. o Giảm rủi ro khi phải dự đoán trước tất cả các thuộc tính có thể xuất hiện trong dữ liệu.
5 Tính tái sử dụng o Mẫu này có thể áp dụng cho nhiều loại dữ liệu khác nhau, từ sản phẩm thương mại đến các cấu trúc dữ liệu linh hoạt trong các ứng dụng lớn.
+ Dùng để quản lý các thuộc tính có đặc điểm chung hoặc không đồng nhất giữa các đối tượng.
+ Giảm số lượng chỉ mục cần tạo.
Một hệ thống lưu trữ thông tin sản phẩm:
Một số sản phẩm có màu sắc và kích thước.
Một số khác có pin và công suất.
Một số chỉ có nhãn hiệu và nơi sản xuất.
- Tìm sản phẩm có màu sắc là "blue" :{ "add_specs.k": "color", "add_specs.v":
- Tìm sản phẩm có cả màu xanh và kích thước 6.5 inches: :
Tại sao sử dụng Attribute Pattern ở đây?
Các sản phẩm có thể có nhiều thuộc tính khác nhau như màu sắc, kích thước, pin, v.v., việc lưu trữ các thuộc tính này dưới dạng mảng cặp key-value mang lại sự linh hoạt trong quản lý dữ liệu, giúp không cần thay đổi cấu trúc tài liệu khi thêm mới thuộc tính Đồng thời, phương pháp này tối ưu hóa khả năng tìm kiếm nhờ vào việc sử dụng duy nhất một chỉ mục cho add_specs.k và add_specs.v, cho phép tìm kiếm theo bất kỳ thuộc tính nào một cách nhanh chóng và hiệu quả.
Nếu không dùng Attribute Pattern, schema có thể trở nên phức tạp và khó bảo trì khi có quá nhiều trường hoặc trường hiếm gặp.
Extented Reference pattern
Thiết kế schema trong MongoDB giúp giảm số lượng phép nối (joins) bằng cách nhúng một phần thông tin từ các tài liệu liên quan vào tài liệu chính, tối ưu hóa hiệu suất truy vấn Sử dụng mô hình one-to-many hoặc many-to-one phù hợp với các trường hợp cần truy xuất dữ liệu từ cả hai phía của mối quan hệ Điều này đặc biệt quan trọng khi các truy vấn thường xuyên yêu cầu thông tin từ cả hai bên của mối liên kết, giúp tăng tốc độ xử lý và giảm tải cho hệ thống MongoDB.
2.2.2 Khi nào nên dùng Extended Reference Pattern
- Ứng dụng cần thực hiện nhiều phép nối giữa các collection
+ Khi truy vấn thường xuyên phải kết hợp dữ liệu từ nhiều tài liệu, việc sử dụng extended reference pattern giúp giảm tải cho hệ thống
- Truy vấn tập trung vào phía “nhiều” của mối quan hệ
Khi phần lớn lượt truy cập tập trung vào các tài liệu phía "nhiều" như đơn hàng, việc nhúng thông tin cần thiết từ phía "ít" như khách hàng sẽ giúp tối ưu hóa hiệu suất hoạt động Việc tích hợp dữ liệu này không những giảm thời gian truy xuất mà còn nâng cao độ chính xác của thông tin, từ đó mang lại hiệu quả tổng thể cao hơn cho hệ thống quản lý Do đó, tập trung vào nội dung chính và bổ sung dữ liệu quan trọng từ các nguồn ít thường xuyên truy cập sẽ giúp nâng cao hiệu quả công việc và trải nghiệm người dùng.
- Dữ liệu nhúng thay đổi ít hoặc không thay đổi :
+ Các trường nhúng nên là dữ liệu ít thay đổi để giảm rủi ro mất đồng bộ
2.2.3 Khi nào không nên dùng Extended Reference Pattern
- Dữ liệu nhúng thay đổi thường xuyên
+ Nếu các trường được nhúng thay đổi liên tục, việc giữ chúng đồng bộ giữa các tài liệu sẽ gây khó khăn và tăng chi phí bảo trì.
- Kích thước tài liệu quá lớn
+ Nếu nhúng nhiều trường, tài liệu có thể vượt giới hạn 16MB của MongoDB
- Dữ liệu không cần truy cập thường xuyên
+ Nếu dữ liệu được nhúng không được truy vấn thường xuyên, việc lưu trữ nó trong tài liệu chính sẽ lãng phí tài nguyên.
2.2.4 Lợi ích của Extended Reference Pattern
+ Truy vấn trực tiếp trên một tài liệu duy nhất thay vì thực hiện phép nối ( join ) phức tạp.
- Đơn giản hóa truy vấn
+ Các truy vấn trở nên ngắn gọn và dễ viết hơn do không cần sử dụng $lockup
- Giảm tải cho cơ sở dữ liệu
+ Tránh việc thực hiện các phép nối đòi hỏi nhiều tài nguyên.
- Một hệ thống quản lý đơn hàng và khách hàng
- Quan hệ: một khách hàng có nhiều đơn hàng ( one to many )
- Trước khi sử dụng pattern
Collection Khách hàng Collection hóa đơn
Phải dùng $lookup để truy vấn, tốn thời gian, tài nguyên, truy vấn phức tạp hơn
Sau khi áp dụng Extended Reference pattern
Collection Khách hàng Collection Đơn hàng
1 Tại sao sử dụng Extended Reference Pattern?
Thay vì sử dụng phép $lookup để lấy thông tin khách hàng từ collection Customer, các trường như customer_name và customer_address được nhúng trực tiếp vào collection đơn hàng Điều này giúp cải thiện tốc độ truy vấn liên quan đến đơn hàng, giảm thời gian xử lý và nâng cao hiệu suất hệ thống Nhúng dữ liệu khách hàng vào collection đơn hàng là giải pháp tối ưu cho các truy vấn cần thông tin khách hàng nhanh chóng và hiệu quả hơn.
- Không cần phép nối ( join): { "_id": "order456" }
Trả về thông tin đơn hàng và thông tin khách hàng mà không cần tìm kiếm trong collection customer
- Truy vấn đơn giản hơn và nhanh hơn vì dữ liệu khách hàng đã được nhúng vào đơn hàng
- Nếu khách hàng thay đổi địa chỉ customer_address, tất cả các tài liệu đơn hàng liên quan phải được cập nhật để giữ tính đồng bộ.
2.2.6 So sánh trước và sau khi áp dụng Extended Reference Pattern
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Để lưu trữ dữ liệu khách hàng một cách hiệu quả, cần tách biệt dữ liệu khách hàng và sử dụng phép nối $lookup để nhúng thông tin cần thiết của khách hàng vào tài liệu đơn hàng Việc thực hiện phép nối này giúp truy vấn dữ liệu nhanh hơn, đặc biệt trong các hệ thống yêu cầu hiệu suất cao và xử lý dữ liệu lớn Áp dụng đúng quy trình này giúp tăng tốc quá trình truy vấn và quản lý dữ liệu khách hàng một cách tối ưu.
$lookup, phức tạp nhiều truy vấn đọc
Hiệu suất Chậm hơn với tập dữ liệu lớn Nhanh hơn, đặc biệt với nhiều truy vấn đọc
Rủi ro Không có vấn đề đồng bộ dữ liệu
Rủi ro mất đồng bộ nếu thông tin nhúng thay đổi
- Khi nên dùng: cần tăng tốc độ truy vấn, dữ liệu nhúng ít thay đổi, truy vấn thường xuyên tập trung vào phía “nhiều”
- Khi không nên dùng: dữ liệu nhúng thay đổi thường xuyên or tài liệu có nguy cơ vượt quá kích thước giới hạn
- Lợi ích: đơn giản hóa truy vấn, tăng hiệu suất đọc.
- Hạn chế: rủi ro mất đồng bộ dữ liệu và tăng kích thước tài liệu.
Subset Pattern
Subset Pattern giúp tách dữ liệu ít truy cập ra khỏi tài liệu chính để giảm kích thước, từ đó tăng hiệu suất làm việc với các tập dữ liệu lớn (working set) vượt quá khả năng lưu trữ RAM Phương pháp này tối ưu hóa quá trình xử lý dữ liệu và nâng cao hiệu quả hệ thống.
2.3.2 Khi nào nên dùng Subset Pattern
1 Bộ dữ liệu lớn ( working set ) vượt quá RAM
Khi tài liệu chứa quá nhiều thông tin, chỉ một phần thường xuyên được truy cập, và phần còn lại ít sử dụng
2 Tài liệu có nhiều quan hệ One to Many; Many to Many
Chỉ cần truy cập một phần nhỏ trong số các quan hệ
3 Cần tối ưu hóa hiệu suất truy vấn
Khi chỉ cần truy cập dữ liệu thường xuyên, giúp giảm tải bộ nhớ và tối ưu hóa tốc độ truy vấn
2.3.3 Khi không nên dùng Subset Pattern
1 Khi dữ liệu thường xuyên thay đổi
+ Dễ dẫn đến vấn đề đồng bộ giữa tài liệu chính và tài liệu phụ
2 Khi cần truy vấn toàn bộ dữ liệu
+ Nếu truy vấn thường xuyên yêu cầu cả dữ liệu chính và dữ liệu tách ra, hiệu suất sẽ giảm do phải thực hiện $lookup
3 Khi dữ liệu không quá lớn
+ Nếu tài liệu nhỏ và đủ để lưu trong RAM, không cần áp dụng pattern này
2.3.4 Lợi ích của Subset Pattern
1 Giảm kích thước tài liệu
+ Chỉ giữ dữ liệu cần thiết trong tài liệu chính
2 Tăng hiệu suất truy vấn
+ Truy vấn nhanh hơn khi chỉ làm việc với dữ liệu thường xuyên được truy cập
+ Tài liệu nhỏ hơn có thể lưu trữ nhiều hơn trên RAM.
Bối cảnh: hệ thống quản lý phim chứa thông tin chi tiết như dàn diễn viên, đánh giá, nhận xét và bình luận
Tài liệu gốc ( Movies Collection )
Kích thước chứa nhiều dữ liệu không cần thiết trong các truy vấn, gây giảm hiệu suất và làm chậm quá trình xử lý Ngoài ra, kích thước lớn của tài liệu còn ảnh hưởng đến khả năng lưu trữ trong RAM, dẫn đến tăng chi phí truy vấn và giảm tối ưu hóa hệ thống dữ liệu.
Sau khi áp dụng Subset Pattern
Tài liệu chính Tài liệu Phụ
1 Trước khi áp dụng pattern
- Tất cả thông tin ( dàn diễn viên, đánh giá, nhận xét, kịch bản) được lưu trong một tài liệu lớn.
- Truy vấn thường xuyên phải tải toàn bộ dữ liệu, dù chỉ cần một phần nhỏ
2 Sau khi áp dụng pattern
- Chỉ các thông tin thường xuyên truy cập ( tựa đề, diễn viên chính, đánh giá nổi bật) được giữ lại trong tài liệu chính
- Dữ liệu ít được truy cập ( dàn diễn viên đầy đủ, kịch bản đầy đủ ) được tách ra và lưu trong tài liệu phụ
- Tài liệu chính nhỏ gọn hơn: chỉ cần tải dữ liệu quan trọng, tăng hiệu suất truy vấn.
- Dữ liệu phụ có thể truy vấn khi cần: khi cần kịch bản đầy đủ hoặc nhận xét, có thể dùng $lookup để kết hợp với tài liệu phụ
- Nếu thường xuyên truy cập cả 2 loại dữ liệu ( chính và phụ), việc phải thực hiện
$lookup có thể làm giảm hiệu suất
2.3.6 So sánh trước và sau khi áp dụng Subset Pattern
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Kích thước tài liệu lớn chứa nhiều dữ liệu không cần thiết có thể làm giảm hiệu suất hệ thống, trong khi giữ các tài liệu nhỏ hơn chỉ gồm các dữ liệu thường xuyên truy cập giúp tối ưu hóa tốc độ truy vấn Các tài liệu có kích thước lớn thường gây ra truy vấn chậm, ảnh hưởng đến trải nghiệm người dùng và hiệu quả vận hành của hệ thống Do đó, việc phân chia và quản lý dữ liệu dựa trên tần suất truy cập là chiến lược hiệu quả để nâng cao hiệu suất tổng thể.
Việc truy vấn nhanh hơn giúp bạn làm việc hiệu quả hơn chỉ trên dữ liệu chính, giảm thiểu thời gian xử lý Quản lý RAM tiêu tốn nhiều bộ nhớ, gây khó khăn khi xử lý tài liệu lớn, trong khi đó các giải pháp tối ưu giúp tiết kiệm RAM phù hợp hơn với khả năng lưu trữ của hệ thống Độ phức tạp trong quản lý dữ liệu càng thấp, càng dễ dàng vận hành và không cần phân chia dữ liệu phức tạp, phù hợp cho các môi trường làm việc đơn giản và hiệu quả.
Tăng thêm phức tạp do phải quản lý tài liệu phụ
Computed Pattern
Computed Pattern là một dạng thiết kế schema trong MongoDB, trong đó kết quả của các phép tính phức tạp hoặc lặp đi lặp lại được tính toán trước và lưu trữ vào tài liệu Phương pháp này giúp tối ưu hóa hiệu năng hệ thống bằng cách giảm thiểu tải xử lý khi thực hiện các phép tính tương tự nhiều lần, tiết kiệm thời gian và tài nguyên cho hệ thống của bạn.
4.1 Khi nào nên dùng Computed Pattern
1 Phép tính phức tạp hoặc tốn kém tài nguyên
- Khi cần thực hiện các phép tính như tổng, trung bình hoặc tổng hợp dư liệu thường xuyên và các kết quả này ít thay đổi
2 Tăng tốc độ truy vấn
- Khi truy vấn yêu cầu tính toán nhiều lần trên cùng một tập dữ liệu, Computed
Pattern giúp giảm độ trễ ( latency )
3 Dữ liệu không thay đổi thường xuyên
- Dữ liệu nguồn không bị cập nhật thường xuyên, giúp kết quả tính toán không phải đồng bộ lại quá nhiều lần.
2.4.2 Khi không nên dùng Computed Pattern
1 Dữ liệu thay đổi liên tục
- Nếu dữ liệu gốc thay đổi thường xuyên, việc đồng bộ kết quả tính toán sẽ tốn kém tài nguyên và phức tạp.
2 Dữ liệu tính toán không được sử dụng thường xuyên
- Nếu kết quả tính toán hiếm khi được truy vấn, việc lưu trữ chứng có thể lãng phí không gian.
- Nếu phép tính đơn giản và không ảnh hưởng lớn đến hiệu suất, Computed Pattern không cần thiết.
2.4.3 Lợi ích của Computed Pattern
1 Giảm tài nguyên sử dụng
- Tiết kiệm CPU và bộ nhớ vì các phép tính không phải thực hiện lặp lại.
2 Tăng tốc độ truy vấn
- Dữ liệu đã được tính toán sẵn giúp truy vấn nhanh hơn, đặc biệt với tập dữ liệu lớn.
3 Đơn giản hóa truy vấn
- Người dùng không cần viết các phép tính phức tạp trong truy vấn, chỉ cần đọc dữ liệu đã tính toán.
Tài liệu gốc( Screenings Collection)
- Truy vấn để tính tổng doanh thu
Hạn chế: phải tính toán lại tổng doanh thu mỗi lần truy vấn, tốn tài nguyên CPU và thời gian nếu dữ liệu lớn.
Tài liệu đã áp dụng Pattern ( Movies Collection)
Cách cập nhật dữ liệu
Khi có thêm một suất chiếu mới Cập nhật tổng doanh thu
Truy vấn để lấy tổng doanh thu Kết quả
1 Trước khi áp dụng Pattern
- Tổng doanh thu phải được tính toán lại từ tất cả các suất chiếu mỗi khi truy vấn
- Với nhiều dữ liệu, phép tính này tốn thời gian và tài nguyên.
2 Sau khi áp dụng Pattern
- Tổng doanh thu được lưu trữ sẵn trong tài liệu Movies Collection
- Khi có dữ liệu mới ( suất chiếu mới ), chỉ cần cập nhật giá trị total_revenues.
- Tăng tốc truy vấn: truy vấn nhanh hơn vì không cần thực hiện phép tính,
- Giảm tài nguyên: Hạn chế việc đọc toàn bộ tài liệu Screenings Collection
2.4.5 So sánh trước và sau khi áp dụng Computed Pattern
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Hiệu suất truy vấn có thể chậm do yêu cầu tính toán lại từ dữ liệu gốc, trong khi dữ liệu đã được lưu sẵn giúp truy vấn nhanh hơn Việc sử dụng tài nguyên như CPU và RAM được tiết kiệm đáng kể vì hệ thống chỉ cần đọc giá trị đã lưu trữ Quá trình cập nhật dữ liệu đơn giản, chỉ cần thêm các dữ liệu mới mà không cần tính toán phức tạp.
Trong quá trình phát triển ứng dụng, việc cập nhật giá trị tính sẵn là rất quan trọng để đảm bảo dữ liệu luôn phản ánh chính xác thực tế Các ứng dụng phù hợp cần xử lý dữ liệu thay đổi liên tục, đồng thời đối mặt với những thách thức như dữ liệu ít biến động hoặc các phép tính phức tạp Điều này đòi hỏi hệ thống phải tối ưu để duy trì hiệu suất cao và đảm bảo tính chính xác của thông tin.
Bucket pattern
Bucket Pattern là một thiết kế schema trong MongoDB, trong đó nhiều bản ghi
Các tài liệu nhỏ có cùng đặc điểm được nhóm lại thành một bucket để tạo thành một tài liệu duy nhất, giúp giảm số lượng tài liệu trong collection và tối ưu hóa truy vấn Phương pháp này đặc biệt hữu ích khi làm việc với dữ liệu có cấu trúc lặp lại, chẳng hạn như dữ liệu cảm biến, nhật ký (log) hoặc dữ liệu theo thời gian, giúp nâng cao hiệu quả xử lý và phân tích dữ liệu.
2.5.2 Khi nào nên dùng Bucket Pattern
1 Dữ liệu có tính lặp lại cao
VD: dữ liệu cảm biến được ghi lại theo thời gian, có giá trị thường xuyên thay đổi nhưng mang tính định kỳ.
2 Số lượng tài liệu lớn
Nếu hệ thống lưu trữ hàng triệu tài liệu nhỏ, Bucket Pattern giúp giảm số lượng tài liệu và chi phí quản lý.
MongoDB phải xử lý và quản lý nhiều tài liệu riêng lẻ; Bucket Pattern giảm số lượng tài liệu cần xử lý.
4 Truy vấn thường tập trung vào nhóm dữ liệu
Khi truy vấn cần lấy tất cả dữ liệu trong 1 nhóm (VD: dữ liệu trong 1 khoảng thời gian cụ thể )
2.5.3 Khi không nên dùng Bucket Pattern
1 Dữ liệu thường xuyên cập nhật hoặt xóa
- Nếu phải thay đổi hoặc xóa dữ liệu trong 1 bucket, việc sửa đổi bucket sẽ tốn kém hơn
2 Dữ liệu không được truy vấn theo nhóm
- Nếu dữ liệu được truy vấn riêng lẻ, Bucket Pattern sẽ làm tăng chi phí vì phải tải cả bucket để lấy một bản ghi
3 Kích thức bucket vượt quá giới hạn tài liệu MongoDB
- Nếu bucket trở nên quá lớn ( vượt 16MB) nó không thể được lưu trữ trong một tài liệu duy nhất.
2.5.4 Lợi ích của Bucket Pattern
1 Giảm số lượng tài liệu
- Giảm áp lực lên hệ thống quản lý tài liệu của MongoDB, giúp cải thiện hiệu suất.
2 Tối ưu hóa truy vấn nhóm
- Truy vấn toàn bộ bucket ( nhóm ) nhanh hơn so với việc truy vấn từng tài liệu nhỏ lẻ.
3 Tiết kiệm không gian lưu trữ
- Gom nhiều bản ghi vào một tài liệu giúp giảm chi phí lưu trữ metadata của từng tài liệu.
4 Dễ dàng làm việc với dữ liệu nhóm
- Bucket Pattern phù hợp khi cần xử lý dữ liệu trong một khoảng thời gian hoặc một phạm vi xác định
Bối cảnh: một hệ thống lưu trữ dữ liệu cảm biến nhiệt độ, ghi lại giá trị mỗi phút
Trước khi áp dụng Bucket Pattern
Dữ liệu ( Sensor Readings Collection)
Truy vấn để lấy dữ liệu trong khoảng thời gian
- Lưu trữ hàng triệu tài liệu nhỏ lẻ gây áp lực lớn cho hệ thống
- Truy vấn cần duyệt qua rất nhiều tài liệu riêng lẻ, làm giảm hiệu suất.
Sau khi sử dụng Bucket Pattern
Dữ liệu (Buckets Collection): Truy vấn để lấy dữ liệu trong khoảng thời gian:
1 Trước khi áp dụng Pattern
- Mỗi giá trị cảm biến được lưu trong 1 tài liệu riêng, dẫn đến hàng triệu tài liệu nhỏ
- Truy vấn cần duyệt qua nhiều tài liệu, gây ấp lực cho hệ thống và làm chậm hiệu suất
2 Sau khi áp dụng Pattern
- Các giá trị cảm biến được gom nhóm theo ngày, giúp giảm số lượng tài liệu.
- Truy vấn chỉ cần lấy một bucket duy nhất ( hoặc 1 vài bucket), nhanh hơn và hiệu quả hơn.
- Giảm số lượng tài liệu: Từ hàng triệu tài liệu xuống còn vài nghìn bucket
- Tăng tốc truy vấn: lấy toàn bộ dữ liệu trong 1 bucket nhanh hơn so với truy vấn từng tài liệu
- Nếu cần xóa hoặc cập nhật 1 giá trị riêng lẻ, việc thay đổi bucket sẽ phức tạp và tốn kém hơn.
2.5.6 So sánh trước và sau khi áp dụng Bucket Pattern
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Số lượng tài liệu Hàng triệu tài liệu nhỏ Vài nghìn Bucket
Hiệu suất truy vấn chậm hơn do phải duyệt qua nhiều tài liệu nhỏ, trong khi truy vấn nhanh hơn khi chỉ cần truy vấn một số bucket cụ thể Việc cập nhật dữ liệu dễ dàng hơn với các tài liệu nhỏ, nhưng trở nên phức tạp hơn khi phải cập nhật trong các bucket lớn Ứng dụng phù hợp phụ thuộc vào loại dữ liệu; dữ liệu không nhóm phù hợp với truy vấn theo từng tài liệu, còn dữ liệu có thể nhóm và không cần truy vấn nhóm sẽ phù hợp hơn với phương pháp truy vấn theo nhóm.
Schema Versioning Pattern
Schema Versioning Pattern trong MongoDB là một phương pháp thiết kế schema giúp quản lý sự thay đổi của cấu trúc dữ liệu theo thời gian một cách hiệu quả Mỗi tài liệu được gán một phiên bản schema (schema version), điều này cho phép ứng dụng xử lý các dữ liệu theo các phiên bản schema khác nhau mà không gây gián đoạn hoạt động Đây là giải pháp tối ưu để duy trì tính linh hoạt và mở rộng của hệ thống dữ liệu, phù hợp cho các ứng dụng yêu cầu cập nhật cấu trúc dữ liệu liên tục.
2.6.2 Khi nào nên dùng Schema Versioning Pattern
1 Khi schema thay đổi theo thời gian
- Dữ liệu mới được lưu trữ theo 1 schema cập nhật, nhưng dữ liệu cũ vẫn tồn tại trong cấu trúc cũ.
2 ứng dụng cần tương thích ngược
- Khi ứng dụng phải xử lý cả tài liệu với schema mới và cũ
3 Hệ thống có nhiều nguồn dữ liệu
- Dữ liệu đến từ nhiều nguồn có thể sử dụng các schema khác nhau.
4 Phát triển hệ thống theo từng giai đoạn
- Cần triển khai các thay đổi schema mà không phải chuyển đổi toàn bộ dữ liệu ngay lập tức.
2.6.3 Khi không nên dùng Schema Versioning Pattern
1 Dữ liệu không thay đổi schema
- Nếu schema không thay đổi theo thời gian, pattern này không cần thiết.
2 Ứng dụng không cần tương thích ngược
- Nếu chỉ làm việc với dữ liệu mới và không cần xử lý dữ liệu cũ
3 Dữ liệu phức tạp và khó đồng bộ
- Quản lý nhiều phiên bản schema có thể làm tăng độ phức tạp nếu không có chiến lược rõ ràng.
2.6.4 Lợi ích của Schema Versioning Pattern
- Ứng dụng có thể xử lý tài liệu thuộc nhiều phiên bản schema mà không cần chuyển đổi ngay toàn bộ dữ liệu
2 Quản lý thay đổi dễ dàng
- Có thể thực hiện thay đổi schema theo từng giai đoạn, giảm rủi ro.
- Cho phép thêm các tính năng mới mà không ảnh hưởng đến dữ liệu cũ
- Không cần dừng hệ thống để chuyển đổi toàn bộ dữ liệu
- Hệ thống lưu trữ thông tin người dùng.
+ Phiên bản cũ: lưu trữ địa chỉ dưới dạng một chuỗi văn bản ( address)
+ Phiên bản mới: Địa chỉ được lưu dưới dạng đối tượng chi tiết ( address có street, city, state)
Trước khi áp dụng Schema Versioning Pattern
Dữ liệu ( Users Collection, không có version)
Trong quá trình xử lý dữ liệu, ứng dụng không có khả năng phân biệt các định dạng khác nhau của địa chỉ Khi cần thay đổi schema, ví dụ như lưu địa chỉ thành đối tượng chi tiết, sẽ phải viết logic xử lý phức tạp để xác định định dạng phù hợp, gây ra sự phức tạp và khó quản lý trong quá trình phát triển.
- Không thể biết liệu tất cả dữ liệu address có cùng 1 định dạng hay không
- Nếu thay đổi schema, toàn bộ dữ liệu cũ cần được cập nhật để phù hợp với schema mới.
- Ứng dụng phải đồng bộ ngay lập tức, gây gián đoạn hoạt động.
- Khó khăn trong việc mở rộng schema khi dữ liệu trở nên phức tạp hơn.
Sau khi áp dụng Schema Versioning Pattern
Dữ liệu ( Users Collection, có version) Ứng dụng xử lý theo phiên bản
- Phiên bản 1: Đọc trực tiếp trường address dưới dạng chuỗi văn bản.
Sử dụng trường address làm đối tượng và xử lý các trường street, city, state.
Chiến lược chuyển đổi dữ liệu
1 Dữ liệu mới được lưu trữ theo schema mới ( phiên bản 2)
2 Dữ liệu cũ vẫn giữ nguyên, chỉ được chuyển đổi khi có yêu cầu truy vấn hoặc cập nhật
1 Trước khi áp dụng pattern
- Không có version, buộc phải cập nhật toàn bộ dữ liệu hoặc chấp nhận không đồng bộ khi thay đổi schema
- Khó khăn khi xử lý các tài liệu thuộc schema khác nhau.
2 Sau khi áp dụng pattern
- Mỗi tài liệu được gắn phiên bản version để biểu thị schema của nó.
- Ứng dụng có thể xử lý tài liệu theo phiên bản tương ứng.
- Tương thích ngược: Dữ liệu cũ vẫn sử dụng được mà không cần chuyển đổi ngay
- Dễ mở rộng: Dữ liệu mới được lưu trữ theo schema mới mà không ảnh hưởng đến dữ liệu cũ
- Tăng độ phức tạp trong quản lý ứng dụng vì phải xử lý nhiều phiên bản schema
2.6.6 So sánh trước và sau khi áp dụng Schema Versioning Pattern
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Quản lý dữ liệu hiệu quả đòi hỏi phải xử lý sự khác biệt giữa các schema, điều này khó khăn nếu không có cách tiếp cận phù hợp Mỗi tài liệu được gắn với phiên bản cụ thể, giúp dễ dàng quản lý và mở rộng hệ thống dữ liệu một cách linh hoạt Tuy nhiên, hệ thống không hỗ trợ khả năng tương thích ngược, do đó cần chuyển đổi toàn bộ dữ liệu khi có sự thay đổi về schema để đảm bảo dữ liệu luôn chính xác và nhất quán.
Hỗ trợ xử lý tài liệu theo phiên bản schema
Thời gian downtime có thể cần thiết để dừng hệ thống nhằm đồng bộ dữ liệu, tuy nhiên cũng có những phương án không cần downtime, thay đổi tùy theo từng giai đoạn Độ phức tạp của ứng dụng ảnh hưởng lớn đến quy trình cập nhật, trong đó các ứng dụng đơn giản vẫn gặp khó khăn trong việc quản lý sự thay đổi của schema Khi hệ thống phức tạp hơn, việc xử lý nhiều phiên bản trở nên cần thiết, nâng cao độ khó trong quản lý và bảo trì hệ thống.
Tree Pattern
Tree Pattern là một thiết kế schema trong MongoDB được sử dụng để lưu trữ và truy vấn dữ liệu phân cấp như cây thư mục, danh mục sản phẩm hoặc cấu trúc tổ chức Thiết kế này giúp biểu diễn các mối quan hệ cha con một cách rõ ràng, đồng thời xử lý các mối quan hệ này một cách hiệu quả Tree Pattern phù hợp cho các ứng dụng cần quản lý dữ liệu hierarchical, đảm bảo khả năng truy vấn nhanh chóng và dễ dàng mở rộng.
2.7.2 Khi nào nên dùng Tree Pattern
1 Dữ liệu có cấu trúc phân cấp
- Khi cần lưu trữ thông tin dạng cây, VD: thư mục tệp, cây thư mục danh mục sản phẩm, hoặc cấu trúc tổ chức doanh nghiệp.
2 Truy vấn phụ thuộc vào cấu trúc cây
- Khi cần truy vấn dữ liệu dựa trên mới quan hệ cha – con VD: tìm tất cả con của một nút hoặc duyệt toàn bộ cây.
3 Quản lý mối quan hệ cha – con.
- Khi các mối quan hệ này thay đổi thường xuyên hoặc cần thêm nút mới
2.7.3 Khi không nên dùng Tree Pattern
1 Dữ liệu không phân cấp
- Nếu dữ liệu không có cấu trúc phân cấp, sử dụng Tree sẽ làm phức tạp thêm thiết kế
2 Truy vấn không phụ thuộc vào cấu trúc cây
- Nếu truy vấn không yêu cầu các mối quan hệ cha – con, các mẫu schema khác có thể hiệu quả hơn
3 Tốc độ cập nhật quan trọng hơn tốc độ đọc
- Một số Tree Pattern (VD: Nested Sets) có chi phí cập nhật cao, không phù hợp nếu cập nhật thường xuyên.
2.7.4 Các kiểu Tree Pattern phổ biến
- Mỗi nút lưu trữ tham chiếu đến cha của nó
- Phù hợp khi truy vấn chủ yếu tập trung vào các nút con dựa trên nút cha
- Mỗi nút lưu danh sách các tham chiếu đến con của nó.
- Phù hợp khi truy vấn thường tìm tất cả các con của một nút.
- Lưu đường dẫn đầy đủ từ gốc đến nút
- Phù hợp khi cần truy vấn nhanh tất cả các nút trong 1 nhánh hoặc xác định cấp bậc ( depth)
- Mỗi nút lưu khoảng giá trị ( left, right) biểu thị vị trí trong cây
- Phù hợp khi cần truy vấn toàn bộ cây hoặc cây con
2.7.5 Lợi ích của Tree pattern
1 Tối ưu hóa truy vấn phân cấp
- Hiệu quả trong việc truy vấn quan hệ cha – con, tìm nhánh hoặc duyệt toàn bộ cây
- Dễ thêm hoặc sửa đổi các nút trong cấu trúc cây
- Nhiều kiểu lưu trữ phù hợp với các loại truy vấn khác nhau
4 Hỗ trợ dữ liệu phức tạp
- Tương thích tốt với các hệ thống yêu cầu quản lý nhiều mối quan hệ
Bối cảnh: một hệ thống lưu trữ cây thư mục ( file system) với các thư mục và tệp
Trước khi áp dụng Tree Pattern
Dữ liệu không có tổ chức phân cấp
- Không lưu trữ được cấu trúc cây rõ ràng ( VD: thư mục con)
- Truy vấn tìm các thư mục hoặc tệp trong cây phân cấp phức tạp.
Sau khi áp dụng Tree Pattern
Dữ liệu tổ chức với Parent Reference
1 Tìm tất cả các thư mục gốc
2 Tìm tất cả các tệp trong thư mục Documents
1 Trước khi áp dụng Pattern
- Cấu trúc không phản ảnh được mối quan hệ cha con
- Truy vấn phức tạp vì phải tham chiếu folder_id để tìm kiếm
2 Sau khi áp dụng Pattern
- Mỗi thư mục/tệp lưu tham chiếu đến cha ( parent_id), tạo ra cấu trúc cây rõ ràng.
- Truy vấn dễ dàng hơn khi tìm các nút con hoặc các thư mục gốc
- Rõ ràng: Cấu trúc cây được lưu trữ một cách minh bạch.
- Truy vấn hiệu quả: Truy vấn các nút cha hoặc con nhanh hơn.
- Nếu cần truy vấn toàn bộ cây, phải lặp qua từng nút, không tối ưu bằng các kiểu khác như Materialized path
2.7.7 So sánh trước và sau khi áp dụng Tree Patterns
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Cấu trúc dữ liệu này không phản ánh rõ mối quan hệ cha – con trong hệ thống, do mỗi nút chỉ lưu tham chiếu đến cha (parent_id) Hiệu suất truy vấn thường chậm hơn khi tìm kiếm các nút con hoặc với cấu trúc cây phức tạp, nhưng lại nhanh hơn trong việc xử lý các mối quan hệ cha – con Tuy nhiên, khả năng mở rộng của cấu trúc này gặp khó khăn khi cần thêm nhiều tầng phân cấp mới, làm giảm tính linh hoạt trong phạm vi mở rộng hệ thống.
Dễ mở rộng với các tầng phân cấp phức tạp
Quản lý Dễ bị lỗi nếu không có tổ chức rõ ràng Cấu trúc cây rõ ràng, dễ bảo trì
Polymorphic Pattern
Polymorphic Pattern là một kỹ thuật thiết kế schema trong MongoDB, cho phép lưu trữ nhiều loại dữ liệu khác nhau trong cùng một collection, giúp tối ưu hóa quản lý dữ liệu đa dạng Mỗi tài liệu trong collection đều có một thuộc tính định danh loại dữ liệu, thường là "type", nhằm giúp ứng dụng xác định cách xử lý phù hợp cho từng loại dữ liệu Đây là giải pháp linh hoạt và hiệu quả để xây dựng hệ thống quản lý dữ liệu phức tạp trong MongoDB.
2.8.2 Khi nào nên dùng Polymorphic Pattern
1 Dữ liệu thuộc nhiều loại nhưng có điểm chung
- Khi các tài liệu có một số trường chung nhưng cũng có trường riêng cho từng loại
2 Cần lưu trữ nhiều loại đối tượng liên quan
- VD: lưu cả xe hơi và xe máy trong cùng 1 collection vehicles
3 ứng dụng cần truy vấn hoặc phân loại dữ liệu dựa trên loại
- Phân biệt các loại tài liệu dễ dàng bằng các sử dụng trường type
- Khi cần truy vấn tất cả các tài liệu mà không cần tách thành nhiều collection nhỏ lẻ.
2.8.3 Khi không nào nên dùng Polymorphic Pattern
1 Dữ liệu có cấu trúc phức tạp và khác biệt lớn
- Nếu các loại tài liệu quá khác nhau, việc lưu trữ trong cùng 1 colleciton sẽ gây khó khăn khi truy vấn.
- Nếu truy vấn chỉ tập trung vào 1 loại dữ liệu, việc gộp chung có thể làm giảm hiệu suất
3 Khi kích thước tài liệu không đồng đều
- Các loại tài liệu với kích thước quá chênh lệch có thể gây ra vấn đề về hiệu suất
4 Khi dữ liệu thay đổi thường xuyên
- Nếu dữ liệu thuộc 1 loại cần thay đổi schema liên tục, có thể ảnh hưởng đến các tài liệu khác trong cùng collection
2.8.4 Lợi ích của Polymorphic Pattern
- Một collection có thể chứa nhiều loại đối tượng khác nhau.
- Không cần tạo nhiều collection nhỏ lẻ cho mỗi loại đối tượng
3 Tăng hiệu quả truy vấn
- Dễ dàng truy vấn các tài liệu khác loại trong cùng 1 collection
4 Đơn giản hóa cấu trúc
- Giảm số lượng collection, giúp tổ chức dữ liệu gọn gàng hơn.
Bối cảnh: một hệ thống lưu trữ phương tiện giao thông với 2 loại: ô tô, xe máy
Trước khi áp dụng Polymorphic Pattern
- Truy vấn kết hợp phức tạp
+ Nếu cần truy vấn cả xe hơi và xe máy, phải thực hiện 2 truy vấn riêng biệt
- Phức tạp trong quản lý
+ Phải duy trì 2 collection với các logic xử lý riêng biệt
Sau khi áp dụng Polymorphic Pattern
Gộp chung thành 1 collection vehicles
1 Tìm tất cả phương tiện giao thông:
3 Tìm tất cả xe máy có dung tích động cơ > 100
1 Trước khi áp dụng Pattern
- Dữ liệu được tách thành 2 collection riêng biệt: cars, motobikes
- Việc quản lý và truy vấn trở nên phức tạp khi cần truy cập cả 2 loại dữ liệu.
2 Sau khi áp dụng Pattern
- Tất cả dữ liệu được lưu trữ trong 1 colleciton duy nhất vehicles
- Phân loại dữ liệu dựa trên trường type
- Truy vấn linh hoạt: Dễ dàng truy vấn cả ô tô và xe máy chỉ với 1 collection
- Quản lý gọn gàng: Giảm số lượng collection trong CSDL
- Nếu số lượng trường khác nhau giữa các loại quá lớn, việc lưu trữ chung có thể gây khó khăn cho việc đọc/ghi
2.8.6 So sánh trước và sau khi áp dụng Polymorphic Pattern
Tiêu chí Trước khi áp dụng Sau khi áp dụng
Cấu trúc dữ liệu Tách riêng từng loại trong các collection khác nhau Gộp chung vào 1 colleciton với trường type
Truy vấn Phức tạp hơn khi cần kết hợp dữ liệu
Linh hoạt hơn khi truy vấn kết hợp
Quản lý Khó quản lý nhiều collection Gọn gàng hơn với một collection duy nhất Tính linh hoạt Kém linh hoạt khi thêm loại mới
Dễ dàng mở rộng với loại dữ liệu mới
TỔNG HỢP
Pattern Trường hợp áp dụng Giải thích ngắn gọn
1 Attribute Pattern Khi cần lưu trữ dữ liệu thuộc tính động hoặc không cố định, VD: sản phẩm có các đặc tính (color, size) thay đổi theo loại sản phẩm.
Lưu trữ các thuộc tính như cặp khóa – giá trị ( key – value ) để tăng tính linh hoạt cho dữ liệu.
Reference Pattern Khi cần bổ sung thêm thông tin từ tài liệu liên quan để tránh các phép nối tốn kém ( $lookup) VD:
Lưu thêm thông tin khách hàng ( tên, địa chỉ ) trực tiếp vào đơn hàng
Nhúng các thông tin cơ bản từ tài liệu liên quan vào tài liệu chính để giảm thiểu truy vấn liên collection
3 Subset pattern Khi tài liệu chứa quá nhiều dữ liệu khong thường xuyên truy vập, VD: sản phẩm lưu phần thông tin chi tiết đầy đủ vào tài liệu phụ, chỉ giữ thông tin chính trong tài liệu chính.
Tách các phần dữ liệu ít được sử dụng ra tài liệu riêng để tối ưu kích thước tài liệu chính và cải thiện hiệu suất.
4 Computed Pattern Khi cần lưu trữ các kết quả của phép tính phức tạp để giảm tải CPU, VD: lưu tổng doanh thu của một bộ phim thay vì tính toán mỗi lần truy vấn
Lưu trữ dữ liệu đã được tính toán trước để giảm thiểu tài nguyên khi truy vấn lặp lại các phép tính phức tạp.
5 Bucket Pattern Khi cần lưu trữ dữ liệu theo gian hoặc lặp lại, VD: dữ liệu cảm biến ( sensor data) hoặc nhật ký ( log
Gom nhóm các tài liệu nhỏ có đặc điểm chung thành một bucket ( nhms ) duy nhất để giảm số lượng tài data) liệu và tăng hiệu suất truy vấn
Khi cấu trúc-schema thay đổi theo thời gian, ví dụ như một hệ thống ban đầu lưu trữ thông tin địa chỉ dưới dạng chuỗi và sau đó chuyển đổi sang dạng đối tượng gồm các thành phần như street, city, state, điều này ảnh hưởng đến khả năng truy xuất và tối ưu hóa dữ liệu Việc cập nhật cấu trúc schema giúp đảm bảo dữ liệu phản ánh chính xác và đầy đủ các thay đổi mới nhất, đồng thời nâng cao hiệu quả vận hành hệ thống Do đó, quản lý sự biến đổi của schema là yếu tố quan trọng để duy trì tính nhất quán và tối ưu hóa hoạt động dữ liệu trong các hệ thống quản lý thông tin.
Gắn phien bản ( version ) cho tài liệu để hỗ trợ quản lý các tài liệu có schema khác nhau trong cùng 1 collection
7 Tree Pattern Khi lưu trữ dữ liệu phân cấp VD: cây thư mục (folder), danh mục sản phẩm ( categories), hoặc cấu trúc tổ chức công ty ( organization hierarchy)
Lưu trữ các quan hệ cha con để dễ dàng truy vấn hoặc duyệt qua cây dữ liệu. Các dạng Tree pattern phổ biến gồm: Parent
Reference, Child reference, materialized path, nested sets.
8 Polymorphic pattern Khi một collection chứa nhiều loại đối tượng có cấu trúc tương tự, VD: 1 collection vehicles lưu cả thông tin xe hơi car và xe máy motorbike
Lưu nhiều kiểu đối tượng trong 1 collection duy nhất và phân biệt chúng bằng trường type
Giải thích thêm từng pattern
Khi áp dụng: Dữ liệu có các thuộc tính không cố định hoặc linh hoạt.
Ví dụ: Sản phẩm có thuộc tính như color, size hoặc weight thay đổi giữa các loại sản phẩm.
Khi áp dụng: Tránh $lookup để giảm tải hệ thống khi truy vấn giữa các collection.
Ví dụ: Nhúng thông tin cơ bản của khách hàng vào đơn hàng để giảm phép nối.
Khi áp dụng: Tài liệu lớn với một phần dữ liệu ít được sử dụng.
Ví dụ: Sản phẩm lưu thông tin cơ bản trong tài liệu chính và chi tiết trong tài liệu phụ.
Khi áp dụng: Tính toán phức tạp hoặc lặp lại nhiều lần.
Ví dụ: Lưu trước tổng doanh thu của bộ phim thay vì tính toán mỗi lần truy vấn.
Khi áp dụng: Dữ liệu lặp lại hoặc theo thời gian.
Ví dụ: Cảm biến nhiệt độ lưu dữ liệu theo từng nhóm (một giờ, một ngày).
Khi áp dụng: Schema thay đổi theo thời gian.
Ví dụ: Địa chỉ từ chuỗi đơn (address) sang đối tượng (street, city, state).
Khi áp dụng: Dữ liệu có cấu trúc phân cấp.
Ví dụ: Cây thư mục hoặc danh mục sản phẩm.
Khi áp dụng: Collection chứa nhiều loại dữ liệu khác nhau nhưng có liên quan.
Ví dụ: Một collection lưu thông tin cả xe hơi và xe máy.
Chương 5: Index
Indexes trong MongoDB
Trong MongoDB, indexes là các cấu trúc dữ liệu đặc biệt giúp cải thiện đáng kể tốc độ truy vấn dữ liệu Chúng hoạt động như các bảng tra cứu, cho phép MongoDB tìm kiếm tài liệu nhanh hơn so với việc quét toàn bộ collection, từ đó nâng cao hiệu suất và hiệu quả của hệ thống cơ sở dữ liệu.
3.1.2 Khi nào nên dùng Indexes
1 Cải thiện hiệu suất truy vấn
- Khi các truy vấn thường xuyên lọc hoặc sắp xếp theo 1 số trường cụ thể
2 Truy vấn với các điều kiện phức tạp
- Khi cần lọc dữ liệu theo nhiều trường hoặc thực hienj các phép sắp xếp kết hợp
- Khi làm việc với các collection lớn, index giúp giảm thiểu thời gian xử lý
4 Sử dụng CRUD thường xuyên
- Đặc biệt là các hoạt động đọc, yêu cầu tốc độ nhanh và chính xác
3.1.3 Khi không nên dùng Indexes
1 Tài liệu nhỏ hoặc collection nhỏ
- Với dữ liệu ít, việc tạo chỉ mục sẽ không cải thiện đáng kể hiệu suất nhưng lại tốn tài nguyên lưu trữ
2 Hoạt động ghi ( write) tần suất cao
- Indexes làm tăng chi phí ghi dữ liệu vì mỗi khi có thay đổi, mongoDB phải cập nhật cả chỉ mục
3 Quá nhiều chỉ mục không cần thiết
- Việc tạo quá nhiều chỉ mục làm tăng kích thước CSDL và giảm hiệu suất tổng thể.
4 Chỉ mục trên các trường có giá trị lặp lại cao ( low cardinality)
- VD: trường Boolean ( true / false ) có giá trị trùng lặp nhiều sẽ không tận dụng được hiệu quả của chỉ mục
1 Tăng tốc độ truy vấn
- MongoDB không cần phải quét toàn bộ collection, giúp giảm đáng kể thời gian truy vấn
2 Hộ trợ sắp xếp hiệu quả
- Chỉ mục có thể được sử dụng để tối ưu hóa các phép sắp xếp dữ liệu
3 Tối ưu hóa bộ nhớ
- Chỉ mục cho phép MongoDB sử dụng RAM hiệu quả hơn bằng cách giới hạn dữ liệu cần tải vào bộ nhớ
4 Hỗ trợ truy vấn phức tạp
- Các chỉ mục hợp phần ( compound index) có thể xử lý các điều kiện truy vấn đa trường
3.1.5 So sánh trước và sau khi áp dụng Indexes
Tiêu chí Trước khi áp dụng Indexes Sau khi áp dụng Indexes Cách xử lý truy vấn Quét toàn bộ collection Sử dụng chỉ mục để tìm kiếm
Hiệu suất Chậm hơn, phụ thuộc vào kích thước collection
Nhanh hơn, đặc biệt với collection lớn
Sử dụng tài nguyên hợp lý để giảm tổn thất CPU và RAM khi quét toàn bộ tài liệu, nhờ tối ưu hóa bằng chỉ mục Phương pháp này thích hợp khi bộ sưu tập dữ liệu nhỏ hoặc số lượng truy vấn hạn chế, giúp nâng cao hiệu quả và hiệu suất hệ thống.
Khi collection lớn và cần tối ưu truy vấn thường xuyên
Chi phí ghi ( write) Không bị ảnh hưởng Tăng chi phí do phải cập nhật chỉ mục
- Khi nên dùng: Khi cần tối ưu hóa hiệu suất truy vấn trên các collection lớn hoặc thường xuyên truy vấn với các điều kiện lọc.
- Khi không nên dùng: Khi tập dữ liệu nhỏ, ít truy vấn, hoặc khi chi phí ghi dữ liệu là yếu tố quan trọng.
Nguyên tắc ESR
Chỉ mục trong MongoDB là một hướng dẫn thiết kế giúp tối ưu hóa hiệu suất truy vấn dữ liệu Nguyên tắc chính của chỉ mục liên quan đến việc xác định thứ tự các trường trong chỉ mục nhằm nâng cao tốc độ truy xuất dữ liệu Việc tổ chức thứ tự các trường phù hợp đảm bảo các truy vấn được thực thi nhanh chóng và hiệu quả hơn Định nghĩa này nhấn mạnh vai trò của việc thiết kế chỉ mục phù hợp để cải thiện hiệu suất tổng thể của hệ thống cơ sở dữ liệu MongoDB.
1 Equality ( E): Các trường sử dụng phép so sánh bằng ( = ) nên được đặt dầu tiên trong chỉ mục.
2 Sort (S): Các trường được sử dụng để sắp xếp kết quả truy vấn ( sort ) nên được đặt tiếp theo.
3 Range ( R): các trường lọc theo phạm vi (VD: $gte, $lte, $in) nên được đặt cuối cùng trong chỉ mục.
Bối cảnh: 1 hệ thống quản lý sản phẩm với collection products
+ Dữ liệu sản phẩm gồm: nhà sản xuất ( manufacturer), loại sản phẩm ( category ), giá ( price).
Truy vấn cần tối ưu
Để tìm tất cả các sản phẩm Laptop của Apple có mức giá từ 1.000 đến 2.000 USD, bạn cần sắp xếp kết quả theo thứ tự giá từ thấp đến cao để dễ dàng so sánh Đặc biệt, hãy áp dụng nguyên tắc ESR để tối ưu hiệu quả tìm kiếm và tạo chỉ mục phù hợp, giúp truy vấn nhanh hơn và nâng cao trải nghiệm người dùng Việc lọc theo khoảng giá này giúp giới hạn kết quả, tập trung vào các mẫu laptop Apple có mức giá phù hợp với ngân sách của bạn.
- Manufacturer và category là các trường lọc bằng ( = ), nên được đặt đầu tiên trong chỉ mục.
- Price là trường dùng để sắp xếp, nên đặt tiếp theo.
- Price cũng được sử dụng để lọc theo phạm vi ( $gte, $lte) nên được đặt cuối cùng trong chỉ mục
Hoạt động sau khi áp dụng chỉ mục
- Lọc tài liệu có manufacturer: “Apple” và category : “laptop”
- Sắp xếp các tài liệu còn lại theo price mà không cần thực hiện thêm xử lý
- Lọc tài liệu có giá price trong khoảng từ 1000 – 2000
- Chỉ mục giúp MongoDB tránh phải quét toàn bộ collection
- Truy vấn được thực hiện trực tiếp trên chỉ mục, nhanh hơn nhiều
2 Truy vấn được tối ưu
- Thứ tự các trường trong chỉ mục tuân theo ESR giúp giảm số lượng tài liệu cần quét
3 Tối ưu hóa bộ nhớ
- Việc kết hợp lọc, sắp xếp, và phạm vi trong chỉ mục hợp phần tiết kiệm bộ nhớ và thời gian.
3.2.1 So sánh trước và sau khi áp dụng ESR
Tiêu chí Trước khi áp dụng ESR Sau khi áp dụng ESR
Cách xử lý MongoDB quét toàn bộ collection để lọc và sắp xếp MongoDB sử dụng chỉ mục, giảm số lượng tài liệu phải quét.
Hiệu suất Chậm hơn, đặc biệt với collection lớn Nhanh hơn đáng kể, tối ưu với collection lớn
Sử dụng tài nguyên Tốn CPU và bộ nhớ do phải xử lý nhiều dữ liệu Ít tài nguyên hơn, hiệu quả hơn
Khi nên dùng Collection nhỏ, truy vấn đơn giản Collection lớn, truy vấn phức tạp
- Khi nên dùng ESR: khi truy vấn có các điều kiện lọc, sắp xếp, và phạm vi phức tạp trên các collection lớn
- Khi không nên dùng ESR: khi dữ liệu nhỏ hoặc không yêu cầu sắp xếp/ phạm vi
Bài tập mẫu
To enhance system performance, optimize the query: `db.users.find({numoflike: {$gte: 50000}, gender: 'female', age: 29}).sort({name: 1})` Consider creating indexes on the `numoflike`, `gender`, `age`, and `name` fields to facilitate faster data retrieval and reduce query latency Proper indexing aligned with this query can significantly improve efficiency, ensuring quicker and more reliable results.
db.createIndex({“gender”:1, “age”: 1, “name”: 1, “numoflike”:1});
db.users.find({gender: 'female', age: 29, “numoflike”:
{$gte:50000}}).sort(name:1); b db.users.find({'Addresses.Country': 'Norfolk'}).skip(10).limit(20).pretty()
db.users.creatIndex({“address.Country”:1});
db.users.find({'Addresses.Country': 'Norfolk'}).skip(10).limit(20).pretty() c db.products.find({price: { $gt: 1, $lt: 5 }, in_stock: true }).sort({ name: 1 })
db.users.createIndex(“in_stock”:1, name:1, price:1);
db.products.find (in_stock: true }, ({price: { $gt: 1, $lt: 5 }).sort({ name: 1 }) d db.user.find( { numoflike : { $gte : NumberDecimal(100000.00) }, city: "TP HCM" } ) sort( { lastName: 1, firstName: 1 } )
db.users.createIndex({“city”:1, “lastName”:1, “firstName”:1, “numoflike”:1})
c1: db.user.find(city: "TP HCM" },{ numoflike : { $gte :
NumberDecimal(100000.00) } ) sort( { lastName: 1, firstName: 1 } ) e db.products.find({'details.manufacturer': 'Acme','pricing.sale': { $lt: 7500}})
db.users.createIndex({'details.manufacturer':1}, {'pricing.sale':1})
db.products.find({'details.manufacturer': 'Acme','pricing.sale': { $lt: 7500}}) f db.myColl.find( { score: 5, price: { $gt: NumberDecimal( "10" ) } } ).sort( { price:
db.users.createIndex({‘score’:1},{price:1} );
db.myColl.find( { score: 5, price: { $gt: NumberDecimal( "10" ) } } ).sort( { price:
Công ty bảo hiểm ABC cung cấp đa dạng các sản phẩm bảo hiểm phù hợp với khách hàng trên toàn quốc Việt Nam Do yêu cầu phân tán dữ liệu để tối ưu hóa hiệu suất, hệ thống của công ty sử dụng kiến trúc sharding gồm 3 node Phân tích workload cho thấy người dùng thường xuyên truy vấn các hồ sơ bảo hiểm của khách hàng theo thành phố nơi khách hàng sinh sống.
Bạn hãy đề xuất một kế hoạch cho việc dựng một sharding sao cho tăng được hiệu năng của hệ thống trong khi truy vấn dữ liệu.
- Dữ liệu là hồ sơ bảo hiểm của khách hàng, phân bổ toàn quốc ( VN)
- Truy vấn phổ biến: Tìm kiếm hồ sơ bảo hiểm của khách hàng dựa trên thành phố mà khách hàng trực thuộc.
- Hệ thống cần được thiết kế phân tán trên 3 shard node
- Tăng hiệu năng truy vấn bằng cách giảm độ trễ và cân bằng tải giữa các shard node
- Tối ưu hóa khả năng mở rộng của hệ thống khi dữ liệu tăng trưởng theo thời gian
3) Kế hoạch thiết lập hệ thống sharding a Chọn shard key
Shard key đóng vai trò quyết định trong việc phân phối dữ liệu giữa các shard, giúp tối ưu hiệu suất truy vấn Khi truy vấn chủ yếu dựa vào thành phố (city), lựa chọn shard key là thành phố sẽ mang lại lợi ích lớn nhất Việc sử dụng shard key city giúp tăng tốc độ truy vấn và giảm tải cho hệ thống, đảm bảo hiệu quả vận hành tốt hơn Đây là lựa chọn phù hợp nhất khi các truy vấn chính liên quan đến dữ liệu dựa trên thông tin địa lý, cụ thể là thành phố.
1 Tăng hiệu suất truy vấn
- Dữ liệu của mỗi thành phố được lưu tập trung trên 1 shard, giảm thời gian truy vấn vì MongoDB chỉ cần truy vấn đúng shard
2 Phân phối dữ liệu đồng đều
- VN có nhiều thành phố, dữ liệu được phân phối đều giữa các shard, tránh hiện tượng “hot shard” ( một shard bị quá tài)
- Khi thêm shard, dữ liệu từ các thành phố có thể được phân bổ lại một cách tự động b Cấu hình shard key
Shard key "city" nên được kết hợp cùng với _id hoặc các trường khác trong trường hợp có nhiều dữ liệu trong cùng một thành phố để đảm bảo tính duy nhất của dữ liệu Việc tạo chỉ mục hỗ trợ cho shard key giúp tối ưu hóa hiệu suất truy vấn và quản lý dữ liệu phân tán hiệu quả hơn.
- Trước khi kích hoạt sharding, cần tạo một chỉ mục trên shard key để
MongoDB phân vùng dữ liệu hiệu quả
- Tạo chỉ mục d Cân nhắc vùng ( zones ) cho sharding
Việt Nam có sự phân bổ địa lý rõ ràng theo miền Bắc, Trung, Nam, giúp dễ dàng áp dụng kỹ thuật sharding zones để nhóm các thành phố thuộc cùng một vùng địa lý thành một shard Việc này tối ưu hóa quản lý dữ liệu, cải thiện hiệu suất hệ thống và đảm bảo tính mở rộng phù hợp với đặc điểm phân bổ khu vực của đất nước Áp dụng sharding theo vùng địa lý giúp giảm tải cho các máy chủ chính, đồng thời tăng tốc độ truy cập dữ liệu cho người dùng ở từng khu vực.
+ Giảm thời gian truy vấn cho các vùng cụ thể.
+ Giảm chi phí truyền dữ liệu giữa các shard
- VD cấu hình vùng ( zones)
4) Ưu điểm của kết hoạch
1 Hiệu suất cao khi truy vấn theo thành phố
Các truy vấn phổ biến dựa trên thành phố sẽ được định tuyến đến đúng shard, giảm thời gian xử lý
Dữ liệu được phân phối đều giữa các shard, tranh hiện tượng quá tải ở một shard cụ thể
Khi thêm shard mới, các thành phố hoặc vùng có thể được di chuyển sang shard mới mà không làm gián đoạn hệ thống
4 Tối ưu hóa theo địa lý
Sử dụng sharding zones giúp lưu trữ dữ liệu gần với người dùng thuộc khu vực đó, giảm độ trễ.
5) Rủi ro và cách xử lý
Rủi ro Cách xử lý
Trong các thành phố nhỏ, việc thiếu dữ liệu dẫn đến mất cân bằng tải hệ thống, gây ảnh hưởng đến hiệu suất hoạt động Để giải quyết vấn đề này, nên kết hợp shard key với _id nhằm làm mịn dữ liệu và phân bổ tải đều hơn Trong khi đó, các thành phố lớn như Hồ Chí Minh và Hà Nội lại có lượng dữ liệu khổng lồ, đòi hỏi các giải pháp tối ưu để quản lý và xử lý dữ liệu hiệu quả, đảm bảo hệ thống vận hành ổn định và nhanh chóng.
Sử dụng sharding zones để phân tác theo khu vực.
Trong quá trình truy vấn không sử dụng shard key, việc tạo chỉ mục hỗ trợ các truy vấn ngoài shard key là rất quan trọng để tối ưu hóa hiệu suất Khi dữ liệu tăng trưởng vượt dự kiến, việc thêm shard mới giúp MongoDB tự động phân phối lại dữ liệu một cách hiệu quả Điều này đảm bảo hệ thống vẫn vận hành mượt mà và duy trì khả năng mở rộng linh hoạt trong môi trường lưu trữ dữ liệu lớn.
- Shard key: “city” ( kết hợp _id để làm min dữ liệu )
- Sharding zones: sử dụng vùng Bắc, Trung, Nam để phân vùng dữ liệu
- Lợi ích + Cải thiện hiệu suất truy vấn dựa tren thành phố.
+ Đảm bảo cân bẳng tải giữa các shard.
+ hỗ trợ mở rộng hệ thống theo nhu cầu trong tương lai.
Lí thuyết
Những yếu tố nào ảnh hưởng đến hiệu năng của hệ thống, cho ví dụ và giải thích lý do tại sao
1 Kích thước bộ nhớ (Memory Size)
RAM là tài nguyên quan trọng đối với MongoDB vì nó thực hiện nhiều thao tác như truy vấn, ghi và kết nối trong bộ nhớ để tối ưu hiệu suất Nếu tập dữ liệu làm việc (working set) không phù hợp với kích thước RAM, hệ thống sẽ phải sử dụng ổ cứng để truy cập dữ liệu, dẫn đến giảm hiệu suất đáng kể do tốc độ truy cập của RAM nhanh hơn SSD khoảng 25 lần.
Một ứng dụng có tập dữ liệu làm việc lớn hơn RAM sẽ phải sử dụng disk paging, gây ra độ trễ lớn cho truy vấn.
2 Thiết kế lược đồ (Schema Design)
Giải thích: o MongoDB có lược đồ linh hoạt, nhưng một thiết kế kém có thể dẫn đến:
Lạm dụng bộ nhớ do kích thước lớn của các trường dữ liệu.
Hiệu suất truy vấn chậm nếu không tối ưu hóa cấu trúc dữ liệu.
Sử dụng embedding (nhúng dữ liệu vào cùng tài liệu) thay vì references (liên kết dữ liệu qua _id) là chiến lược hiệu quả khi dữ liệu thường xuyên được truy xuất cùng nhau Phương pháp này giúp giảm thiểu số lần truy vấn cơ sở dữ liệu, nâng cao hiệu suất hệ thống và tối ưu trải nghiệm người dùng Chọn embedding phù hợp không chỉ tiết kiệm tài nguyên mà còn đảm bảo truy cập dữ liệu nhanh chóng, đồng thời thúc đẩy hiệu quả xử lý thông tin trong các ứng dụng đòi hỏi truy xuất dữ liệu liên tục.
Chỉ mục hỗ trợ tăng tốc truy vấn dữ liệu, giúp cải thiện hiệu suất tìm kiếm và thao tác trên cơ sở dữ liệu, nhưng đồng thời cũng làm tăng chi phí lưu trữ và ghi dữ liệu Do đó, việc sử dụng chỉ mục hợp lý dựa trên quy tắc ESR (Equality, Sort, Range) là cách hiệu quả để tối ưu hóa hiệu suất truy vấn mà không gây quá tải về lưu trữ Áp dụng đúng các nguyên tắc này giúp đảm bảo hệ thống hoạt động ổn định, nhanh chóng và tiết kiệm tài nguyên.
Trong quá trình tối ưu hóa truy vấn MongoDB, việc tạo các chỉ mục phù hợp đóng vai trò quan trọng Ví dụ, tạo một compound index như {manufacturer: 1, model: 1} giúp hỗ trợ truy vấn kết hợp tìm kiếm và sắp xếp một cách hiệu quả Trong khi đó, nếu không có chỉ mục phù hợp, MongoDB sẽ phải thực hiện việc sắp xếp chặn (blocking sort), gây tiêu thụ nhiều tài nguyên và thời gian xử lý không cần thiết.
4 Hệ thống phân tán (Distributed Systems)
Trong kiến trúc replica, ghi trên primary và đọc từ secondary có thể giúp cải thiện hiệu năng, tuy nhiên độ trễ mạng có thể ảnh hưởng tiêu cực đến trải nghiệm người dùng Đối với cụm shard, việc chọn shard key phù hợp là vô cùng quan trọng, bởi một shard key không tối ưu có thể dẫn đến phân phối dữ liệu không đều, gây quá tải cho một số shard, làm giảm hiệu suất hệ thống.
Choosing a shard key with low cardinality, such as status: "active/inactive," can lead to data being concentrated on a few shards, which reduces scalability and hinders effective distribution of workload across the database Selecting an appropriate shard key is crucial for ensuring balanced data distribution and optimal database performance.
5 Tối ưu hóa pipeline Aggregation
Aggregation pipeline hoạt động hiệu quả hơn khi các bước được tối ưu hóa để xử lý dữ liệu tại shard trước khi hợp nhất, giúp giảm tải cho hệ thống Các phép toán như $lookup và $facet có thể tiêu tốn nhiều tài nguyên nếu dữ liệu không được tổ chức tốt, dẫn đến hiệu suất truy vấn giảm Vì vậy, việc tối ưu hóa cấu trúc dữ liệu và quá trình xử lý tại các shard là yếu tố quan trọng để nâng cao hiệu quả của aggregation pipeline trong MongoDB.
Sử dụng $out để xuất kết quả aggregation ra một bộ sưu tập riêng, tránh việc xử lý lại dữ liệu trong các truy vấn tiếp theo.
Để nâng cao hiệu năng của hệ thống, một trong những giải pháp là sử dụng RAM hiệu quả Bạn đề xuất các giải pháp có thể có trong khi thiết kế cấu trúc lưu trữ dữ liệu mà giúp ta dùng RAM hiệu quả, giải thích tại sao?
Để nâng cao hiệu năng hệ thống và tối ưu hóa việc sử dụng RAM, việc thiết kế cấu trúc lưu trữ dữ liệu hợp lý trong MongoDB là yếu tố then chốt Việc này giúp giảm thiểu truy xuất dữ liệu không cần thiết, cải thiện tốc độ xử lý và tối ưu hóa bộ nhớ RAM của hệ thống Các giải pháp phù hợp như phân mảnh dữ liệu, sử dụng chỉ mục phù hợp và tổ chức dữ liệu hiệu quả sẽ đóng vai trò quan trọng trong việc nâng cao hiệu quả hoạt động của MongoDB Bằng cách áp dụng các chiến lược này, bạn có thể đảm bảo hệ thống hoạt động ổn định, nhanh chóng và tiết kiệm tài nguyên, từ đó đem lại trải nghiệm người dùng tốt hơn.
1 Đảm bảo tập dữ liệu làm việc (Working Set) vừa với RAM
Để tối ưu hiệu quả xử lý dữ liệu, cần xác định rõ kích thước của tập dữ liệu làm việc gồm các tài liệu và chỉ mục thường xuyên truy cập Đồng thời, việc lựa chọn lưu trữ chỉ các dữ liệu cần thiết trong RAM bằng cách sử dụng các kỹ thuật như chỉ mục phân đoạn (partial indexes) hoặc truy vấn dựa trên dự án (projection queries) giúp giảm đáng kể lượng RAM tiêu thụ, nâng cao hiệu suất truy cập và xử lý dữ liệu.
Khi tập dữ liệu làm việc vừa với RAM, MongoDB không phải truy cập đĩa, giúp giảm độ trễ đáng kể.
2 Tối ưu hóa chỉ mục (Indexes)
Để tối ưu hóa hiệu suất truy vấn, nên sử dụng compound indexes giúp hỗ trợ nhiều truy vấn đồng thời và giảm số lần quét dữ liệu Bên cạnh đó, việc áp dụng chỉ mục bao phủ (covered indexes) cho phép các truy vấn không cần đọc dữ liệu trực tiếp từ tài liệu gốc, từ đó tiết kiệm thời gian và tài nguyên Ngoài ra, cần loại bỏ các chỉ mục không còn sử dụng hoặc dư thừa để tránh gây giảm hiệu quả của hệ thống cơ sở dữ liệu.
Chỉ mục quá lớn hoặc không cần thiết sẽ chiếm RAM và làm tăng chi phí ghi dữ liệu, làm giảm hiệu năng hệ thống.
3 Thiết kế lược đồ phù hợp (Schema Design)
Trong các giải pháp tối ưu hóa, việc ưu tiên sử dụng embedding (nhúng dữ liệu) cho các tài liệu có liên quan chặt chẽ giúp cải thiện hiệu quả truy xuất thông tin, thay vì dựa vào references (tham chiếu qua _id) không tối ưu Ngoài ra, cần hạn chế lưu trữ các mảng có kích thước không giới hạn để tránh làm tăng kích thước tài liệu quá mức, đảm bảo hệ thống vận hành mượt mà hơn và tiết kiệm tài nguyên lưu trữ.
Thiết kế lược đồ phù hợp giúp giảm thiểu số lượng truy vấn và tải dữ liệu không cần thiết vào RAM, tiết kiệm tài nguyên.
4 Tận dụng các kỹ thuật nén dữ liệu
Để tối ưu hóa hiệu suất, có thể sử dụng các chỉ mục nén như prefix compression cho các trường có low cardinality, giúp giảm kích thước dữ liệu và tăng tốc truy vấn Bên cạnh đó, lựa chọn định dạng dữ liệu nhỏ gọn cũng là giải pháp hiệu quả để giảm thiểu kích thước tài liệu, từ đó nâng cao hiệu quả lưu trữ và truyền tải dữ liệu.
Nén dữ liệu giúp giảm tải RAM và tối ưu hóa không gian lưu trữ.
5 Sử dụng chế độ TTL (Time-To-Live) cho dữ liệu không cần thiết
Giải pháp: o Tạo các TTL indexes để tự động xóa các tài liệu hết hạn sau một khoảng thời gian định trước.
Dữ liệu không cần thiết sẽ không chiếm RAM lâu dài, giải phóng tài nguyên cho các tác vụ quan trọng hơn.
6 Giảm kích thước tài liệu (Document Size Optimization)
Giải pháp: o Tối ưu hóa độ dài tên các trường trong tài liệu. o Loại bỏ các trường không cần thiết hoặc ít được sử dụng.
MongoDB lưu trữ tên trường trong từng tài liệu, do đó, giảm kích thước tài liệu cũng giảm dung lượng RAM cần để lưu trữ.
7 Phân phối dữ liệu thông minh trong cụm phân mảnh (Sharded Cluster)
Để tối ưu hóa hiệu suất hệ thống, việc chọn shard key phù hợp là rất quan trọng nhằm phân phối dữ liệu đều giữa các shard, tránh tình trạng quá tải hoặc thiếu dữ liệu trên các nút Bên cạnh đó, cần đảm bảo rằng tập dữ liệu làm việc của từng shard phù hợp với dung lượng RAM của nút tương ứng, giúp giảm thiểu thời gian truy xuất dữ liệu và cải thiện tốc độ xử lý.
Việc phân phối đồng đều dữ liệu tránh hiện tượng một số shard bị quá tải RAM, trong khi các shard khác không được sử dụng hiệu quả.
Hệ thống có sử dụng replication, hãy cho ví dụ 1 trường hợp là chúng ta nên đọc (Read) dữ liệu từ secondary tốt hơn là từ Primary, giải thích lý do
ta nên đọc (Read) dữ liệu từ secondary tốt hơn là từ Primary, giải thích lý do
Một hệ thống phân tích dữ liệu (analytics) hiệu quả cần truy cập vào các báo cáo hoặc thống kê từ cơ sở dữ liệu một cách dễ dàng và nhanh chóng Điều quan trọng là hệ thống này không yêu cầu dữ liệu phải luôn luôn cập nhật theo thời gian thực (real-time), mà có thể sử dụng dữ liệu đã được lưu trữ hoặc tổng hợp để đảm bảo hiệu quả và tiết kiệm tài nguyên Việc không phụ thuộc vào dữ liệu mới nhất giúp tối ưu quá trình phân tích, giảm thiểu độ trễ và nâng cao khả năng ra quyết định dựa trên dữ liệu sẵn có.
Một ứng dụng bán hàng trực tuyến cần tổng hợp số lượng sản phẩm bán ra mỗi ngày hoặc mỗi tuần để hiển thị các báo cáo doanh thu.
Dữ liệu bán hàng được ghi vào primary, nhưng báo cáo chỉ cần cập nhật sau vài giây hoặc vài phút.
Lý do nên đọc từ secondary:
1 Giảm tải cho primary: o Primary cần ưu tiên phục vụ các tác vụ ghi dữ liệu, vốn quan trọng và yêu cầu đảm bảo tính toàn vẹn của dữ liệu. o Chuyển các truy vấn phân tích không khẩn cấp sang secondary giúp giảm thiểu áp lực lên primary, giữ hiệu suất cao cho các tác vụ ghi.
2 Tận dụng tài nguyên: o Secondary thường chỉ thực hiện sao chép dữ liệu từ primary, và nếu không tận dụng để đọc dữ liệu, tài nguyên của nó sẽ bị lãng phí.
3 Độ trễ không ảnh hưởng lớn: o Trong các báo cáo phân tích hoặc thống kê, việc dữ liệu có độ trễ nhỏ (vài giây đến vài phút) thường không gây ảnh hưởng lớn đến kết quả.
4 Tăng khả năng chịu tải của hệ thống: o Khi số lượng truy vấn đọc tăng cao, việc phân tán các truy vấn này sang secondary nodes giúp hệ thống xử lý được lượng lớn người dùng mà không làm giảm hiệu năng.
Những yếu tố nào ảnh hưởng đến tốc độ của câu truy vấn (Find) dữ liệu
1 Sử dụng hoặc không sử dụng chỉ mục (Indexes)
Trong MongoDB, việc không sử dụng chỉ mục phù hợp trong truy vấn sẽ khiến hệ thống phải quét toàn bộ các tài liệu trong bộ sưu tập (collection scan), gây ảnh hưởng tiêu cực đến hiệu suất hoạt động Ngược lại, một chỉ mục phù hợp giúp MongoDB truy xuất dữ liệu nhanh hơn, giảm thiểu số lượng tài liệu cần quét, từ đó tối ưu hóa hiệu suất truy vấn và tiết kiệm thời gian xử lý dữ liệu.
Khi thực hiện truy vấn `db.users.find({age: 25})`, nếu trường `age` không có chỉ mục, MongoDB sẽ thực hiện quét toàn bộ bộ sưu tập (COLLSCAN), gây chậm truy vấn khi dữ liệu lớn Ngược lại, nếu có chỉ mục `{age: 1}`, MongoDB sẽ tối ưu hóa truy vấn bằng cách chỉ quét qua các giá trị liên quan trong chỉ mục, giúp truy vấn nhanh hơn và nâng cao hiệu suất hệ thống.
2 Độ lớn và tính chọn lọc của dữ liệu
Trong MongoDB, tính chọn lọc (selectivity) của điều kiện truy vấn đóng vai trò quan trọng ảnh hưởng đến hiệu suất truy vấn Các truy vấn có điều kiện truy vấn có chọn lọc cao, tức là ít kết quả, sẽ thực thi nhanh hơn vì MongoDB quét ít dữ liệu hơn Ngược lại, những truy vấn trả về nhiều kết quả sẽ tiêu tốn nhiều tài nguyên hơn và mất thời gian lâu hơn Ngoài ra, độ lớn của bộ sưu tập cũng tác động đáng kể đến thời gian truy vấn; bộ sưu tập lớn hơn đòi hỏi khả năng tối ưu chỉ mục để giảm thời gian xử lý và nâng cao hiệu suất tổng thể.
For example, executing the query `db.orders.find({status: "completed"})` can impact performance if the `status` field has low selectivity; for instance, when 90% of documents have `status` set to "completed," MongoDB is required to scan many documents, which can lead to slower query response times.
3 Cách sắp xếp dữ liệu (Sorting)
Trong MongoDB, khi truy vấn yêu cầu sắp xếp dữ liệu (sort) mà không có chỉ mục hỗ trợ, hệ thống phải thực hiện sắp xếp trong bộ nhớ (blocking sort), gây tiêu tốn nhiều tài nguyên và thời gian Tuy nhiên, việc sử dụng chỉ mục hỗ trợ sắp xếp có thể giúp cải thiện đáng kể hiệu suất truy vấn, giảm thiểu tối đa thời gian xử lý và tiêu thụ tài nguyên hệ thống.
For example, running the query db.products.find({category: "electronics"}).sort({price: 1}) without a combined index on {category: 1, price: 1} forces MongoDB to sort the entire result set in memory, which can significantly impact performance.
4 Kích thước tài liệu và số lượng trường trả về
Trong quá trình làm việc với MongoDB, việc truy vấn các tài liệu có kích thước lớn hoặc trả về nhiều trường không cần thiết có thể gây mất nhiều thời gian do MongoDB phải đọc và truyền dữ liệu nhiều hơn Để tối ưu hiệu suất truy vấn và giảm tải hệ thống, người dùng nên sử dụng phép projection để chỉ truy xuất các trường dữ liệu cần thiết, giúp giảm lượng dữ liệu truyền tải và nâng cao tốc độ truy cập.
Trong việc tối ưu hóa truy vấn cơ sở dữ liệu, việc chọn lọc các trường cần thiết giúp giảm thiểu lượng dữ liệu truyền tải và nâng cao hiệu suất truy vấn Ví dụ, truy vấn không tối ưu là db.users.find({age: 25}), trong khi truy vấn tối ưu hơn là db.users.find({age: 25}, {name: 1, age: 1}), vì chỉ trả về các trường cần thiết như tên và tuổi của người dùng Việc này giúp giảm thiểu bớt dữ liệu không cần thiết, tối ưu hóa tốc độ truy cập và tăng hiệu quả của hệ thống.
5 Kích thước và vị trí của tập dữ liệu làm việc (Working Set)
Khi dung lượng dữ liệu lớn hơn RAM, MongoDB phải sử dụng ổ cứng để lưu trữ dữ liệu, điều này làm giảm hiệu suất truy cập do tốc độ đọc/ghi ổ cứng chậm hơn nhiều so với RAM.
Ví dụ: o Một bộ sưu tập lớn với tập dữ liệu làm việc không vừa RAM sẽ dẫn đến truy vấn chậm do phải đọc dữ liệu từ ổ đĩa.
6 Cấu hình chỉ mục phức tạp hoặc dư thừa
Số lượng chỉ mục quá lớn có thể làm tăng chi phí duy trì và chiếm dụng nhiều dung lượng RAM, từ đó làm giảm hiệu suất tổng thể của hệ thống Ngoài ra, cấu trúc chỉ mục không phù hợp, như chỉ mục quá tổng quát hoặc không phản ánh đúng mẫu truy vấn, cũng gây ảnh hưởng tiêu cực đến tốc độ truy vấn dữ liệu, làm chậm quá trình truy xuất thông tin cần thiết.
Ví dụ: o Nếu chỉ mục là {name: 1} nhưng truy vấn lại yêu cầu tìm kiếm theo {name:
"John", age: 30}, MongoDB không thể tận dụng chỉ mục một cách hiệu quả.
7 Quá tải trên cụm (Cluster Overload)
Trong hệ thống phân mảnh (sharded cluster), việc thiết kế shard key không hợp lý có thể gây ra rối loạn trong phân phối dữ liệu Nếu shard key không được tối ưu, dữ liệu sẽ không được phân bổ đều trên các shard, dẫn đến tình trạng quá tải và giảm hiệu năng hệ thống Do đó, việc chọn lựa shard key phù hợp đóng vai trò quan trọng trong việc duy trì cân bằng tải và tối ưu hóa hoạt động của hệ thống phân mảnh.
For example, a query like db.orders.find({region: "North"}) illustrates that if "region" is not the shard key or has low cardinality, the query will need to scan all shards to retrieve the results This can lead to inefficient query performance in sharded database systems Properly selecting a shard key with high cardinality is essential to optimize query efficiency and minimize unnecessary data scanning across multiple shards.
Đứng dước gốc độ người optimize hiệu năng của hệ thống hãy cho biết ưu điểm và nhược điểm lưu trữ dữ liệu phân tán trên hệ thống sharding
ưu điểm và nhược điểm lưu trữ dữ liệu phân tán trên hệ thống sharding. Ưu điểm của Sharding
1 Khả năng mở rộng theo chiều ngang (Horizontal Scaling) o Mô tả: Sharding cho phép phân phối dữ liệu trên nhiều máy chủ (shard), giúp mở rộng khả năng lưu trữ và xử lý khi dữ liệu tăng. o Lợi ích:
Xử lý hiệu quả khối lượng dữ liệu lớn.
Hỗ trợ các truy vấn có hiệu suất cao nhờ phân tán tải trên nhiều shard.
2 Hiệu suất cao hơn khi truy vấn song song o Mô tả: Truy vấn có thể được thực hiện đồng thời trên các shard khác nhau (routed queries). o Lợi ích:
Giảm thời gian xử lý khi chỉ một phần dữ liệu nằm trên shard cụ thể.
Tận dụng tối đa tài nguyên hệ thống.
3 Khả năng xử lý dữ liệu địa lý hoặc logic theo vùng o Mô tả: Sharding theo các giá trị như vùng địa lý hoặc nhóm logic giúp tập trung dữ liệu liên quan trên cùng một shard. o Lợi ích:
Giảm độ trễ do dữ liệu được lưu gần ứng dụng hoặc người dùng cụ thể.
4 Tăng khả năng chịu lỗi (Fault Tolerance) o Mô tả: Các shard có thể được sao chép thông qua replica sets, đảm bảo hệ thống tiếp tục hoạt động khi một số nút bị lỗi. o Lợi ích:
Độ tin cậy cao hơn.
Dữ liệu vẫn khả dụng trong các trường hợp xảy ra sự cố.
1 Độ phức tạp trong triển khai và quản lý o Mô tả: Cấu hình và quản lý sharding yêu cầu hiểu biết sâu về hệ thống và mẫu truy vấn. o Hạn chế:
Cần lựa chọn shard key phù hợp để tránh tình trạng phân phối dữ liệu không đồng đều.
Tăng chi phí quản trị và bảo trì.
2 Truy vấn phân tán (Scatter-Gather Query) o Mô tả: Truy vấn không dựa trên shard key sẽ gửi yêu cầu tới tất cả các shard, gây quá tải hệ thống. o Hạn chế:
Hiệu suất kém cho các truy vấn không tối ưu hoặc truy vấn toàn cục.
Tăng độ trễ khi phải hợp nhất dữ liệu từ nhiều shard.
3 Khó dự đoán hiệu năng o Mô tả: Hiệu suất của hệ thống phụ thuộc vào cách dữ liệu được phân phối. o Hạn chế:
Dữ liệu không phân phối đồng đều có thể khiến một số shard bị quá tải trong khi các shard khác nhàn rỗi.
4 Chi phí tài nguyên cao hơn o Mô tả: Sharding yêu cầu nhiều máy chủ hơn so với việc lưu trữ dữ liệu tập trung. o Hạn chế:
Tăng chi phí phần cứng, mạng, và bảo trì.
Yêu cầu quản lý config servers để duy trì metadata và phân phối dữ liệu.
5 Thách thức trong việc tái cấu trúc shard key o Mô tả: Khi cần thay đổi shard key, việc tái phân phối dữ liệu giữa các shard rất phức tạp và tốn kém. o Hạn chế:
Có thể gây gián đoạn hệ thống.
Yêu cầu nhiều thời gian và tài nguyên.
6 Tăng độ trễ trong thao tác ghi o Mô tả: Dữ liệu có thể cần được phân tán tới nhiều shard, làm tăng độ trễ ghi so với lưu trữ tập trung. o Hạn chế:
Tăng thời gian xử lý giao dịch nếu không tối ưu hóa cấu trúc shard. Khi nào nên sử dụng Sharding
Khi dữ liệu vượt quá khả năng lưu trữ và xử lý của một máy chủ đơn lẻ.
Khi cần hỗ trợ số lượng lớn truy vấn đọc hoặc ghi đồng thời.
Khi cần phân phối dữ liệu để đáp ứng nhu cầu truy cập địa phương hoặc theo nhóm logic.