Quiz 2

10 - Relational Algebra

1624 words
8 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# 10 - Relational Algebra ## 🎯 Learning Objectives After reading this topic, you will be able to: - Write relational algebra expressions for database queries - Use σ (select), π (project), ρ (rename), ∪ (union), − (difference), ∩ (intersection), × (Cartesian product) - Write join expressions (natural join, theta jo...

10 - Relational Algebra

🎯 Learning Objectives

After reading this topic, you will be able to:
  • Write relational algebra expressions for database queries
  • Use σ (select), π (project), ρ (rename), ∪ (union), − (difference), ∩ (intersection), × (Cartesian product)
  • Write join expressions (natural join, theta join, outer join)
  • Use the division operator (÷) for "all" queries
  • Translate between relational algebra and SQL

📋 Prerequisites

  • 03 - Relational Model — Relations, tuples, attributes, keys
  • Set theory from BSMA1001 (Maths 1) — Sets, subsets, set operations

📖 Core Content

10.1 Intuition: The Mathematical Foundation of SQL

Relational algebra is the theoretical foundation of SQL. Every SQL query can be translated to a relational algebra expression. While SQL is declarative (WHAT), relational algebra is procedural (HOW). Think of it as a recipe:
  1. Take the instructor relation
  2. Select rows where salary > 80000
  3. Project only name and dept_name In relational algebra: πname,deptname(σsalary>80000(instructor))\pi_{name, dept_name}(\sigma_{salary > 80000}(instructor))
Why This Matters: Understanding relational algebra helps you:
  • Write complex SQL queries correctly
  • Understand what the query optimizer does
  • Reason about query equivalence and optimization

10.2 The Basic Operations

Select: σ\sigma (Sigma)

Selects rows based on a condition:
σcondition(relation)\sigma_{condition}(relation) σdeptname=Comp.Sci.(instructor)\sigma_{dept_name = 'Comp. Sci.'}(instructor)
Returns all instructors in Comp. Sci.
σsalary>80000deptname=Finance(instructor)\sigma_{salary > 80000 \land dept_name = 'Finance'}(instructor)
Returns Finance instructors earning > 80000.
SymbolMeaning
σc(R)\sigma_{c}(R)Select rows from R satisfying condition c
\landAND
\lorOR
¬\lnotNOT

Project: π\pi (Pi)

Selects columns (attributes):
πname,salary(instructor)\pi_{name, salary}(instructor)
Returns only the name and salary columns.
πdeptname(instructor)\pi_{dept_name}(instructor)
Returns department names (WITHOUT duplicates — unlike SQL's default behavior).

Rename: ρ\rho (Rho)

Renames relations and/or attributes:
ρX(A1,A2,,An)(E)\rho_{X(A_1, A_2, \dots, A_n)}(E)
Returns the result of expression E with the name X and attributes renamed to A1,A2,,AnA_1, A_2, \dots, A_n.
ρemp(ID,n,d,s)(instructor)\rho_{emp(ID, n, d, s)}(instructor)
Renames instructor to emp and its columns to ID, n, d, s.

10.3 Set Operations

All set operations require union compatibility: same number of columns, same data types.

Union: \cup

rs={ttr or ts}r \cup s = \{t \mid t \in r \text{ or } t \in s\} πcourseid(teachesFall)πcourseid(teachesSpring)\pi_{course_id}(teaches_Fall) \cup \pi_{course_id}(teaches_Spring)
Courses taught in Fall OR Spring.

Difference: - (or \setminus)

rs={ttr and ts}r - s = \{t \mid t \in r \text{ and } t \notin s\} πcourseid(teachesFall)πcourseid(teachesSpring)\pi_{course_id}(teaches_Fall) - \pi_{course_id}(teaches_Spring)
Courses taught in Fall but NOT in Spring.

Intersection: \cap

rs={ttr and ts}r \cap s = \{t \mid t \in r \text{ and } t \in s\}
Can be expressed using difference: rs=r(rs)r \cap s = r - (r - s)
πcourseid(teachesFall)πcourseid(teachesSpring)\pi_{course_id}(teaches_Fall) \cap \pi_{course_id}(teaches_Spring)
Courses taught in BOTH Fall and Spring.

10.4 Cartesian Product: ×\times

Every combination of tuples from both relations:
r×s={tqtr and qs}r \times s = \{t q \mid t \in r \text{ and } q \in s\}
If instructor has 12 tuples and teaches has 15 tuples:
σinstructor.ID=teaches.ID(instructor×teaches)\sigma_{instructor.ID = teaches.ID}(instructor \times teaches)
This is equivalent to a JOIN. In practice, Cartesian product is almost always followed by a select condition.

10.5 Join Operations

Theta Join: θ\bowtie_\theta

RθS=σθ(R×S)R \bowtie_\theta S = \sigma_\theta(R \times S) instructorinstructor.ID=teaches.IDteachesinstructor \bowtie_{instructor.ID = teaches.ID} teaches

Natural Join: \bowtie

Joins on all common attributes (removes duplicate columns):
RSR \bowtie S instructorteachesinstructor \bowtie teaches
Joins on ID (the common attribute). Equivalent to:
πID,name,deptname,salary,courseid,...(σinstructor.ID=teaches.ID(instructor×teaches))\pi_{ID, name, dept_name, salary, course_id, ...}(\sigma_{instructor.ID = teaches.ID}(instructor \times teaches))

Outer Join

Preserves non-matching rows (like SQL's LEFT/RIGHT/FULL OUTER JOIN):
  • RSR ⟕ S — Left outer join
  • RSR ⟖ S — Right outer join
  • RSR ⟗ S — Full outer join

10.6 Division: ÷\div

The division operator answers "all" queries: "Find students who have taken ALL CS courses."
R÷SR \div S
Where attributes(R) ⊇ attributes(S). Result has attributes(R) - attributes(S). Intuition: For a tuple t to appear in the result, t must appear in R combined with every tuple in S. (Diagram) Example:
student_idcourse_id
1CS101
1CS201
2CS101
2CS201
3CS101
SS = {CS101, CS201} R÷SR \div S = {1, 2} — students 1 and 2 took BOTH CS101 and CS201. Student 3 only took CS101.

10.7 Equivalence Rules

Important equivalences that the optimizer uses:
  1. Cascade selection: σθ1θ2(E)=σθ1(σθ2(E))\sigma_{\theta_1 \land \theta_2}(E) = \sigma_{\theta_1}(\sigma_{\theta_2}(E))
  2. Commuting selection: σθ1(σθ2(E))=σθ2(σθ1(E))\sigma_{\theta_1}(\sigma_{\theta_2}(E)) = \sigma_{\theta_2}(\sigma_{\theta_1}(E))
  3. Cascade projection: πL1(πL2(E))=πL1(E)\pi_{L_1}(\pi_{L_2}(E)) = \pi_{L_1}(E)
  4. Selection before join: σθ(E1×E2)=E1θE2\sigma_\theta(E_1 \times E_2) = E_1 \bowtie_\theta E_2
  5. Commuting join: E1θE2=E2θE1E_1 \bowtie_\theta E_2 = E_2 \bowtie_\theta E_1
  6. Associating join: (E1E2)E3=E1(E2E3)(E_1 \bowtie E_2) \bowtie E_3 = E_1 \bowtie (E_2 \bowtie E_3)

10.8 Worked Examples

Example 1: Simple query

Find the names of all instructors in the Physics department.
πname(σdeptname=Physics(instructor))\pi_{name}(\sigma_{dept_name = 'Physics'}(instructor))

Example 2: Join query

Find the names of all instructors who teach a course.
πname(instructorteaches)\pi_{name}(instructor \bowtie teaches)

Example 3: Division

Find the IDs of students who have taken ALL courses offered in Fall 2017. Let R=πID,courseid(takes)R = \pi_{ID, course_id}(takes) Let S=πcourseid(σsemester=Fallyear=2017(teaches))S = \pi_{course_id}(\sigma_{semester='Fall' \land year=2017}(teaches)) Answer: R÷SR \div S

10.9 Relational Algebra Summary Table

OperationSymbolSQL EquivalentPurpose
Selectσ\sigmaWHEREFilter rows
Projectπ\piSELECTChoose columns
Renameρ\rhoASRename relation/attributes
Union\cupUNIONRows in either
Difference-EXCEPTRows in first but not second
Intersection\capINTERSECTRows in both
Cartesian Product×\timesCROSS JOINAll combinations
Natural Join\bowtieNATURAL JOINJoin on common attributes
Theta Joinθ\bowtie_\thetaJOIN ON conditionJoin on arbitrary condition
Division÷\divNOT EXISTS + EXCEPT"All" queries

⚠️ Common Pitfalls

Pitfall 1: Confusing σ (select) with SQL SELECT

The Mistake: Thinking σ is the same as SQL's SELECT. Why It's Wrong: σ selects rows (filtering), while SQL's SELECT picks columns. The relational algebra equivalent of SQL's SELECT is π (project).
ConceptRelational AlgebraSQL
Row filteringσ\sigmaWHERE
Column pickingπ\piSELECT
Renamingρ\rhoAS

Pitfall 2: Forgetting Set Operations Need Union Compatibility

The Mistake: Applying ∪, ∩, or - to relations with different schemas. Why It's Wrong: Set operations require the same number of attributes with compatible domains. R(A, B) ∪ S(C, D, E) is invalid. Fix: Use project to match schemas: πA,B(R)πC,D(S)\pi_{A,B}(R) \cup \pi_{C,D}(S)

Pitfall 3: Thinking Natural Join is Always Equijoin

The Mistake: Assuming natural join always joins on foreign key = primary key. Why It's Wrong: Natural join joins on ALL common attributes. If two tables accidentally share a column name (e.g., both have name), the join uses that too. Fix: Use theta join (θ\bowtie_\theta) to be explicit about join conditions.

📝 Practice Questions

Q1. Write a relational algebra expression to find the names of all instructors who earn more than 90000.

Answer
πname(σsalary>90000(instructor))\pi_{name}(\sigma_{salary > 90000}(instructor))
Step 1: σsalary>90000(instructor)\sigma_{salary > 90000}(instructor) — filter rows with salary > 90000 Step 2: πname\pi_{name} — keep only the name column

Q2. Express the following SQL query in relational algebra: SELECT name FROM instructor WHERE dept_name = 'Music';

Answer
πname(σdeptname=Music(instructor))\pi_{name}(\sigma_{dept_name = 'Music'}(instructor))

Q3. Write a relational algebra expression to find course IDs taught in Fall 2017 but not in Spring 2018.

Answer
πcourseid(σsemester=Fallyear=2017(teaches))πcourseid(σsemester=Springyear=2018(teaches))\pi_{course_id}(\sigma_{semester='Fall' \land year=2017}(teaches)) - \pi_{course_id}(\sigma_{semester='Spring' \land year=2018}(teaches))

Q4. What is the division operator? Give an intuitive explanation.

Answer
The division operator (R÷SR \div S) answers "for ALL" queries. For a tuple t to be in the result, t (combined with other attributes) must have a match with every tuple in S.
Example: "Find students who have taken ALL courses offered by the CS department." Use division:
  • R = (student_id, course_id) — all enrollment records
  • S = (course_id) — all CS courses
  • R ÷ S = students who took every CS course

Q5. Show that intersection can be expressed using difference. RS=?R \cap S = ?

Answer
RS=R(RS)R \cap S = R - (R - S)
Proof:
  1. RSR - S = tuples in R but not S
  2. R(RS)R - (R - S) = tuples in R minus those not in S = tuples in both R and S = RSR \cap S

Q6. Write a relational algebra expression to find the names of instructors and the course IDs they teach.

Answer
πname,courseid(instructorteaches)\pi_{name, course_id}(instructor \bowtie teaches)
This natural joins instructor and teaches on ID, then projects name and course_id.

Q7. What is the difference between natural join (\bowtie) and theta join (θ\bowtie_\theta)?

Answer
  • Natural join (\bowtie): Automatically joins on ALL common attribute names. Duplicate columns are removed from the result.
  • Theta join (θ\bowtie_\theta): Joins based on an explicit condition θ\theta. Can use any comparison operator (=, <, >, etc.). May have duplicate columns.
Natural join is a special case of theta join where θ\theta is equality on all common attributes.

Q8. Translate: πname(σdeptname=CS(instructorσyear=2018(teaches)))\pi_{name}(\sigma_{dept_name='CS'}(instructor \bowtie \sigma_{year=2018}(teaches))) to English.

Answer
"Find the names of all instructors in the Comp. Sci. department who taught a course in the year 2018."
Step by step:
  1. σyear=2018(teaches)\sigma_{year=2018}(teaches) — find teaching assignments from 2018
  2. instructorinstructor \bowtie (step 1) — join with instructor to get instructor details
  3. σdeptname=CS\sigma_{dept_name='CS'} — keep only Comp. Sci. instructors
  4. πname\pi_{name} — return their names

🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.