I've started learning NoSQL on an example of RavenDB. I've started with a simplest model, let's say we have topics that were created by users:
public class Topic
{
public string Id { get; protected set; }
public string Title { get; set; }
public string Text { get; set; }
public DenormalizedUser User { get; set; }
}
public class DenormalizedUser
{
public string Id { get; set; }
public string Name { get; set; }
}
public class User
{
public string Id { get; protected set; }
public string Name { get; set; }
public DateTime Birthdate { get; set; }
//some other fields
}
We don't need the whole User
for displaying a Topic
, so I've denormalized it to DenormalizedUser
, containing an Id
and a Name
.
So, here are the questions:
1) Is this approach correct for NoSQL?
2) How to handle cases when User
changes the Name
? Do I need to manually update all the Name
fields in denormalized classes?
Shaddix you can use the Raven DB Include function to load the User using the UserId from your topic.
var topic = _session.Load<Topic>(topicId)
.Customize(x => x.Include<Topic>(y => y.UserId));
var user = _session.Load<User>(topic.UserId);
The Load for Topic will 'preload' the User and both Loads will only result in one GET request. (I couldn't reply directly to your response to Ayende due to my reputation).
You also use the alternative (and probably clearer) .Include() function without Customize().
http://docs.ravendb.net/consumer/querying/handling-document-relationships.html
shaddix,
You don't need to denormalize, you can hold a reference to the id and then Include that when you load from the server
1) Yes, this approach works fine and the result is, that you only need to load the topic-document when you want to display it along with the name of its user. However, as Ayende states, the perfomance will be nearly the same as if you didn't denormalize the user and just include it when needed. If you don't worry about multiple-server deployment I recommend that approach.
2) If you really want to denormalize the user, then you can update all topics referencing this user simply with a set based operation. Look at this: http://ravendb.net/faq/denormalized-updates