SQL Conditional relationships
I've come up with two approaches to the same idea and would like to avoid any obvious pitfalls by using one over the other. I have a table (tbl_post) where a single row can have many relationships to other tables (tbl_category, tbl_site, tbl_team). I have a relationship table to join these but don't know which structure to go with, conditional or direct? Hopefully the following will explain...
tbl_post (simple post, can be associated with many categories, teams and sites)
* id
* title
* content
tbl_category
* id
* title
* other category only columns
tbl_team
* id
* title
* other team only columns
tbl_site
* id
* title
* other site only columns
----------------------------------------------------------
tbl_post_relationship
* id (pk)
* post_id (fk tbl_post)
* related_id (fk, dependant on related_type to either tbl_category, tbl_site or tbl_team)
* related_type (category, site or team)
____________________________________
|id|post_id|related_id|related_type|
|--|-------|----------|------------|
| 1| 1| 6| category|
| 2| 1| 4| site|
| 3| 1| 开发者_运维技巧 9| category|
| 4| 1| 3| team|
------------------------------------
SELECT c.*
FROM tbl_category c
JOIN tbl_relationship r ON
r.post_id = 1
AND r.related_type = 'category'
AND c.id = r.related_id
------------- OR ---------------
tbl_post_relationship
* id (pk)
* post_id (fk tbl_post)
* category_id (fk tbl_category)
* site_id (fk tbl_site)
* team_id (fk tbl_team)
________________________________________
|id|post_id|category_id|site_id|team_id|
|--|-------|-----------|-------|-------|
| 1| 1| 6| NULL| NULL|
| 2| 1| NULL| 4| NULL|
| 3| 1| 9| NULL| NULL|
| 4| 1| NULL| NULL| 3|
----------------------------------------
SELECT c.*
FROM tbl_category c
JOIN tbl_relationship r ON
r.post_id = 1
AND r.category_id = c.id
So with the one approach I'll end up with lots of columns (there might be more tables) with NULL's. Or I end up with one simple table to maintain it, but every join is based on a "type". I also know I could have a table per relationship, but again that feels like too many tables. Any ideas / thoughts?
You are best out with one table per relationship. You should not worry about the amount of tables. The drawbacks of a single relationship table are several, and quite risky:
1) You cannot enforce foreign keys if the related tables vary from row to row, so your data integrity is at risk... and sooner or later you will have orphaned data.
2) Queries are more complex because you have to use the related_type to filter out the relations in many places.
3) Query maintenance is more costly, for the same reasons of 2), and because you have to explicitly use the related_type constants in many places... it'll be hell when you need to change them or add some.
I'd suggest you use the orthodox design... just got with 3 distinct relationship tables: post_category, post_team, post_site.
精彩评论