Building Relational Algebra Expressions
How to turn an English question into an algebra expression, read an expression tree, and apply the equivalence rules an optimiser uses to make the same query cheaper.
-
DBMS Fundamentals
- Data, Information and Databases
- What a DBMS Is and Why It Exists
- File System versus DBMS
- Advantages and Limitations of a DBMS
- Database Users and the Role of the DBA
- Three Level Architecture and Data Abstraction
- Logical and Physical Data Independence
- Schema, Instance and Metadata
- Database Applications and the Database System Environment
- Database Architecture
- Data Models
-
ER Model
- Entities, Entity Sets and Entity Types
- Types of Attributes in the ER Model
- Keys in the ER Model
- Relationships, Relationship Sets and Degree
- Cardinality and Participation Constraints
- Strong and Weak Entities
- Drawing and Reading ER Diagrams
- Extended ER: Generalisation, Specialisation and Aggregation
- Converting an ER Diagram into Relational Tables
- ER Design Projects
- Relational Model
- Relational Algebra
- Functional Dependencies
-
Normalisation
- Why Normalisation Exists: Anomalies and Redundancy
- First Normal Form
- Second Normal Form and Partial Dependency
- Third Normal Form and Transitive Dependency
- BCNF and BCNF Decomposition
- 4NF, 5NF, Multivalued and Join Dependencies
- Lossless Decomposition and Dependency Preservation
- Complete Worked Normalisation: Unnormalised to BCNF
- Denormalisation and When to Use It
Concept
Individual operators are only half the subject. The examinable skill is composing them into an expression that answers a question, and knowing which rewrites preserve the answer.
A method for writing an expression
- Identify the relations the question needs. Anything not needed is a cost, not a help.
- Join them on their common attributes, one at a time.
- Apply the conditions as selections.
- Project the attributes actually asked for, last.
- Then optimise: push selections down and projections down.
Write it correct first, then rewrite it cheap. Trying to do both at once is how errors get in.
Worked example
Names of Computing students who scored more than 80 in a four credit course.
STEP 1 relations needed: STUDENT, ENROL, COURSE
STEP 2 join them
( STUDENT natural join ENROL ) natural join COURSE
STEP 3 apply conditions
SELECT[dept = CS AND marks > 80 AND credits = 4]( ... )
STEP 4 project
PROJECT[name]( ... )
THE CORRECT, UNOPTIMISED EXPRESSION
PROJECT[name](
SELECT[dept = CS AND marks > 80 AND credits = 4](
( STUDENT natural join ENROL ) natural join COURSE
)
)The expression tree
PROJECT[name]
|
SELECT[dept=CS AND marks>80 AND credits=4]
|
natural join
/
natural join COURSE
/
STUDENT ENROL
Read a tree BOTTOM UP: leaves are relations, data flows
upward, the root produces the answer.
The problem with this tree: the joins run FIRST on the
full relations, and the selection throws most of it away
afterwards. Every discarded tuple was joined for nothing.Equivalence rules
These rewrites always preserve the result. They are what an optimiser is permitted to do.
| Rule | Statement |
|---|---|
| Cascade of selection | A selection with AND splits into nested selections |
| Commutativity of selection | Two selections may be applied in either order |
| Cascade of projection | Only the outermost projection matters in a chain |
| Selection with join | A selection on attributes of one relation may move below the join, to that relation |
| Commutativity of join | R join S equals S join R |
| Associativity of join | The join order may be changed freely |
| Projection with join | A projection may move below a join if the join attributes are kept |
| Selection with set operations | A selection distributes over union, intersection and difference |
Optimising the example
Push each condition down to the relation that owns it:
dept = CS belongs to STUDENT
marks > 80 belongs to ENROL
credits = 4 belongs to COURSE
THE OPTIMISED EXPRESSION
PROJECT[name](
( ( SELECT[dept = CS](STUDENT)
natural join
SELECT[marks > 80](ENROL) )
natural join
SELECT[credits = 4](COURSE) )
)
THE OPTIMISED TREE
PROJECT[name]
|
natural join
/
natural join SELECT[credits=4]
/ |
SELECT[dept=CS] SELECT[marks>80] COURSE
| |
STUDENT ENROL
Same answer. Every join now receives far fewer tuples.Why it is faster, with numbers
Assume 4,000 students, 30,000 enrolments, 200 courses.
Say 1,500 students are CS, 3,000 enrolments exceed 80
marks, and 60 courses carry 4 credits.
UNOPTIMISED
STUDENT join ENROL joins 4,000 with 30,000
produces about 30,000 tuples
join COURSE joins 30,000 with 200
produces about 30,000 tuples
then discards almost all of them
OPTIMISED
selections first 1,500 and 3,000 and 60
first join 1,500 with 3,000 -> far smaller
second join small with 60
The answer is identical. The work is not.
This is the entire justification for the heuristic
"push selections down", and Phase 14 formalises it.More worked expressions
"Students who have not enrolled in any course"
STUDENT antijoin ENROL
or
PROJECT[roll_no](STUDENT) - PROJECT[roll_no](ENROL)
"Courses taken by every Computing student"
needs division, with the divisor being the set of
CS students:
ENROL / PROJECT[roll_no](SELECT[dept=CS](STUDENT))
-- careful: this divides ENROL(roll_no, code) by a
-- relation over roll_no, so the result is over code
"Departments having at least one student scoring above 90"
PROJECT[dept](
SELECT[marks > 90](STUDENT natural join ENROL) )
"Pairs of students in the same department"
needs RENAME, because STUDENT appears twice:
SELECT[A.dept = B.dept AND A.roll_no < B.roll_no](
RENAME[A](STUDENT) x RENAME[B](STUDENT) )
-- the < condition removes self pairs and mirror
-- duplicates in one strokeCommon mistakes
- Projecting too early. An attribute a later step needs is gone.
- Pushing a selection below a join it depends on. A condition referring to attributes of both relations cannot move below the join.
- Forgetting rename for a self join. The expression is ambiguous without it.
- Optimising before the expression is correct. Get the answer right first.
- Assuming every rewrite is valid. Only the listed equivalences are guaranteed.
Exam and interview questions
- Give a method for writing an algebra expression from an English question.
- Draw the expression tree for a three relation query and mark the data flow.
- State five equivalence rules and say which one drives the main heuristic.
- Why is pushing selections down beneficial? Justify with cardinalities.
- Which selections cannot be pushed below a join?
Practice
- Write and optimise an expression for the titles of four credit courses taken by Electronics students.
- Draw both trees for that query and mark where the tuple count drops.
- Write an expression for students enrolled in Databases but not Networks.
- Write an expression for the student with the same department as student 21, excluding student 21.
Conclusion
Compose an expression by joining, filtering, then projecting, and only then rewrite it. Expression trees make the order visible, and the equivalence rules are exactly the freedom a query optimiser has — which is why Phase 14 begins where this note ends.