MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Mongoose điền và đối tượng lồng vào nhau

Điều đầu tiên cần hiểu về dân số cầy mangut là nó không phải là phép thuật mà chỉ là một phương pháp tiện lợi cho phép bạn truy xuất thông tin liên quan mà không cần tự mình thực hiện.

Về cơ bản, khái niệm này được sử dụng khi bạn quyết định rằng bạn sẽ cần đặt dữ liệu trong một bộ sưu tập riêng biệt thay vì nhúng dữ liệu đó và các cân nhắc chính của bạn thường là về kích thước tài liệu hoặc nơi thông tin liên quan đó phải được cập nhật thường xuyên. duy trì dữ liệu nhúng khó sử dụng.

Phần "không kỳ diệu" là về cơ bản những gì xảy ra bên dưới là khi bạn "tham chiếu" một nguồn khác, hàm điền tạo một truy vấn / truy vấn bổ sung cho bộ sưu tập "có liên quan" đó để "hợp nhất" các kết quả đó của nguồn gốc đối tượng mà bạn đã truy xuất. Bạn có thể tự làm việc này, nhưng có phương pháp để đơn giản hóa công việc một cách thuận tiện. Việc xem xét "hiệu suất" rõ ràng là không có một chuyến đi vòng nào đến cơ sở dữ liệu (phiên bản MongoDB) để lấy tất cả thông tin. Luôn có nhiều hơn một.

Làm mẫu, lấy hai bộ sưu tập:

{ 
    "_id": ObjectId("5392fea00ff066b7d533a765"),
    "customerName": "Bill",
    "items": [
        ObjectId("5392fee10ff066b7d533a766"),
        ObjectId("5392fefe0ff066b7d533a767")
    ]
}

Và các mặt hàng:

{ "_id": ObjectId("5392fee10ff066b7d533a766"), "prod": "ABC", "qty": 1 }
{ "_id": ObjectId("5392fefe0ff066b7d533a767"), "prod": "XYZ", "qty": 2 }

Điều "tốt nhất" có thể được thực hiện bởi mô hình "được tham chiếu" hoặc việc sử dụng điền (ẩn) là:

var order = db.orders.findOne({ "_id": ObjectId("5392fea00ff066b7d533a765") });
order.items = db.items.find({ "_id": { "$in": order.items } ).toArray();

Vì vậy, rõ ràng có "ít nhất" hai truy vấn và hoạt động để "kết hợp" dữ liệu đó.

Về cơ bản, khái niệm nhúng là câu trả lời của MongoDB về cách đối phó với việc không hỗ trợ "tham gia". Vì vậy, thay vì phân chia dữ liệu thành các bộ sưu tập chuẩn hóa, bạn cố gắng nhúng dữ liệu "có liên quan" trực tiếp vào tài liệu sử dụng nó. Ưu điểm ở đây là có một thao tác "đọc" duy nhất để truy xuất thông tin "liên quan" và cũng có một điểm duy nhất của hoạt động "ghi" để cập nhật các mục nhập "cha" và "con", mặc dù thường không thể ghi vào "nhiều" con cùng một lúc mà không cần xử lý "danh sách" trên ứng dụng khách hoặc chấp nhận các hoạt động ghi "nhiều" và tốt nhất là trong xử lý "hàng loạt".

Dữ liệu sau đó trông giống như thế này (so với ví dụ ở trên):

{ 
    "_id": ObjectId("5392fea00ff066b7d533a765"),
    "customerName": "Bill",
    "items": [
        { "_id": ObjectId("5392fee10ff066b7d533a766"), "prod": "ABC", "qty": 1 },
        { "_id": ObjectId("5392fefe0ff066b7d533a767"), "prod": "XYZ", "qty": 2 }
    ]
}

Do đó, việc tìm nạp dữ liệu thực sự chỉ là vấn đề:

db.orders.findOne({ "_id": ObjectId("5392fea00ff066b7d533a765") });

Ưu và nhược điểm của một trong hai sẽ luôn phụ thuộc phần lớn vào cách sử dụng ứng dụng của bạn. Nhưng trong nháy mắt:

Nhúng

  • Tổng kích thước tài liệu với dữ liệu được nhúng thường sẽ không vượt quá 16MB dung lượng lưu trữ (giới hạn BSON) hoặc nếu không (theo hướng dẫn) có các mảng chứa 500 mục nhập trở lên.

  • Dữ liệu được nhúng thường không yêu cầu thay đổi thường xuyên. Vì vậy, bạn có thể sống chung với "sự trùng lặp" do việc hủy chuẩn hóa không dẫn đến việc phải cập nhật những "bản sao" đó với cùng một thông tin trên nhiều tài liệu mẹ chỉ để thực hiện thay đổi.

  • Dữ liệu liên quan thường được sử dụng cùng với nguồn gốc. Điều đó có nghĩa là nếu trường hợp "đọc / ghi" của bạn luôn cần "đọc / ghi" cho cả cấp độ gốc và cấp độ con thì việc nhúng dữ liệu cho các phép toán nguyên tử là rất hợp lý.

Tham khảo

  • Dữ liệu liên quan sẽ luôn vượt quá giới hạn 16MB BSON. Bạn luôn có thể xem xét một cách tiếp cận kết hợp của "bán vé", nhưng không thể vi phạm giới hạn cứng chung của tài liệu chính. Các trường hợp phổ biến là "đăng bài" và "nhận xét" trong đó hoạt động "bình luận" dự kiến ​​sẽ rất lớn.

  • Dữ liệu liên quan cần được cập nhật thường xuyên. Hoặc về cơ bản trường hợp bạn "bình thường hóa" vì dữ liệu đó được "chia sẻ" giữa nhiều phụ huynh và dữ liệu "liên quan" được thay đổi thường xuyên đến mức sẽ không thực tế để cập nhật các mục được nhúng trong mọi "gốc" nơi mục "con" đó xuất hiện . Trường hợp dễ dàng hơn là chỉ cần tham chiếu đến "con" và thực hiện thay đổi một lần.

  • Có sự tách biệt rõ ràng giữa việc đọc và ghi. Trong trường hợp có thể bạn sẽ không luôn yêu cầu thông tin "liên quan" đó khi đọc "phụ huynh" hoặc không cần phải luôn thay đổi "phụ huynh" khi viết cho trẻ, có thể có lý do chính đáng để tách mô hình như đã tham chiếu. Ngoài ra, nếu có mong muốn chung là cập nhật nhiều "tài liệu con" cùng một lúc trong đó những "tài liệu con" đó thực sự là tham chiếu đến một bộ sưu tập khác, thì việc triển khai thường hiệu quả hơn khi dữ liệu nằm trong một bộ sưu tập riêng biệt. bộ sưu tập.

Vì vậy, thực sự có một cuộc thảo luận rộng rãi hơn về "ưu / nhược điểm" cho một trong hai vị trí trong tài liệu MongoDB về Mô hình dữ liệu, bao gồm các trường hợp sử dụng khác nhau và các cách tiếp cận bằng cách sử dụng mô hình nhúng hoặc tham chiếu được hỗ trợ bởi phương pháp điền.

Hy vọng rằng các "điểm chấm" được sử dụng, nhưng khuyến nghị chung là hãy xem xét các kiểu sử dụng dữ liệu của ứng dụng của bạn và chọn những gì tốt nhất. Có "tùy chọn" để nhúng "nên" là lý do bạn chọn MongoDB, nhưng nó thực sự là cách ứng dụng của bạn "sử dụng dữ liệu" đưa ra quyết định phương pháp nào phù hợp với phần nào của mô hình dữ liệu của bạn (vì nó không "tất cả hoặc không có gì") tốt nhất.

  1. Lưu ý rằng vì điều này ban đầu được viết nên MongoDB đã giới thiệu $lookup toán tử thực sự thực hiện "nối" giữa các bộ sưu tập trên máy chủ. Đối với mục đích của cuộc thảo luận chung ở đây, hãy sử dụng "tốt hơn" trong hầu hết các trường hợp mà chi phí "nhiều truy vấn" do populate() phải gánh chịu và "nhiều truy vấn" nói chung vẫn có "chi phí đáng kể" phát sinh với bất kỳ $lookup nào hoạt động.

Nguyên tắc thiết kế cốt lõi là "nhúng" có nghĩa là "đã có" trái ngược với "tìm nạp từ một nơi khác". Về cơ bản, sự khác biệt giữa "trong túi của bạn" và "trên giá" và trong điều kiện I / O thường giống "trên giá trong thư viện ở trung tâm thành phố" và đặc biệt là xa hơn nữa đối với các yêu cầu dựa trên mạng.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB là gì và nó hoạt động như thế nào?

  2. mongoexport E QUERY Cú pháp Lỗi:Số nhận dạng không mong muốn

  3. Cách chèn nhiều tài liệu cùng lúc trong MongoDB thông qua Java

  4. Nối dữ liệu vào tệp gridfs hiện có

  5. Trình điều khiển Mongodb C # chỉ trả về các tài liệu con phù hợp trong mảng