🗓️ 08102025 1037
Core Principle
A junction table should represent ONE type of relationship between two entities.
The Fundamental Question: "Are the relationships independent or bound together?"
This single question drives your entire junction table design.
Design Patterns
Pattern 1: Independent Relationships
When to Use
Two entities (B and C) relate to entity A separately.
Characteristics:
- Adding B doesn't require specifying C
 - Adding C doesn't require specifying B
 - All B's work with all C's (cross product)
 
Design
-- Two separate tables
table_a_b (a_id, b_id)
table_a_c (a_id, c_id)
Example
Order has:
- Products: {P1, P2, P3}
- Shipping methods: {Standard, Express}
All products can use all shipping methods
Pattern 2: Bound Relationship
When to Use
The combination of B and C relating to A is meaningful.
Characteristics:
- "Which B for which C?" is a meaningful question
 - B and C cannot vary independently
 - Specific pairings matter
 
Design
-- One combined table
table_a_b_c (a_id, b_id, c_id)
Example
Employee assignment:
- Employee X works on Project Y in Role Z
The triple (employee, project, role) is inseparable
The Decision Test
| Question | Independent → Separate | Bound → Combined | 
|---|---|---|
| Can I add B without specifying C? | YES ✅ | NO ❌ | 
| Can I add C without specifying B? | YES ✅ | NO ❌ | 
| Does the B+C combination have unique meaning? | NO ❌ | YES ✅ | 
| Are they filters/attributes that work together? | NO ❌ | YES ✅ | 
Anti-Pattern: The Sparse Table
❌ The Sparse Table Anti-Pattern
Creating a single table where most columns are NULL is a major design smell that indicates you're mixing different relationship types.
Problem Example
CREATE TABLE relation (
    a_id,
    b_id,  -- sometimes NULL
    c_id,  -- sometimes NULL
    d_id   -- sometimes NULL
)
-- Rows look like:
(1, 10, NULL, NULL)  -- a relates to b
(1, NULL, 20, NULL)  -- a relates to c
(1, NULL, NULL, 30)  -- a relates to d
Problems
- Semantic confusion - each row represents a different type of relationship
 - Data waste - most columns are NULL
 - Broken constraints - can't enforce uniqueness properly (NULL ≠ NULL in SQL)
 - Query complexity - need 
isNotNull()checks everywhere - Maintenance nightmare - hard to understand and modify
 
✅ DO THIS INSTEAD
-- Separate tables, each with clear purpose
table_a_b (a_id, b_id)
table_a_c (a_id, c_id)
table_a_d (a_id, d_id)
Naming Conventions
Standard Pattern
{entity1}_{entity2}           ✅ BEST
{entity1}_{entity2}s          ✅ GOOD (plural)
{entity1}_{entity2}_relation  ❌ REDUNDANT
{entity1}_{entity2}_mapping   ❌ REDUNDANT
{entity1}_{entity2}_link      ❌ REDUNDANT
The table name itself implies it's a relationship - no need to say it twice.
When to Add Suffix
Only when the relationship has significant domain meaning beyond just linking:
employee_project_assignments  ✅ (implies work assignments)
book_author_contributions     ✅ (implies authorship roles)
user_course_enrollments       ✅ (implies enrollment process)
Key Database Concepts
1. Junction/Join Table
A table that implements a many-to-many relationship by storing foreign keys to both entities.
2. Ternary Relationship
A relationship involving three entities where all three must be considered together as a unit.
3. Normalization
Don't mix unrelated data. Each table should have one clear purpose.
4. NULL Handling
- NULL ≠ NULL in SQL uniqueness checks
 - Sparse tables with many NULLs indicate design problems
 - If you need NULLs in junction tables, you're probably mixing relationships
 
Decision Tree
Do B and C both relate to A?
│
├─ Can they vary independently?
│  │
│  ├─ YES → Use separate tables
│  │         table_a_b + table_a_c
│  │
│  └─ NO → Does the B+C combination matter?
│           │
│           ├─ YES → Use combined table
│           │         table_a_b_c
│           │
│           └─ NO → Re-examine requirements
│
└─ Are they different types of relationships?
   │
   └─ YES → ALWAYS use separate tables
Mental Model
Think of it like tagging
Independent (Separate Tables):
Article has:
- Tags: {tech, tutorial, beginner}
- Authors: {Alice, Bob}
All authors contributed to all tags
→ article_tags + article_authors
Bound (Combined Table):
Article has:
- Alice wrote the "tech" section
- Bob wrote the "tutorial" section
Author-section pairs are specific
→ article_author_sections (article_id, author_id, section_id)
The Golden Rule
The Golden Rule: If you find yourself creating rows with mostly NULL values, you're mixing different relationship types. Split them into separate tables.
Quick Reference Examples
✅ Independent Relationships (Separate Tables)
-- User can have multiple roles AND multiple departments independently
user_roles (user_id, role_id)
user_departments (user_id, department_id)
-- Product can have multiple categories AND multiple tags independently
product_categories (product_id, category_id)
product_tags (product_id, tag_id)
-- Course can have multiple instructors AND multiple prerequisites independently
course_instructors (course_id, instructor_id)
course_prerequisites (course_id, prerequisite_course_id)
✅ Bound Relationships (Combined Table)
-- Student enrolled in course with specific grade
student_course_enrollments (student_id, course_id, grade, enrollment_date)
-- Doctor works at hospital in specific department
doctor_hospital_departments (doctor_id, hospital_id, department_id)
-- Product sold in region at specific price
product_region_pricing (product_id, region_id, price, currency)
❌ Anti-Pattern (Sparse Table)
-- DON'T: Mixing different relationship types
user_relations (
    user_id,
    role_id,       -- sometimes NULL
    department_id, -- sometimes NULL
    team_id,       -- sometimes NULL
    project_id     -- sometimes NULL
)
Summary
| Scenario | Solution | Key Indicator | 
|---|---|---|
| Independent relationships | Separate tables | Can add/remove each independently | 
| Bound relationship | Combined table | The combination has unique meaning | 
| Multiple relationship types | ALWAYS separate | Different semantic meanings | 
| Mostly NULL columns | Split into separate tables | Design smell - fix immediately |