Porting MVC Music Store to RavenThe data model
The MVC Music Store release came as a fortunate surprise, I wanted to write a sample application for Raven, and having someone else write all the hard bits (the UI :-)) for me and leave to just replace the data access is just about ideal. The overall goal is to touch absolutely no JS/HTML code in the app, replacing just the controllers. It would be interesting to see if I’ll manage to do that.
The database model for the application is:
You can see some interesting things in the schema immediately:
- The Cart table should probably be called CartLineItem, because it stores a row per item in the cart.
- The CartId is not an foreign key, but a reference to the user name or the session id.
- The Artist table only hold the artist name, there is no other data.
With this information, I think that the following data model would be appropriate:
- The album document contains a reference to the Genre as well as the Genre’s name. This allows us to display the album without having to refer to the Genre document.
- The album document contains the artist name and id, for much the same reason.
- There isn’t actually a set of Artist documents in the database. We don’t keep any information about an artist, except its name, so I didn’t see a reason to introduce it at this time.
The genre document is an exact duplicate of the Genre table, no surprises here.
The cart is a pretty common document format, we have a single document and it contains an array of elements where the relational model contained a set of rows. Note that the UserIdentifier is where we store the user id or the session id for the cart.
Order is another pretty standard document format. We aggregate all the order information to a single document, and we aggregate related information (Address) to a specific node.
There is no artist document.
Why does Genre deserve a standalone document while Artist gets subsumed into Album?
For the simple reason that the application does something with Genres (if only just displaying their description) where the only thing that is done with Artists is displaying their name in the context of an album. At this point, I consider Artist to be wholly owned by album, so there is no reason to keep a separate document for it. The only reason that album’s artist have and artist id is that I am assuming (based on the data) that the source for artist is an external system that does something a bit more meaningful with it than keep the artist name around.
This is just one half of the work we need to do, we have defined the data model, now we need to consider how this is used in a broader context, and add the query model using indexes. That will be covered in a future post.
More posts in "Porting MVC Music Store to Raven" series:
- (31 May 2010) StoreManagerController, part 2
- (29 May 2010) StoreManagerController
- (28 May 2010) Porting the checkout process
- (25 May 2010) StoreController
- (24 May 2010) Advanced Migrations
- (23 May 2010) Migrations
- (22 May 2010) Porting the HomeController, the Right Way
- (21 May 2010) Porting the HomeController, the map/reduce way
- (20 May 2010) Data migration
- (19 May 2010) Setting up the application
- (18 May 2010) The data model
"For the simple reason that the application does something with Genres (if only just displaying their description) where the only thing that is done with Artists is displaying their name in the context of an album."
What happens if the store was to be extended to include Artist information at a later date. Photo, bio, etc.
Would you create an Artist document that does not belong to the Album, and link from the album to the artist if a artist document happen to exist?
I just wanted to say thanks for writing down your thoughts and modus operandi for how you would re-do this with Raven. For someone else like me used to thinking in SQL-terms it's very educating. Thanks. :)
Precisely, this is also why I keep both the artist name and the artist id around.
Very interesting. Another thing to think about is whether you want to de-normalize prices in the shopping cart. I think it might be a good business decision to allow the user to buy with "old" prices rather than silently swapping the prices upon checkout or showing an "error" while he was shopping.
And what about adding new Album from same artist? You will lookup all albums to create dropdown to select an Artist on new Album, or user will type in Artist again even he exists in DB so then in short time we can have artists like (Ozzy Osbourne, Ozzzy Osbourne, Ozy Osbourne) , or application does not enable adding new albums/artists into DB?
Anyway thank you for post. I found RavenDB and other NoSQL DB interesting because of your work.
That topic is covered in one of the future posts
Ah you have changed the release dates of this series future posts ... I was looking forward to read some good information this whole day. Ah well, back to work it is ...
Where's the fancy images of the model come from? Is that taken from the Raven UI?
No, I am using this; http://jsonviewer.stack.hu/
Why Order lines don't contain Album titles? When I want display order I need "joining" with albums and when any album is modified/deleted I don't have it's (original) name.
You are correct, and in the real implementation, they are there.
So, cart lines should have album titles for the same reason. Shouldn't it?
Next series of posts would be "Giving Love to Raven - Raven Profiler"