2012-06-24 5 views
6

Tôi đang lưu trữ một chuỗi trong cơ sở dữ liệu cùng với các chủ sở hữu của chuỗi (một hoặc nhiều chủ sở hữu trên mỗi chuỗi).Làm cách nào để liên kết dữ liệu trong MongoDB?

Tôi đã luôn làm việc với MySQL, một cơ sở dữ liệu quan hệ thông thường. Trong trường hợp đó, tôi sẽ lưu trữ chuỗi cùng với một id duy nhất trong một bảng, và sau đó là id duy nhất của chuỗi cùng với các chủ sở hữu (như nhiều bản ghi) trong một bảng thứ hai.

Sau đó tôi có thể tìm nạp chuỗi của chủ sở hữu bằng cách sử dụng Tham gia SQL.

Tôi hiện đang làm việc trên một dự án sử dụng MongoDB và tôi đang làm tương tự như trên.

Điều này có được coi là sai khi làm việc với cơ sở dữ liệu NoSQL không? Tôi có nên không suy nghĩ về 'quan hệ' khi làm việc với NoSQL không?

Một cách khác tôi có thể nghĩ đến việc đạt được như nhau trong MongoDB được lưu trữ nó như thế này:

{ 
    "string": "foobar", 
    "owners": [ 
     "owner1", 
     "owner2", 
     "owner3" 
    ] 
} 

Tuy nhiên, trong trường hợp này, tôi không chắc chắn làm thế nào tôi sẽ tìm kiếm cho "tất cả các chuỗi thuộc sở hữu của owner1" .

+7

Vui lòng không sử dụng "NoSQL" làm ô. Bạn đang sử dụng MongoDB. Đó là nó."NoSQL" có nghĩa là * quá nhiều và quá ít * :-) –

Trả lời

2

Điều này giống như cách tiếp cận chính xác; tuy nhiên, hãy nhớ rằng nó luôn phụ thuộc vào toàn bộ dự án của bạn, mục đích là gì (hiệu suất, tính linh hoạt), truy vấn nào bạn định chạy nhiều nhất, nếu bạn cần chạy truy vấn đặc biệt và các yếu tố khác. Nói chung, mặc dù, bằng cách sử dụng các tài liệu lồng nhau, như bạn đã viết, là sự thay thế chính xác để sử dụng các phép nối và khóa ngoài.

Hãy ghi nhớ cũng là maximum document size (hiện tại là 16MB), đây sẽ là mối quan ngại nếu có nhiều (giống như hàng trăm nghìn) chủ sở hữu của một chuỗi nhất định.

+0

Cảm ơn bạn. Tôi không phải lo lắng về kích thước tài liệu tối đa vì tôi sẽ không nhận được bất kỳ nơi nào gần với nó. Truy vấn phổ biến nhất của tôi sẽ là chèn. Rất, rất ít phát hiện. – xbonez

5

Để bổ sung câu trả lời của dbaseman:

Có, cách tiếp cận của bạn có vẻ ổn. Bạn có thể dễ dàng tìm kiếm "tất cả các chuỗi thuộc sở hữu của chủ sở hữu1"

db.collection.find({owners: 'author1'}) 

Điều này có thể do mongodb xử lý mảng theo cách đặc biệt.

+0

Cảm ơn bạn đã hiển thị ví dụ về truy vấn. – xbonez

6

Điều này có được coi là sai khi làm việc với cơ sở dữ liệu NoSQL không? Tôi có nên không suy nghĩ về 'quan hệ' khi làm việc với NoSQL không?

Có quá nhiều câu hỏi về trường hợp nhúng và quá ít.

Somethings chưa được đề cập ở đây mà cần phải được xem xét nếu bạn muốn nhúng:

  • sẽ kích thước tài liệu được tăng ồ ạt? Nếu vậy thì tài liệu có thể thường xuyên di chuyển trên đĩa, đây là một điều xấu.
  • Hàng có liên quan có nhiều lần tham gia vào bộ sưu tập mà tôi đang làm việc (ví dụ: video không thể nhúng user). Nếu đây là trường hợp bạn có thể gặp sự cố khi sao chép dữ liệu dư thừa từ hàng có liên quan vào tài liệu phụ, đặc biệt là khi cập nhật dữ liệu dư thừa đó.
  • Tôi sẽ cần hiển thị các kết quả này như thế nào?

Hiển thị kết quả luôn là quyết định quan trọng trong việc có nhúng hay không. Nếu bạn cần phân trang số hàng cao, giả sử 1000, bạn sẽ cần sử dụng toán tử $slice trong truy vấn thông thường hoặc khung tổng hợp. Tại 1000 tôi thừa nhận nó có thể là khá nhanh nhưng sớm hay muộn rằng hoạt động trong bộ nhớ sẽ trở nên chậm hơn so với truy vấn bình thường (infact nó luôn luôn nên được).

Nếu bạn cần phân loại phức tạp và hiển thị các tài liệu phụ, bạn có thể muốn chia này ra và thay vào đó có cấu trúc tài liệu của:

{ 
    "string": "foobar", 
    "owners": [ 
     ObjectId(), 
     ObjectId(), 
     ObjectId() 
    ] 
} 

Tôi nghĩ rằng điều này thực sự có thể là một cấu trúc performant hơn anyway cho dữ liệu của bạn từ các âm thanh owner giống như một hàng user trong bộ sưu tập users.

Thay vì điền các tài liệu phụ có thể thay đổi dữ liệu của người dùng, bạn chỉ có thể tham khảo _id của họ. Đây là khá kool kể từ khi bạn có thể nhúng mối quan hệ nhưng đồng thời tài liệu sẽ chỉ phát triển rất ít hy vọng có nghĩa là một cơ hội thấp của chuyển động đĩa liên tục, không chỉ có vậy mà một bộ làm việc nhỏ hơn tạo ra một hoạt động hiệu quả hơn tổng thể. Không chỉ vậy nhưng tất nhiên, _id của chủ sở hữu hiếm khi thay đổi, do đó, các thao tác duy nhất bạn sẽ cần phải có nhiều khả năng nhất trong tập con dữ liệu này là tạo và xóa.

Quay lại phân loại và phân trang phức tạp. Với dữ liệu này, tất nhiên bạn có thể nhận được tất cả các id owner với một chuyến đi khứ hồi và sau đó trong một chuyến đi khứ hồi khác, bạn có thể truy vấn những hàng chủ sở hữu đó trong bảng users với truy vấn thông thường bằng cách sử dụng $in cho phép hiển thị phức tạp mà bạn yêu cầu.

Vì vậy, cấu trúc tổng thể này, tôi đã tìm thấy, rất hiệu quả. Tất nhiên cấu trúc này phụ thuộc vào truy vấn của bạn, có thể tốt hơn để thay thế id chuỗi trên người dùng nhưng trong trường hợp này, không phải vì người dùng có thể sở hữu nhiều chuỗi như vậy tôi sẽ nói nó là một nhiều-> nhiều mối quan hệ được nhúng vào bên chuỗi.

Hy vọng rằng điều này giúp và tôi đã không đi vòng vòng,

3

Khi giao dịch với dữ liệu nhúng tôi khuyên bạn nên nhận được để làm quen với các hành vi Atomicity ở Mông Cổ. Một điểm khởi đầu tốt sẽ là ở đây: http://docs.mongodb.org/manual/core/data-modeling/#atomicity

Trong trường hợp cụ thể của bạn khi thêm/loại bỏ một ObjectId người dùng (theo khuyến cáo của Sammaye) để mảng "chủ sở hữu" của bạn, bạn sẽ muốn sử dụng a findAndModify() hoạt động trên tài liệu chuỗi để đảm bảo rằng khi nhiều ghi vào tài liệu đó xảy ra, tính toàn vẹn dữ liệu vẫn được duy trì.

Trong hoạt động này, tôi khuyên bạn nên sử dụng các toán tử sau:

  1. Khi thêm một chủ sở hữu, $ addToSet để ngăn chặn bản sao
  2. Khi tháo một chủ sở hữu, $ kéo

Cả được ghi lại ở đây: http://docs.mongodb.org/manual/reference/operators/#update-operators-array