Database design help – Splitting out tables
Asked By: David Reid
Originally Asked On: 2014-01-05 22:54:58
Asked Via: stackoverflow
I am building out an app that have different types of “posts” and a user can insert as many of these as they like. The posts though can be of different types, for example an image post, video post, text post etc… and obviously these will all have different fields in the database. An example would be that the image type will have:
Image ---------- date image_url
and the text post might have:
Text ---------- date title content
Now for each of the different types, do I have a unique table and just link the user to these? Assuming this is correct, If I want to show them in date order, do I do this with a
JOIN
, or am I completely on the wrong track.Thanks for any help in advance!
He received 3 answers
eventually accepting:
Ezequiel Muns’s answer to
Database design help – Splitting out tables
The natural way to model what you’re doing here is by mapping an inheritance hierarchy into your relational schema.
What you want is to take all the common elements of all posts (post_id, date_created, user_id, etc.) plus a
type
field and you make that your ‘base’ table. This table represents allposts
regardless of the specific kind of post it is.Next you take all the specific attributes for each type of post and create a table for that specific type (these are the ‘children’ tables). The primary key of this table is also a foreign key into the base table (post_id).
The
type
field in the base table references which specific table a post belongs to.So it all ends up looking like this:
Now you can do all sorts of queries:
Select all videos, order by descending date:
SELECT post.*, video.* FROM post JOIN video USING(post_id) WHERE post.type = 'video' ORDER BY post.date_created DESC
Select all posts with just basic details, for a single user:
SELECT post.* FROM post WHERE user_id = ?
Polymorphic query (Select all post for a single user, with specific type detail):
SELECT p.*, i.*, t.*, v.* FROM post p LEFT JOIN image i ON (p.post_id = i.post_id) LEFT JOIN text t ON (p.post_id = t.post_id) LEFT JOIN video v ON (p.post_id = v.post_id) WHERE p.user_id = ?
The downside, and an alternative
This model gives you great flexibility, but at the cost of greater query complexity and lower query performance. If your videos, text and image posts differ by a small enough number of fields you’ll get much better performance by just implementing what some call Single Table Inheritance: a single table that has all the columns for all the subtypes plus a
type
column with the same purpose as above:
The key aspect is that the type-specific columns should be nullable (since they will be null for posts which are not of that type). This model is more wasteful in space, but you can run all the same queries as above without needing the child table joins (effectively these tables are already joined by default) resulting in faster, less complex queries.
The answer with the highest score with 1 points was:
Uours’s answer to
Database design help – Splitting out tables
While you could have separate tables for each post type , I cannot think of any reason against using just one table :
posts
post_id post__type -- Ex. 1: Text ,2: Image ,3: Video . post__user_id post__datetime post__title -- Images and Videos probably could have titles as well . post__content -- This gets meaning based on post__type . Ex. This would be a URL if post__type is Image or Video . post__deleted post__likes_count
If the selected answer did not help you out, the other answers might!
All Answers For: Database design help – Splitting out tables
user1832281’s answer to
Database design help – Splitting out tables
Yes you would have a table for each type of content with a user id column on each table then when you display the data you write select statements creating joins. Then you can display by date, by user, by date, and content type.
Do some testing using a sqlite database file and test things out before you go into production.
Uours’s answer to
Database design help – Splitting out tables
While you could have separate tables for each post type , I cannot think of any reason against using just one table :
posts
post_id post__type -- Ex. 1: Text ,2: Image ,3: Video . post__user_id post__datetime post__title -- Images and Videos probably could have titles as well . post__content -- This gets meaning based on post__type . Ex. This would be a URL if post__type is Image or Video . post__deleted post__likes_count
Ezequiel Muns’s answer to
Database design help – Splitting out tables
The natural way to model what you’re doing here is by mapping an inheritance hierarchy into your relational schema.
What you want is to take all the common elements of all posts (post_id, date_created, user_id, etc.) plus a
type
field and you make that your ‘base’ table. This table represents allposts
regardless of the specific kind of post it is.Next you take all the specific attributes for each type of post and create a table for that specific type (these are the ‘children’ tables). The primary key of this table is also a foreign key into the base table (post_id).
The
type
field in the base table references which specific table a post belongs to.So it all ends up looking like this:
Now you can do all sorts of queries:
Select all videos, order by descending date:
SELECT post.*, video.* FROM post JOIN video USING(post_id) WHERE post.type = 'video' ORDER BY post.date_created DESC
Select all posts with just basic details, for a single user:
SELECT post.* FROM post WHERE user_id = ?
Polymorphic query (Select all post for a single user, with specific type detail):
SELECT p.*, i.*, t.*, v.* FROM post p LEFT JOIN image i ON (p.post_id = i.post_id) LEFT JOIN text t ON (p.post_id = t.post_id) LEFT JOIN video v ON (p.post_id = v.post_id) WHERE p.user_id = ?
The downside, and an alternative
This model gives you great flexibility, but at the cost of greater query complexity and lower query performance. If your videos, text and image posts differ by a small enough number of fields you’ll get much better performance by just implementing what some call Single Table Inheritance: a single table that has all the columns for all the subtypes plus a
type
column with the same purpose as above:
The key aspect is that the type-specific columns should be nullable (since they will be null for posts which are not of that type). This model is more wasteful in space, but you can run all the same queries as above without needing the child table joins (effectively these tables are already joined by default) resulting in faster, less complex queries.
Of course, you should really check out the original question.
The post Database design help – Splitting out tables [ANSWERED] appeared first on Tech ABC to XYZ.