DCSIMG
How To: Model Inheritance in Databases - Guy Burstein's Blog

Guy Burstein's Blog

Developer Evangelist @ Microsoft

News

Guy Burstein The Bu

Disclaimer
Postings are provided 'As Is' with no warranties and confer no rights.

Guy Burstein LinkedIn Profile

TwitterCounter for @bursteg

Links

Articles

Blogs I Read

How To: Model Inheritance in Databases

How To: Model Inheritance in Databases

Playing with some Object Relational Mapping technologies these days such as Linq to SQL and ADO.Net Entity Framework, one of the capabilities that is important to check is which strategies of inheritance modeling is supported by each technology.

This post talks about how to model inheritance in the database, regardless the technology that we will use later to talk to the database.

Assuming that the business entities look somewhat similar to this:

 Model Inheritance in Databases

There are three common strategies of modeling this class hierarchy in the database:

Table per Class Hierarchy

This strategy means that all the class hierarchy is stored in a single table in the database. The top level columns can allow nulls but all the lower level columns must allow nulls. There is an additional column (in the following example: PersonType) which is the discriminator - it holds a value indicating the level in the hierarchy to which the record matches.

Table per Class Hierarchy

This strategy is very useful when selecting rows from the database of multiple person types. The select goes only to this table and therefore more efficient. It is also very simple to add a column to all the person types - we just have to add it to this table. The downside of this strategy is that it cannot enforce constrains such as not allowing nulls in columns that are not in the top level. It also may lead to many columns with null values and therefore to wasting some disk space.

Table per Subclass

This strategy means that each level in the class hierarchy is represented in a table in the database. The top level table (Person) contains the columns that are common to all levels and as we go down in the hierarchy, we get only the additional columns for the specific level. The root table contains the discriminator columns, for joining with the appropriate table when selecting rows.

Table per Subclass

This strategy there can require less disk space, and can enforce required columns. It also allows adding new columns to subclasses without having to change other tables. The down side of this strategy is the cost of each select statements and the amount of joins it requires.

Table per Concrete Class

Since not all the classes in the above diagram are concrete (Person and Employee classes are abstract), there is no need to create tables for each level in the hierarchy. In this strategy each concrete class has its own table.

Table per Concrete Class

Notice that there isn't any table that contain any common columns. This means that adding columns to all tables should be done on each of the tables. Selecting rows is very efficient when selecting a single type of person, but can cost much more when we need to union between the tables in order to get multiple types or find the type of the person only by its primary key.

Conclusion

There are 3 common ways of modeling inheritance in databases, each on of them has its pros and cons. It is very important to be familiar with those strategies when investigating ORM technologies.

Enjoy!

Comments

Anonymous said:

Another one:

Union of all classes; needs a flag(column) that discriminates between types.

In most cases 'Table per Subclass' is the best choice.

# September 30, 2007 6:37 PM

napyfab:blog» Blog Archive » links for 2007-10-02 said:

Pingback from  napyfab:blog» Blog Archive » links for 2007-10-02

# October 3, 2007 1:35 AM

Guy Burstein [MVP] said:

Linq to SQL Stored Procedures with Multiple Results - IMultipleResults Continuing my post series about

# October 5, 2007 9:10 PM

Wayne said:

Got a question for ya.  In the 'Table per Subclass' model, how are joins made between tables?  Is the PersonID key propagated to its children?  If not how are they joined.  Also, with this model, how does one join to the correct subclass?  I notice the Person entity includes personType Attribute.  How is that used in a SQL statement to find the proper child entity?

# November 1, 2007 5:06 AM

גיא בורשטיין said:

Hi Wayne,

This is the major downside of this approach. You have to know what type you're looking for when you select the data, in order to select from the right table.

Why do you need to join between two subclasses (two sub-tables)?

Guy

# November 1, 2007 10:04 PM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# December 2, 2007 9:29 PM

Tamir Shlomi said:

Great stuff.

Thanx a lot,

Tamir Shlomi.

# February 3, 2008 3:19 PM

André Ricardo said:

And if i want to search for Bill in the database?

Like:

SELECT * FROM SalesPerson, Programmer, Contact WHERE SalesPerson.FirstName = 'Bill' OR Programmer.FirstName = 'Bill' OR Contact.FirstName = 'Bill'

??????

I'm very, very lost..

I'm trying to implement inheritance in SQL but i don't think i have enough knowledge to do this...

# May 14, 2008 12:10 AM

Bob Tabor said:

Wow, awesome article.

I'll  take a crack at answering two questions I didn't see answered above ... I'll disclaim any real expertise in this area, so take this with a grain of salt.

@Guy ... joining between two subclasses ... what came to mind first is the scenario where employee hierarchy ... I'm a manager of some, and I report to others.  Another example would be things that are composites of (potentially) other composites for systems that have to allow for product customization.  I haven't actually sat down to design this, so I might be missing something obvious here.

@Andre ... I think you would want to avoid the "Table per Concrete Class" approach, which seems to be what you're modeling your query after.  Either of the other two approaches would work for what you're trying to accomplish.

Hope that helps!

# June 5, 2008 9:12 PM

Peter said:

It seems to me that the Table per Concrete Class has nothing to do with inheritance since every class is mapped to a table.

# July 1, 2008 1:05 AM

Peter said:

Is the Table per Subclass approach actually same as the Table Per Type?

Thanks.

# July 1, 2008 1:20 AM

Peter said:

I think I have misunderstood the Table per Concrete Class concept (or the whole concept about model inheritance) earlier (the July 1, 2008 1:05AM comment).  

I'm confused about the terms related to model interance in databases since MS and other articles are using different terms.  Here is my understanding about the terms:

Table per subclass = Table per type (TPT) = Table per class

Table per abstract class = Table per Hierarchy (TPH)

Is my understanding correct?

# July 1, 2008 10:52 PM

Gus said:

@Peter. Table per abstract class != Table per Hierarchy. In TPH you have only one table mapped to the Base class, in this example Person.

But since there might be other abstract classes derived from an abstract class, in the TPA you might end up with more than one table for one Hierarchy.

I hope to have cleared that one up.

Cheers!

# August 26, 2008 8:14 AM

Tawhid said:

Great stuff Bursteins.

I'm trying to model my companies data using SID, and found this article good for recollecting UML techniques.

Cheers

Tawhid

# November 18, 2008 12:08 PM

Modelling inheritance in a database « Low IT said:

Pingback from  Modelling inheritance in a database «  Low IT

# September 29, 2009 3:35 PM

Glynd??r University - The telly nerd’s project » Database said:

Pingback from  Glynd??r University - The telly nerd’s project » Database

# February 5, 2010 4:19 PM

computer error comedy film said:

Some of the harsher colleges of the valve were allowed down as the form finished more traditional; for bug, in some personal services of the proximity, sullivan included an low, but this object was then grey from the european law.

# May 20, 2010 12:09 AM

rezaxm said:

how can i implement table per subclass strategy?

i have a posts  table (post_id(KEY), date, text)

and a comments table(comment_id(KEY)->posts.post_id, post_id->posts.post_id)

i try to do this by replace comment_id>post_id relation to inheritance in o/r designer, but it cause this error:

the selected classes are mapped to different sources or the child class containts a primary key. classes participanting in an inheritance must map to same source and the derived class cannot have a primary key.

:(

# July 26, 2011 6:48 PM

Milox said:

awesome man, great explanation!

# October 12, 2011 11:04 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: