Ayende @ Rahien

Unnatural acts on source code

Porting MVC Music Store to Raven: The 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:

image

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:

Albums

image

  • 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.

Genre

image

The genre document is an exact duplicate of the Genre table, no surprises here.

Cart

image

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

image

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.

Artist

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.

Tags:

Posted By: Ayende Rahien

Published at

Originally posted at

Comments

NC
05/18/2010 07:08 AM by
NC

"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?

Justin
05/18/2010 07:18 AM by
Justin

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. :)

Ayende Rahien
05/18/2010 07:22 AM by
Ayende Rahien

NC,

Precisely, this is also why I keep both the artist name and the artist id around.

Sergey Shishkin
05/18/2010 07:39 AM by
Sergey Shishkin

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.

ales
05/18/2010 08:15 AM by
ales

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.

A.

Ayende Rahien
05/18/2010 08:20 AM by
Ayende Rahien

Ales,

That topic is covered in one of the future posts

lurking-fanboy
05/18/2010 09:32 AM by
lurking-fanboy

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 ...

Corey Coogan
05/18/2010 01:43 PM by
Corey Coogan

Where's the fancy images of the model come from? Is that taken from the Raven UI?

Petr
05/18/2010 02:17 PM by
Petr

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.

Ayende Rahien
05/18/2010 02:21 PM by
Ayende Rahien

Petr,

You are correct, and in the real implementation, they are there.

Jesús López
05/18/2010 03:46 PM by
Jesús López

So, cart lines should have album titles for the same reason. Shouldn't it?

Ken Tong
05/19/2010 02:21 AM by
Ken Tong

Next series of posts would be "Giving Love to Raven - Raven Profiler"

Comments have been closed on this topic.