0

I'm having a hard time deciding on multi table inheritance vs an abstract base model. Let's say I have a Django project with a load of models, say...

Video, Document, Picture, and a load more.

They will share some common fields and pieces of functionality. Eg, I might want to show a list of the latest 20 items mixed of all types, and a user can rate or tag any of these content types, or a user can have their own list which will include multiple content types.

Something like this:

BaseItem
    - added
    - updated
    - tags
    - ratings

Video(BaseItem)

Document(BaseItem)

Person(BaseItem)

I'm wondering if this is a good case for using multi table inheritance or if I should simply use an abstract base class.

1 - Use Multi Table Inheritence.

Thus would mean I could easily query and display the latest 20 items across all types. I could use something like the InheritenceManager from django-model-utils to get the correct types when needed. I'd no doubt need to be careful with using select_related and keeping an eye on my query count when retrieving items.

2 - Use an abstract base class.

This seems as though it would be more simple in knowing exactly what's going on, and that it would save JOINs against a very large table when just querying a single content type, but I guess I wouldn't be able to combine the types at database level and so would need to do so in Python which feels like a fudge. I'd also need my Tag model to use a GFK to multiple types rather than an FK to just the BaseItem.

Multi table inheritance feels like it should be right from some sort of purity standpoint, but I've seen people recommend that it's avoided where possible. In my case I feel as though I'm not sure the extra JOINs and potential ability for someone to shoot themselves in the foot by missing a select_related call would be worth it, and I also feel as though I'm not super clear on where this might cause problems in the future.

Any thoughts on which way would be a better choice and why, or anywhere I could find some more discussion around the trade offs?

Thanks!

Ludo
  • 2,739
  • 2
  • 28
  • 42

1 Answers1

1

Use an abstract class. Video, Document and Person have no conceptual parent class. This will avoid creating a new table for BaseItem that requires a join every time you pull the data in any one of those tables. If you are just attaching methods to the table and not columns, then I'd also suggest to just use mixins.

Victor 'Chris' Cabral
  • 2,135
  • 1
  • 16
  • 33