Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB, C# and NoRM + Denormalization

I am trying to use MongoDB, C# and NoRM to work on some sample projects, but at this point I'm having a much harder time wrapping my head around the data model. With RDBMS's related data is no problem. In MongoDB, however, I'm having a difficult time deciding what to do with them.

Let's use StackOverflow as an example... I have no problem understanding that the majority of data on a question page should be included in one document. Title, question text, revisions, comments... all good in one document object.

Where I start to get hazy is on the question of user data like username, avatar, reputation (which changes especially often)... Do you denormalize and update thousands of document records every time there is a user change or do you somehow link the data together?

What is the most efficient way to accomplish a user relationship without causing tons of queries to happen on each page load? I noticed the DbReference<T> type in NoRM, but haven't found a great way to use it yet. What if I have nullable optional relationships?

Thanks for your insight!

like image 877
jocull Avatar asked Mar 18 '11 14:03

jocull


People also ask

Does MongoDB use C++?

Welcome to the documentation site for the official MongoDB C++ driver. You can add the driver to your application to work with MongoDB using the C++11 or later standard.

Can you use MongoDB with C#?

By developing with C# and MongoDB together one opens up a world of possibilities. Console, window, and web applications are all possible. As are cross-platform mobile applications using the Xamarin framework.

What is a MongoDB driver?

The official MongoDB Node. js driver allows Node. js applications to connect to MongoDB and work with data. The driver features an asynchronous API which allows you to interact with MongoDB using Promises or via traditional callbacks.


2 Answers

The balance that I have found is using SQL as the normalized database and Mongo as the denormalized copy. I use a ESB to keep them in sync with each other. I use a concept that I call "prepared documents" and "stored documents". Stored documents are data that is only kept in mongo. Useful for data that isn't relational. The prepared documents contain data that can be rebuilt using the data within the normalized database. They act as living caches in a way - they can be rebuilt from scratch if the data ever falls out of sync (in complicated documents this is an expensive process because these documents require many queries to be rebuilt). They can also be updated one field at a time. This is where the service bus comes in. It responds to events sent after the normalized database has been updated and then updates the relevant mongo prepared documents.

Use each database to their strengths. Allow SQL to be the write database that ensures data integrity. Let Mongo be the read-only database that is blazing fast and can contain sub-documents so that you need less queries.

** EDIT ** I just re-read your question and realized what you were actually asking for. I'm leaving my original answer in case its helpful at all.

The way I would handle the Stackoverflow example you gave is to store the user id in each comment. You would load up the post which would have all of the comments in it. Thats one query.

You would then traverse the comment data and pull out an array of user ids that you need to load. Then load those as a batch query (using the Q.In() query operator). Thats two queries total. You would then need to merge the data together into a final form. There is a balance that you need to strike between when to do it like this and when to use something like an ESB to manually update each document. Use what works best for each individual scenario of your data structure.

like image 137
Jake Hoffner Avatar answered Sep 27 '22 16:09

Jake Hoffner


I think you need to strike a balance.

If I were you, I'd just reference the userid instead of their name/reputation in each post.

Unlike a RDBMS though, you would opt to have comments embedded in the document.

like image 27
Andrew Avatar answered Sep 27 '22 18:09

Andrew