Database Engineering · 24 Julplan ↓

48-hour focus · paper-first preparation

Turn the prompt into the right database answer.

A source-aligned exam studybook for recognizing the question type, choosing the method, showing just enough working, and checking the result without a calculator.

WhenFri 24 Jul · 08:30
Duration90 minutes
PlaceC103 / C104
Permitted aidDictionary only
Binding rule: no calculator and no cheat sheet. The official plan allows only an English/English or English/German dictionary, with no computer encyclopaedia. Bring your student ID and recheck the room because the plan warns that dates and rooms can change.
0

What the evidence actually says

Separate known exam facts from inference so your preparation is aggressive without pretending there is evidence that is not here.

Confirmed

  • The course slide names three final-exam areas: knowledge questions, database design (ER models), and database queries (SQL and relational algebra).
  • The official plan states written exam, 90 minutes, Friday 24 July 2026 at 08:30, room C103/104.
  • Prof. Scholz confirmed on 22 July 2026 that a specific iLearn learning lab is mock-equivalent, all semester topics remain relevant, and the focus is Normalization, ERM, SQL, Relational Model, and Relational Algebra.

Not supplied

  • No past exam paper or cover page.
  • No point distribution, problem count, pass threshold, or marking rubric.
  • The email does not name the exact iLearn lab; LearningLabWrapUp.pdf is the strongest local match because it is the integrated lab under Exam Preparation.

Priorities therefore use the instructor’s dated focus, the mock-equivalent lab inference, and recurrence across homework and labs—not invented “past-exam frequency.”

Final Exam slide listing knowledge questions, ER models, SQL and relational algebra
Source snippet: 01_Introduction.pdf, p. 7. This is the direct source for the three exam areas.

The universal paper workflow

  1. Circle the deliverable. “ER model,” “candidate keys,” “normalize,” “relational algebra,” and “SQL” demand different output languages.
  2. Write the smallest useful schema. List relation names, keys, and join paths before drawing or querying.
  3. Execute mechanically. Use the recipe beside each worked solution; do not improvise notation under time pressure.
  4. Run the invariant check. Cardinalities, closure, loss of zero rows, grouping grain, and requested sorting catch most errors.
  5. Box the requested result. A marker should find the final relation, SQL statement, or conclusion immediately.
Practice timing—not an official point contractUntil the paper reveals its points, spend time in proportion to the printed points. For rehearsals in this book, use 10 minutes to scan and allocate, 70 minutes to solve, and 10 minutes to check.
!

Instructor briefing · 22 July 2026

This late evidence overrides the earlier priority order. It confirms what deserves the remaining study time; it does not remove any semester topic from scope.

Bottom line: treat learning labs and homework as the exam blueprint. Put the five named focus areas first: Normalization, ER modelling (ERM), SQL, Relational Model, and Relational Algebra.
VerdictTopic / sourceWhat to do now
FOCUS ★NormalizationDo closure, candidate-key proof, 1NF→BCNF verdict, and decomposition from Homework 06, Learning Lab 07, and Additional Exercise 2.
FOCUS ★ERMDraw entities, attributes, both cardinalities, and relationship attributes from Homework 03, Learning Labs 03–04, and Wrap-Up Task 1.
FOCUS ★Relational ModelMap 1:N, 1:1, M:N, recursive, and multivalued constructs; show PKs and FKs explicitly.
FOCUS ★Relational AlgebraSolve Learning Lab 06 on paper, including intermediate/result tuples—not expression-only answers.
FOCUS ★SQLWrite joins, aggregates, HAVING, zero-preserving counts, and anti-joins from Homework 08, Learning Lab 09, and Wrap-Up Task 5.
INAll other semester topicsRetain short knowledge recall after the five focus areas. Nothing was ruled out.
MOCK-EQUIVALENTA specific iLearn learning labUse the local Wrap-Up lab as the rehearsal unless iLearn shows a different title; the email itself does not identify it.

Tonight’s time, in order of value

  1. ERM → Relational Model. Do one complete prose-to-ER-to-relations pipeline without notes.
  2. Normalization. Compute closures and justify every normal-form verdict with the violating FD.
  3. Relational Algebra → SQL. Solve the same information request in both languages and compare the result grain.
  4. Preserve the mock. Keep the Wrap-Up lab unseen or clean enough for Thursday’s uninterrupted 90-minute attempt.
Cleaned primary source · Prof. Dr. Michael Scholz email

“You can find a specific learning lab in iLearn is comparable to a mock exam.”

“Furthermore, all the topics we were discussing about during the semester are relevant.”

“However, the focus is on topics that were included in the learning labs and homework sheets.”

“Normalization, ERM, SQL, Relational Model, Relational Algebra are hence the focus.”

Received 22 July 2026 in reply to Alex’s 21 July request for a mock exam, main examinable areas, and expected working. Wording is preserved; greeting, signature, and contact details are omitted as administrative material.

The one battle plan

Two study days remain before Friday’s exam. The order follows the instructor’s 22 July focus; “safe to skip” applies only after every must-do block.

WED
22 JUL

Focus block I · design and normalization

Must doRead the briefing, then Chapters 1–3. On blank paper: Homework 03 ERM; Learning Lab 05 ER→relations; Homework 06 or Learning Lab 07 closure, keys, all normal-form verdicts, and decomposition.
Must doRedraw the Hotel ER and mapping-pipeline visuals from memory. Write PK/FK relation lines before any DDL. Keep the Wrap-Up lab unused for Thursday’s mock-equivalent attempt.
If timeNormalize ec_order from Additional Exercise 2 and write the five-table copy order.
THU 23
+ FRI

Rehearse, repair, recall

Must doMorning: Chapters 4–5. Solve all six Learning Lab 06 relational-algebra queries with result rows, then one join, one aggregate/HAVING query, and one NOT EXISTS query from Learning Lab 09 or Homework 08.
Must doAfternoon: attempt the Chapter 7 90-minute mock-equivalent rehearsal on paper with no aids. Mark misses as recognition, schema, execution, or check; redo only the failed method.
Must doEvening: reproduce Version 2 of cheatsheet.html from memory, check it, then leave it at home. Spend 30 minutes on Chapter 6 knowledge recall because all semester topics remain relevant.
If timeReview stored procedures/functions/triggers, PostgreSQL character types, and the corrected airline queries.
Fri 07:30Twenty-minute oral recall: ER mapping rules, normal forms, SQL logical order, ACID/WAL. Stop studying by 08:00; bring dictionary and student ID, not the memory sheet.

Drill lab: from zero to the answer

Every exam question type, worked on a real exercise. Each drill: the basics in plain words → the real exercise → what to look at → exactly what to write → why it works.

Read this chapter first. The later chapters are the reference; this one is the training. Nothing here assumes you already know the vocabulary—each drill starts by building it.

How each drill is laid outFoundation — the handful of ideas you must own, in everyday language. The exercise — the actual page from the course. What to look at — how to read the prompt and decide what it wants. Write this — the short answer you would actually put on the exam sheet. Why — the full explanation, so the short answer stops being magic.

DRILL 1Draw an ER model from a written description

🔴 Exam-core Prof. Scholz explicitly named ERM as a focus on 22 July 2026; it is drilled in Homework 03, Learning Labs 03–05, and Wrap-Up Task 1.

Foundation — four shapes, that is the whole language

An ER model is a picture of what the database will store, drawn before any table exists. Chen notation uses exactly four things:

  • Rectangle = entity. A thing you will keep many of, each one separately identifiable. Hotel, Room, Guest, Employee. Rule of thumb: it will become a table.
  • Oval = attribute. A fact about one entity. Name, Birthday, Price. It will become a column. Underline the one that identifies the row (the ID) — that is the key.
  • Diamond = relationship. A fact that connects two entities. Hotel includes Room. Employee works for Department. Name it with a verb.
  • Numbers on the lines = cardinality. How many of the other side may each one have. Written 1 or N (or M) at each end.

How to read cardinality without confusing yourself. Always ask the question twice, once from each side, and write the answer at the far end:

"One company has how many departments?" → many → put N at the Department end "One department belongs to how many companies?" → one → put 1 at the Company end result: Company --1-- (consists of) --N-- Department

If both answers are “many”, it is M:N and you will later need a third table. If both are “one”, it is 1:1 and is rare. Most links are 1:N.

Homework 3 ER modelling task: company, department, employee description with specialization and boss relationship
The real exercise: HomeWork03.pdf, p. 1. Cover the rest of the page and try Task 1 on paper first.
What to look at in this prompt
  1. Underline every noun. company, department, employee, producer, retailer → these are candidate entities.
  2. Underline every “is described by / has”. Whatever follows is an attribute. “described by a company ID, a name and a legal form” → three ovals on Company, ID underlined.
  3. Circle every verb between two nouns. “consists of”, “is assigned to”, “is the boss of”, “is head of” → these become diamonds.
  4. Hunt for the counting words. “exactly one”, “one to many”, “a” — these fix the cardinalities. “An employee is assigned to exactly one department” → 1 at the Department end.
  5. Spot the “either/or”. “Companies either are producers or retailers” with different attributes each → that is specialization (an “is a” triangle/diamond), not two separate entities.
  6. Spot the self-link. “An employee can be the boss of one to many other employees” → a relationship from Employee back to itself. Do not invent a “Boss” entity.

Homework 03 Task 1 · Company / Department / Employee

matches the official solution

Write this — the exam answer

Draw it. If you also want words beside the drawing, this is all that is needed:

Entities + keys Company(CompanyID, Name, LegalForm) Department(Dep.ID, Name) Employee(EmployeeID, Name, Birthday) Producer(ProductionCapacity) Retailer(StorageCapacity) Relationships + cardinalities Company 1 --- consists of --- N Department Department 1 --- works for --- N Employee (employee in exactly one dept) Employee 1 --- is head of --- 1 Department Employee 1 --- is boss of --- N Employee (self-link) Company --- is a --- Producer / Retailer (specialization)
If the marker wants a sentence“Company and Department are 1:N because a department belongs to one company. Employee–Department is N:1 because each employee is assigned to exactly one department. ‘is boss of’ is a recursive 1:N relationship on Employee. Producer and Retailer are subtypes of Company.”

Why — the full explanation

Why Department is its own entity and not an attribute of Employee. A department has its own ID and its own name, and many employees share it. Anything with its own identifier that repeats across rows is an entity. If you made it a text attribute on Employee you would store the same department name hundreds of times — the exact problem normalization exists to prevent.

Why “is head of” is 1:1. The text says a department has “a person who is the head”. One head per department; and a person heads at most one department. Both directions answer “one”, so 1:1. This is a separate relationship from “works for” even though both connect Employee and Department — they mean different facts, so they get their own diamonds. Two entities may be joined by several relationships.

Why “is boss of” loops back to Employee. A boss is an employee. Drawing a second box called “Boss” would duplicate the same people. Instead the line leaves Employee and returns to Employee. Cardinality: one employee can boss many (N), and each employee has one boss (1). When you translate this to tables later, it becomes a boss_id column inside Employee pointing at Employee.

Why specialization rather than three entities. Producers and retailers are companies — they share CompanyID, Name, LegalForm — and only add one attribute each. Specialization says “same thing, extra detail”. Two independent entities would force you to duplicate the shared attributes. In the exam, draw the supertype on top, an “is a” connector, and the two subtypes below with only their extra attributes.

Task 2 — what changes when dates arrive. “An employee belongs to a department from some start date to an end date” means the fact now has its own properties. A fact’s properties hang off the diamond, not off either entity: StartDate and EndDate become attributes of the relationship. Do this for all three relationships the task lists. And note the consequence: once a relationship carries dates, the same employee can appear in it more than once, so it stops being a plain 1:N link and behaves like M:N over time.

Official solution ER diagram for the company, department and employee model
The official answer: SolutionHomeWork03.pdf, p. 1. Compare shape by shape with your drawing — especially the ‘is a’ subtype split and the recursive ‘is boss of’ loop.
Official solution for task 2 with start date and end date on the three relationships
Task 2 official answer: SolutionHomeWork03.pdf, p. 2. The only change is StartDate/EndDate hanging off the three diamonds.
The four mistakes that cost marks here
  • Forgetting to underline the key attribute — it is the cheapest mark on the page.
  • Writing cardinality on the wrong end. Ask the question out loud, twice.
  • Turning a repeated value (department name, room type) into a text attribute instead of its own entity.
  • Leaving a relationship unnamed. A blank diamond is not an answer; use the verb from the text.

DRILL 2Turn the ER model into tables, then into CREATE TABLE

🔴 Exam-core Prof. Scholz explicitly named the Relational Model as a focus on 22 July 2026; Wrap-Up Tasks 2–4, Learning Labs 05 and 08, and Homework 07 drill it.

Foundation — three rules cover every diagram

Turning a picture into tables is mechanical. There are only three cases, decided by the cardinality you already wrote:

  • 1:N → no new table. Put the key of the “1” side as a column inside the “N” side table. That column is the foreign key. One hotel has many rooms → Room gets a HotelID column.
  • M:N → you must create a new table. It holds the two keys together as its primary key, plus any attributes that were on the diamond. Guests book rooms, many-to-many → new table Books(RoomID, GuestID, StartDate, EndDate).
  • 1:1 → put the foreign key on either side (choose the side that is never empty).

Vocabulary you need: a primary key is the column(s) that identify a row uniquely — never repeated, never empty. A foreign key is a column holding a primary key value from another table; it is how tables are linked, and the database refuses values that do not exist over there.

Wrap-Up Tasks 2–3 · Hotel model → relations → DDL

source compared; repeat-booking key corrected

Write this — the exam answer

-- step 1: relations, keys underlined Hotel(HotelID, Name, Street, HouseNumber, ZipCode, City) Type(TypeID, Name, Description, Price) Room(RoomID, HotelID→Hotel, TypeID→Type, LivingArea) Guest(GuestID, Name, Street, HouseNumber, ZipCode, City) Booking(RoomID→Room, GuestID→Guest, StartDate, EndDate) -- step 2: the two 1:N links folded in, M:N kept as its own table

Then the DDL, one table per relation, parents before children. This version uses the short, common PostgreSQL spelling varchar and puts each one-column foreign key directly on its column:

CREATE TABLE hm_hotel (
  ho_id integer PRIMARY KEY,
  ho_name varchar(255) NOT NULL,
  ho_street varchar(255) NOT NULL,
  ho_house_number varchar(50) NOT NULL,
  ho_zip_code varchar(50) NOT NULL,
  ho_city varchar(255) NOT NULL
);

CREATE TABLE hm_type (
  ty_id integer PRIMARY KEY,
  ty_name varchar(255) NOT NULL UNIQUE,
  ty_description varchar(255),
  ty_price numeric(10,2) NOT NULL CHECK (ty_price >= 0)
);

CREATE TABLE hm_room (
  ro_id integer PRIMARY KEY,
  ro_hotel integer NOT NULL REFERENCES hm_hotel(ho_id),
  ro_type integer NOT NULL REFERENCES hm_type(ty_id),
  ro_living_area numeric(10,2) NOT NULL CHECK (ro_living_area > 0)
);

CREATE TABLE hm_guest (
  gu_id integer PRIMARY KEY,
  gu_name varchar(255) NOT NULL,
  gu_street varchar(255) NOT NULL,
  gu_house_number varchar(50) NOT NULL,
  gu_zip_code varchar(50) NOT NULL,
  gu_city varchar(255) NOT NULL
);

CREATE TABLE hm_booking (
  bo_room integer REFERENCES hm_room(ro_id),
  bo_guest integer REFERENCES hm_guest(gu_id),
  bo_start_date date,
  bo_end_date date NOT NULL,
  PRIMARY KEY (bo_room, bo_guest, bo_start_date),
  CHECK (bo_end_date > bo_start_date)
);

Why — the full explanation

Why Room swallowed two foreign keys. Both “includes” (Hotel–Room) and “is of” (Room–Type) are 1:N with Room on the N side. Rule 1 fires twice: the key of the 1 side goes into the N side. So Room gains HotelID and TypeID, and the two relationships vanish as separate tables. This is what “refine the relational model” means in Task 2 — the first draft lists Includes and IsOf as tables, and refining folds them away.

Why Booking survived as a table. A guest books many rooms and a room is booked by many guests — M:N. There is no single column you could add to either side without repeating rows. So it becomes its own table and the dates from the diamond live there. Because the prompt explicitly allows the same guest to book the same room at different dates, the occurrence key is (bo_room, bo_guest, bo_start_date).

Why this foreign-key form is easier. ro_hotel integer NOT NULL REFERENCES hm_hotel(ho_id) says the whole rule from left to right: column name → type → mandatory → referenced table/key. It creates the same foreign-key constraint as the longer table-level CONSTRAINT … FOREIGN KEY … REFERENCES … form. Use the long form only when the FK has several columns, you must give the constraint a specific name, or you need a more elaborate table-level declaration.

varchar is the short spelling. In PostgreSQL, varchar(n) and character varying(n) are synonyms. The numbers 50 and 255 are common, memorable conventions—not special presets and not normal-form rules. Here 50 is ample for compact address parts such as house number and postal code; 255 is a simple shared cap for names, streets, cities, and descriptions. If the requirements give no meaningful maximum, PostgreSQL text is also valid.

Why integer and NOT NULL. The exercise explicitly asks for integer primary keys and supplies the ID values, so plain integer PRIMARY KEY is the easiest exam answer. NOT NULL on ro_hotel encodes a modelling fact: a room cannot exist without a hotel. The three BOOKING key columns are automatically NOT NULL because they form its primary key.

Why order matters. A foreign key can only point at a table that already exists, so create Hotel and Type before Room, and Room and Guest before Booking. If the exam asks only for one table, say which tables it depends on.

Correction to the supplied answer. Its hm_books primary key is only (bo_room, bo_guest), which silently forbids the repeated-date case stated in Task 1. The exam-faithful answer is the three-column key above. Name the prompt sentence as justification; do not copy a key that contradicts it.

Paper recipe Mark the participants of every M:N event, then ask what distinguishes two occurrences involving the same participants. Put that discriminator—here StartDate—in the bridge key.

Easy inline FK: child_id integer NOT NULL REFERENCES parent(parent_id). Use table-level FOREIGN KEY mainly for composite or specially named constraints.

Repeatable event key = participant FKs + occurrence discriminator; here BOOKING(room_id,guest_id,start_date) → end_date.

Wrap-Up Tasks 1–3 · Normalize the hotel relations

full 1NF → 2NF → 3NF → BCNF proof

Write this — the exam answer

State the semantic FDs and candidate keys first. We infer dependencies from the prompt, not from accidental repetition in the twelve sample rows.

RelationCandidate keyNon-trivial functional dependency
HOTELHotelIDHotelID → Name, Street, HouseNumber, ZipCode, City
TYPETypeIDTypeID → Name, Description, Price
ROOMRoomIDRoomID → HotelID, TypeID, LivingArea
GUESTGuestIDGuestID → Name, Street, HouseNumber, ZipCode, City
BOOKINGRoomID, GuestID, StartDate(RoomID, GuestID, StartDate) → EndDate
UNF → 1NF
Remove the repeating and bundled values

The source row “Rooms = 1, 2, 3” becomes three ROOM rows linked by HotelID. Address is split into the fields shown by the ER model; BookingPeriod becomes StartDate and EndDate. Every cell is now one value from one domain.

then test the whole key
2NF ✓
No partial dependency

HOTEL, TYPE, ROOM, and GUEST have one-attribute keys, so a proper key subset does not exist. BOOKING has one non-key fact, EndDate, and it depends on the complete occurrence key—not RoomID alone, GuestID alone, or the participant pair.

then look for a non-key detour
3NF ✓
No transitive dependency

Hotel facts live only in HOTEL, type description/price only in TYPE, room facts only in ROOM, and guest facts only in GUEST. BOOKING stores no copied hotel, type, price, or guest address. Therefore no non-key attribute determines another non-key attribute.

strongest determinant test
BCNF ✓
Every listed determinant is a candidate key

Each non-trivial FD above starts at the relation’s key. Therefore all five relations are already in BCNF; normalization requires no further split.

Final verdict: the corrected relational model is in BCNF (therefore also 3NF, 2NF, and 1NF) under the stated FDs.

Why this is a proof, not a guess

Normalization can finish without decomposing again. The ER-to-relational mapping has already separated the determinants: TypeID fixes the type’s price in TYPE rather than repeating Price in ROOM or BOOKING, and HotelID fixes hotel facts in HOTEL rather than copying the address into every room.

Do not invent ZipCode → City. Postal codes are not globally unique without a country/context, and the prompt never declares that dependency. Likewise the sample happens to show one row per type name, but Name is an alternate key only if the design explicitly makes it UNIQUE. If it is declared UNIQUE, it is still a candidate key, so TYPE remains BCNF.

The booking key controls the 2NF argument. With the supplied two-column key, a second booking of the same room by the same guest cannot exist at all. With the corrected occurrence key, EndDate is a fact about that full occurrence.

What stays on paper Relation + key; semantic FDs; one sentence for 1NF, 2NF, 3NF, and BCNF; final highest-normal-form verdict. If no split is needed, say so explicitly.

Hotel proof: IDs determine their own facts; (room,guest,start)→end; scalar cells, no partial/transitive FDs, and every determinant is a key ⇒ BCNF.

Learning Lab 5 relational model exercise
More mapping practice: LearningLab05.pdf, p. 1 — translate the lecture-manager ER model into relations using the same three rules.
Homework 7 creating tables exercise
More DDL practice: HomeWork07_en.pdf, p. 1 — the same CREATE TABLE skills with different constraints.

Homework 07 · Task 1.2 · Create the invoice schema and tables

paper answer + PostgreSQL meaning

Write this — the complete paper answer

Assumption: the current PostgreSQL connection is to database lecture.

-- current database: lecture
CREATE SCHEMA invoiceschema;

CREATE TABLE invoiceschema.customer (
  cu_id integer PRIMARY KEY,
  cu_firstname varchar(255) NOT NULL,
  cu_lastname varchar(255) NOT NULL,
  cu_city varchar(255) NOT NULL
);

CREATE TABLE invoiceschema.invoice (
  in_id integer PRIMARY KEY,
  in_customer integer NOT NULL REFERENCES invoiceschema.customer(cu_id),
  in_items integer NOT NULL CHECK (in_items > 0),
  in_date date NOT NULL,
  in_amount numeric(10,2) NOT NULL CHECK (in_amount >= 0)
);

If Task 1.1 treated the full customer name as one atomic display value, replace the first-name and last-name columns with cu_name varchar(255) NOT NULL. The schema commands do not change.

What “schema” means here

PostgreSQL server └── database lecture └── schema invoiceschema ├── customer └── invoice

It is not the same as a relational schema. A relational schema is a table description such as INVOICE(IID,CID,Items,Date,Amount). A PostgreSQL schema is a named namespace inside one database, used to group and qualify objects.

How the database part works. PostgreSQL cannot create an object “in another database” from the current connection. In pgAdmin, open the Query Tool under lecture. In psql, connect with \connect lecture first; that line is a psql command, not SQL. On paper, the comment -- current database: lecture is enough unless the question explicitly asks for psql commands.

Why the table names include the schema. Writing invoiceschema.customer proves where the table goes and needs no SET search_path. The equivalent alternative is SET search_path TO invoiceschema; followed by unqualified CREATE TABLE customer ....

Correction to the supplied solution. It shows the two CREATE TABLE statements but omits both CREATE SCHEMA invoiceschema and schema qualification. Unless the search path had already been changed, that code would normally create the tables in public, not in the requested schema.

Paper recipe State the connected database; create the PostgreSQL schema; create the parent table first; create the child with an inline, schema-qualified foreign key.

PostgreSQL namespace: connect to database d → CREATE SCHEMA s; → CREATE TABLE s.parent(...); → CREATE TABLE s.child(... REFERENCES s.parent(id));

DRILL 3Functional dependencies, candidate keys, normal forms

🔴 Exam-core Prof. Scholz explicitly named Normalization as a focus on 22 July 2026; Homework 06, Learning Lab 07, Additional Exercise 2, and the Wrap-Up require it.

Foundation — one idea, then four checks

Functional dependency (FD). Written X → Y, read: “if I know X, then Y is fixed.” That is the whole definition. Test it on the data: pick two rows with the same X — if Y ever differs, it is not an FD.

StudentID → Name every row with 101 has Name = Fred ✓ it holds Name → StudentID Fred is 101 and also 106 ✗ not an FD

Candidate key. A set of columns that (a) determines every other column, and (b) cannot be made smaller. Find it by asking: what is the fewest columns I need to pin down one row?

Prime attribute = a column that is part of some candidate key. Non-prime = everything else. You need the word for the 2NF test.

Now the four checks, in order. Each one assumes the previous passed — if 1NF fails, everything below fails automatically.

  • 1NF — every cell holds a single value. A cell containing “Louvre, Eiffel Tower” breaks it.
  • 2NF — no non-prime column depends on only part of the key. Only ever a problem when the key has two or more columns. Single-column key → 2NF is automatic.
  • 3NF — no non-key column determines another non-key column (no “detour”). Country → CountryPopulation inside a City table is the classic failure.
  • BCNF — for every FD X → Y, X must be a superkey. Stricter than 3NF.

Use the same classroom workflow every time: first write the atomic 1NF relation and its key; use its partial dependencies to build 2NF; use the 2NF relations’ transitive dependencies to build 3NF; then test every resulting relation for BCNF. If a stage needs no split, copy the relations forward and write “unchanged”—do not jump silently from the source table to the final design.

How one split works: take the FD that broke the current stage, put its determinant and dependants in a new relation with the determinant as key, and retain the determinant in the remaining relation as a foreign key. Nothing is deleted; the facts get one clear home.

Notation key — how to read and write the exam syntax

These lines are relational-schema shorthand, not SQL. The arrow has two related but different readings depending on where it appears.

Dependencies and keys

  • {City, Attraction} is a set of attributes. Braces group the columns; their order is irrelevant.
  • City → Country is an FD: equal City values must have equal Country values. Read the arrow as “determines.”
  • Country⁺ is the closure of Country: everything obtainable from Country using the FDs.
  • If X⁺ contains every attribute, X is a superkey. If no proper subset of X still works, X is a candidate key.

Relation schemas

  • CITY(City, Country, …) means a relation/table named CITY with the listed attributes/columns.
  • City PK means City is the chosen primary key — one selected candidate key.
  • Country FK→COUNTRY.Country means CITY.Country is a foreign key referencing COUNTRY.Country. Here the arrow means “references.”
  • PK(CITY_ATTRACTION)={City, Attraction} means the pair is one composite primary key; neither attribute is claimed to be a key alone.
Read this relation line CITY(City PK, Country FK→COUNTRY.Country, CityPopulation, Capital) Table CITY · key City · Country references COUNTRY · two ordinary attributes

Paper rule: use either underlining or explicit PK/FK labels, and stay consistent. When the referenced primary key is obvious, Country FK→COUNTRY is an acceptable shorter form.

Learning Lab 7 student relation with StudentID, Name, Gender, Unit and Grade
The real exercise: LearningLab07_en.pdf, p. 1. Work Task 1.1–1.3 before reading on.
What to look at in this prompt
  1. Read the prose under the table, not just the table. It tells you “StudentID is unique per student” and “names are not required to be unique”. Those two sentences decide every FD.
  2. Find the repeated rows. StudentID 101 appears three times — so StudentID alone cannot be the key. What makes those three rows different? The Unit. That is your key hint.
  3. For each column ask “what fixes this value?” Name is fixed by StudentID. Grade needs StudentID and Unit.
  4. Check cells for lists — here every cell has one value, so 1NF passes. (In Task 2 the Attractions column does not.)

Learning Lab 07 Task 1 · Student relation

matches the official solution

Write this — the exam answer

1.1 FDs {StudentID} → {Name, Gender} {StudentID, Unit} → {Grade} 1.2 Candidate key {StudentID, Unit} 1.3 Normalization Original relation verdict: 1NF YES — every cell contains one value 2NF NO — StudentID → Name, Gender is a partial dependency on key {StudentID, Unit} 3NF NO — not in 2NF BCNF NO — not in 3NF Normalize as far as possible: 1NF: STUDENT_1NF(StudentID, Unit, Name, Gender, Grade) PK = {StudentID, Unit} 2NF — split StudentID → Name, Gender: STUDENT(StudentID PK, Name, Gender) STUDENT_UNIT(StudentID FK→STUDENT, Unit, Grade) PK(STUDENT_UNIT) = {StudentID, Unit} 3NF: unchanged — no transitive dependency BCNF: unchanged — every determinant is a key Final BCNF design: STUDENT and STUDENT_UNIT.

Classroom working example · build every stage

The original answer above is already correct. The sequence below expands its decomposition into the 1NF → 2NF → 3NF → BCNF working used in class.

1NF ✓
Write the atomic starting relation
STUDENT_1NF(StudentID, Unit, Name, Gender, Grade)

Every cell is atomic. Candidate key: (StudentID, Unit).

StudentID → Name, Gender is partial — split it out ↓
2NF ✓
Build 2NF from the 1NF relation
STUDENT(StudentID, Name, Gender)STUDENT_UNIT(StudentID, Unit, Grade) · StudentID FK → STUDENT

Name and Gender now depend on the whole key of STUDENT; Grade depends on the whole composite key of STUDENT_UNIT.

No transitive dependency in either 2NF relation ↓
3NF ✓
No new split: carry the two 2NF relations forward

STUDENT and STUDENT_UNIT are already in 3NF.

Test every non-trivial FD’s left side ↓
BCNF ✓
No new split: the 3NF design is already BCNF

StudentID is a key of STUDENT; (StudentID, Unit) is a key of STUDENT_UNIT. Every determinant is therefore a superkey of its own relation.

Final BCNF design: STUDENT(StudentID, Name, Gender) and STUDENT_UNIT(StudentID, Unit, Grade).

The sentence that earns the 2NF split“In STUDENT_1NF, Name and Gender depend on StudentID, a proper subset of candidate key (StudentID, Unit); therefore split off STUDENT(StudentID, Name, Gender).”

Why — the full explanation

Why the key is the pair. One row is one grade. To point at exactly one grade you must say which student and which unit — student 101 has three grades, and “Mathematics” is taken by several students. Neither column alone is enough, and together they are enough, so {StudentID, Unit} is minimal and therefore a candidate key.

Why Name → StudentID is not an FD. Tempting, because names look identifying. But the prose warns you: Fred is 101 and Fred is also 106. Two rows share a Name and disagree on StudentID, so the dependency fails. This is exactly why the prose is printed — it is not decoration.

What “partial dependency” actually means. The key has two parts. Gender is decided by only one of them. So if student 102 takes four units, her Name and Gender are copied into four rows. That duplication is the disease; 2NF is the rule that names it. Split so each fact is stored once: identity facts in Student, performance facts in StudentUnit.

Separate the source verdict from the repaired design. The original 1NF relation is not in 2NF, so that original relation is also not in 3NF or BCNF. After the 2NF split, however, the new relations pass 3NF and BCNF. Write both facts; “not 3NF” describes the starting table, while “final design is BCNF” describes the result.

Check your decomposition is lossless. The two new tables share StudentID. Joining them back on StudentID reproduces the original rows exactly, with nothing invented and nothing lost. That shared column is the test: if the pieces had no column in common, the split would be wrong.

Paper layout Draw four labelled rows: 1NF, 2NF, 3NF, BCNF. Put the relation schemas in each row; beside every arrow write the FD that causes the next split. If there is no split, write “unchanged” and one pass reason.

NF working: write 1NF schema+key → split partial FDs for 2NF → split transitive FDs for 3NF → in each relation, every determinant must be a key for BCNF.

Learning Lab 7 CIA World Factbook city table with multi-valued attractions column
Task 2: LearningLab07_en.pdf, p. 2. This one fails at 1NF — spot why before reading the answer.

Learning Lab 07 Task 2 · City / country table

matches the official solution

Write this — the exam answer

2.1 Functional dependencies Before 1NF: {City} → {Country, CityPopulation, CountryPopulation, Capital, Attractions-list} {Country} → {CountryPopulation} After 1NF: {City} → {Country, CityPopulation, CountryPopulation, Capital} {Country} → {CountryPopulation} City does not determine Attraction. 2.2 Candidate keys Before 1NF: {City} After 1NF: {City, Attraction} {Country} is not a candidate key: Country⁺ = {Country, CountryPopulation}. 2.3 Normalization Original relation verdict: 1NF NO — Attractions holds several values in one cell 2NF NO — not in 1NF 3NF NO — not in 2NF; also City → Country → CountryPopulation BCNF NO — not in 3NF Normalize as far as possible: 1NF — one row per attraction: CITY_FACT_1NF(City, Attraction, Country, CityPopulation, CountryPopulation, Capital) PK = {City, Attraction} 2NF — split the partial dependency on City: CITY_2NF(City PK, Country, CityPopulation, CountryPopulation, Capital) CITY_ATTRACTION(City FK→CITY_2NF, Attraction) PK(CITY_ATTRACTION) = {City, Attraction} 3NF — split Country → CountryPopulation: COUNTRY(Country PK, CountryPopulation) CITY(City PK, Country FK→COUNTRY, CityPopulation, Capital) CITY_ATTRACTION(City FK→CITY, Attraction) PK(CITY_ATTRACTION) = {City, Attraction} BCNF: unchanged — every determinant is a key Final BCNF design: COUNTRY, CITY, CITY_ATTRACTION.

Classroom working example · build every stage

The original answer above is the concise solution. The sequence below shows how to arrive at those final relations one normal form at a time.

SOURCE ✗
The displayed table is not in 1NF

Attractions contains lists such as “Louvre, Eiffel Tower”. Build one row per attraction.

Explode the repeating Attractions group ↓
1NF ✓
Atomic wide relation
CITY_FACT_1NF(City, Attraction, Country, CityPopulation, CountryPopulation, Capital)

Candidate key after the explosion: (City, Attraction).

City determines all city facts — a proper-subset dependency ↓
2NF ✓
Split facts that depend on City alone
CITY_2NF(City, Country, CityPopulation, CountryPopulation, Capital)CITY_ATTRACTION(City, Attraction) · City FK → CITY_2NF

Every non-prime attribute now depends on the whole key of its relation.

Country → CountryPopulation is transitive inside CITY_2NF ↓
3NF ✓
Give the country fact its own relation
COUNTRY(Country, CountryPopulation)CITY(City, Country, CityPopulation, Capital) · Country FK → COUNTRYCITY_ATTRACTION(City, Attraction) · City FK → CITY
Test each remaining determinant ↓
BCNF ✓
No new split: the 3NF design is already BCNF

Country, City, and (City, Attraction) are keys of their respective relations, so every non-trivial determinant is a superkey.

Final BCNF design: COUNTRY, CITY, and CITY_ATTRACTION as shown above.

Why — the full explanation

The 1NF break is the visible one. “Louvre, Eiffel Tower” is two facts in one cell. You cannot search, count, or delete one attraction without string surgery. The fix is a row per attraction, which is why Attractions becomes its own table and the key of that table is the pair {City, Attraction}.

The 3NF break is the one people miss. CountryPopulation is a fact about the country, not about the city. The chain is City → Country → CountryPopulation: a non-key column determined by another non-key column. Consequence: France’s population is written three times (Paris, Lyon, Marseille), and correcting it means finding every row. Pull it into a Country table and store it once.

Why the key changes after the 1NF fix. Before the fix, one row per city, so {City} identifies it. After splitting attractions into their own rows, a city appears several times in that table, so you need City plus Attraction to pin one row. This is worth a sentence in the exam — the official answer states both keys.

Why Capital stays in City. Capital is yes/no for that city. It genuinely depends on City, not on Country, so it belongs in the City table. (You could argue Country → capital-city, but the column as written describes the city.)

Paper layout Start with the non-1NF source, then write the five-column 1NF wide relation with key (City, Attraction). Do not jump straight to three final tables: show the City-only 2NF split first, then remove CountryPopulation for 3NF, then state why no BCNF split remains.

Repeating group → one 1NF row per value and recompute key; then City-only facts → CITY, CountryPopulation → COUNTRY, pair fact → CITY_ATTRACTION.

Learning Lab 7 abstract relation ABCDEF with five functional dependencies
Task 3: LearningLab07_en.pdf, p. 3. Pure mechanics, no story — this is the format most likely to appear as a short exam item.
Foundation — finding candidate keys mechanically (the closure method)

With no story to reason about, use the algorithm. The closure of a set X, written X⁺, is everything you can reach by repeatedly applying the FDs.

Given: A→B, CD→A, BC→D, AE→F, CE→F over ABCDEF 1. Which letters never appear on the RIGHT of any arrow? C and E → they can never be derived, so EVERY key must contain C and E. 2. Start from {C,E} and close it: CE⁺ = C,E, +F (CE→F) = {C,E,F} ← missing A,B,D, so CE is not a key. 3. Add one more letter at a time and close: ACE⁺ : A,C,E +B (A→B) +F (AE→F) +D (BC→D) = ALL ✓ key BCE⁺ : B,C,E +D (BC→D) +A (CD→A) +F = ALL ✓ key CDE⁺ : C,D,E +A (CD→A) +B (A→B) +F = ALL ✓ key

Stop as soon as a set reaches all six letters, and never test a superset of something that already worked (keys must be minimal).

Learning Lab 07 Task 3 · Abstract relation ABCDEF

official verdict + verified extension

Write this — the exam answer

3.1 Candidate keys ACE, BCE, CDE (C and E are in every key: neither ever appears on the right of an arrow) 3.2 Original answer No. Not even in 2NF: F depends on AE and on CE, each only part of a candidate key — a partial dependency. Not in BCNF: for example, A→B while A is not a superkey. Supplied decomposition AB BCD AEF

Worked BCNF example · optional extension

Task 3.2 asks only for the BCNF verdict. The cards below keep that original answer intact and show one independently checked lossless BCNF attempt as extra practice.

BCNF ✗
The asked-for verdict
R(A,B,C,D,E,F)

A → B is one sufficient counterexample: A+ = AB, not all attributes.

Optional generated extension: decompose on CE → F, then A → B, then CD → A ↓
BCNF ✓
One lossless BCNF result
CEF(C,E, F)AB(A, B)ACD(A,C, D) · alternate key (C,D)CDE(C,D,E)

Every decomposition step is lossless. This extension is not required by Task 3.2.

Exam stopping point: “Not in BCNF because A → B and A is not a superkey.”

Why — the full explanation

Why start with “what never appears on the right”. If a letter is never produced by any FD, no combination of other letters can ever give it to you — so it must be handed to you in the key itself. C and E qualify, which instantly shrinks the search from 63 possible subsets to a handful. This trick alone usually finds the keys in under a minute.

Why three keys and not one. Once you have C and E, you need something that eventually yields A, B and D. Adding A works (A→B, then BC→D). Adding B works (BC→D, then CD→A). Adding D works (CD→A, then A→B). Three different minimal ways in, so three candidate keys — all equally valid.

Why it fails 2NF, not merely BCNF. Take AE→F. The candidate key containing A and E is ACE. AE is a proper part of it, and F is non-prime (F is in no key). A non-prime attribute depending on part of a key is precisely the 2NF violation. Naming the specific FD and the specific key is what earns the mark — “it is not in BCNF” alone does not.

Why the optional BCNF result is labelled carefully. The source asks only for the verdict. The generated decomposition CEF, AB, ACD, CDE is lossless and every result is in BCNF, but it does not preserve BC→D and AE→F as constraints that can be checked inside one table. BCNF can sacrifice dependency preservation; say so if you volunteer the decomposition.

Paper rule For the asked task, stop after one violating FD and a closure showing its determinant is not a superkey. Only decompose if the question asks; at each BCNF split write the violating FD and test the two resulting schemas again.

BCNF failure proof: name X→Y, show X⁺ ≠ all attributes. A lossless BCNF split can lose dependency preservation—check both properties separately.

Normalization in four lines, for the exam1NF one value per cell · 2NF nothing depends on part of the key · 3NF no non-key → non-key detour · BCNF every arrow starts at a superkey. Always answer all four in order, and say which FD breaks the rule.

DRILL 4Relational algebra

🔴 Exam-core Prof. Scholz explicitly named Relational Algebra as a focus on 22 July 2026; it is drilled in Homework 05 and Learning Lab 06.

Foundation — the core symbols, plus the extensions used by Wrap-Up 5

Relational algebra is SQL with mathematical notation. Each operator takes relations in and gives a relation out, so you can nest them. The first six operators are classical; counting, totals, outer joins, and ordering use named extended operators.

SymbolNamePlain meaningSQL equivalent
σ sigmaselectionkeep the rows that match a conditionWHERE
π piprojectionkeep the columns you list (drops duplicates)SELECT DISTINCT
joinglue two tables where a condition matchesJOIN … ON
differencein the first, not in the secondNOT IN / EXCEPT
∩ ∪intersect / unionin both / in eitherINTERSECT / UNION
γ gammagroup / aggregateone group per listed key; compute COUNT, SUM, …GROUP BY + aggregate
left outer joinkeep every left row, even without a matchLEFT JOIN
τ tausortorder the result; ↓ means descendingORDER BY … DESC

Exam-safe notation note. Classical relational algebra is unordered and has no COUNT or SUM. Therefore Wrap-Up 5.1.2 needs extended τ for its requested order, while 5.2.2 and 5.3.2 need extended γ. State “extended relational algebra” beside those answers; if the examiner permits only the classical core, write the relational part and explicitly say which requested operation is outside it.

The one habit that makes these easy: read the expression from the inside out, and build it in this order —

1. σ first cut rows down as early as possible 2. ⋈ next join only what survived, matching key = key 3. set ops ∩ ∪ − if the sentence says "and also" / "or" / "not" 4. π last finally keep only the asked-for columns πName( σStudy='Economics'( Student ) ) └ step 4 ┘ └──── step 1 ────┘

Subscripts. The condition rides under the symbol: σPlaces=2(Room). The join condition rides under the bowtie: A ⋈A.x=B.x B. When two tables both have a “Name” column, write the table in front: Student.Name.

Learning Lab 6 professor and student tables used for the relational algebra queries
The database you query: LearningLab06.pdf, p. 1 (Professor, Student). Rooms, Lectures, TakesPlace, Attends and Examines follow on pp. 2–4.
Learning Lab 6 lecture, room and takes-place tables
The rest of the schema: LearningLab06.pdf, p. 2. You need TakesPlace for the Wednesday query and the operations tree.
What to look at in an algebra prompt
  1. Which columns does it ask to show? That is your outermost π. “Find the names” → πName.
  2. Which conditions are stated? Each becomes a σ. “that study economics” → σStudy='Economics'.
  3. Do the columns you need live in more than one table? If yes you need a join, and the join column is the shared key (Student# with Student#, Lecture# with Lecture#).
  4. Listen for the set-op words.and the course …” meaning both → ∩. “do not” → −.
  5. Passed vs failed. German grades: 1.0 best, 4.0 still a pass, 5.0 fail. “passed” → Grade ≤ 4.0; “failed” → Grade > 4.0.

Learning Lab 06 · The six queries

matches the official solution

Write this — the exam answer

1.1 names of students studying economics πName( σStudy='Economics'(Student) ) 1.2 professors in a room with two places πProfessor.Name( Professor ⋈Professor.Room#=Room.Room# σPlaces=2(Room) ) 1.3 courses taking place on Wednesday πLecture.Title( Lecture ⋈Lecture.Lecture#=TakesPlace.Lecture# σWeekday='Wednesday'(TakesPlace) ) 1.4 students who passed BOTH 'Operations Research' AND 'Information Systems' πStudent.Name( Student ⋈ σGrade<=4.0(Examines) ⋈ σTitle='Operations Research'(Lecture) ) πStudent.Name( Student ⋈ σGrade<=4.0(Examines) ⋈ σTitle='Information Systems'(Lecture) ) 1.5 students that do not attend any course πStudent.Name( Student ⋈ ( πStudent#(Student) πStudent#(Attends) ) ) 1.6 students who failed in WT2023, with the course name πStudent.Name, Lecture.Title( Lecture ⋈ Student ⋈ σSemester='WT2023' ∧ Grade>4.0(Examines) )
Operations tree question (Task 2)Read a tree bottom-up. σName=Konstantin Pfeiffer on Professor → πProfessor# gives 004 → join into TakesPlace → πWeekday,Timeslot. Answer: (Thursday, 10-12) and (Wednesday, 14-16) — the two slots professor 004 teaches.

Why — the full explanation

1.1 needs no join because Study and Name are both inside Student. Whenever every column mentioned lives in one table, the answer is just π(σ(table)) — do not add joins for decoration.

1.2 and 1.3 are the standard shape. The filter applies to one table, then you join to reach the column you must display. Note the σ sits inside the join: filter Room down to the 2-place rooms first, then join. Filtering before joining is both cheaper and easier to write.

Why 1.4 needs ∩ and not a single σ with “and”. The condition is about two different rows of Examines — one exam for Operations Research, another for Information Systems. A single row can never satisfy Title='OR' ∧ Title='IS'; that would return nothing. So compute the set of students who passed the first course, compute the set who passed the second, and intersect. This is the standard trick whenever a prompt says “both X and Y” about repeated facts.

Why 1.5 uses difference and then joins back. “Students that do not attend courses” is an absence, and algebra expresses absence with −. Take all Student# and subtract the Student# that appear in Attends; what remains are the non-attenders — but only their IDs. The prompt asks for names, so join that set back to Student to pick up the Name column. Forgetting the join back is the most common error here.

Why 1.6 puts both conditions in one σ. Semester and Grade describe the same exam row, so a single selection with ∧ works. Then two joins bring in the student’s name and the lecture’s title, and the final π shows both columns as asked.

Reading trees in general. Leaves are tables; you evaluate upward; each node consumes what is below it. If asked for “the resulting relation”, give the actual rows, not a description — check them against the printed data.

DRILL 5Write the SQL query

🔴 Exam-core Prof. Scholz explicitly named SQL as a focus on 22 July 2026; Homework 08, Learning Lab 09, Wrap-Up 5, and Additional 4 are query sets.

Foundation — write the clauses in this order, every time

A SELECT has at most six clauses and they must appear in this order. You can memorise the skeleton and fill the blanks:

SELECT which columns to show (and aggregates: COUNT, SUM, AVG) FROM the first table JOIN … ON key = key (repeat for each extra table) WHERE filter individual ROWS (no aggregates allowed here) GROUP BY one row per what? HAVING filter the GROUPS (aggregates allowed here) ORDER BY … ASC | DESC

The single most useful idea: “what is one row of my answer?” Decide that first, and everything follows.

  • One row per hotel with a count → GROUP BY hotel.
  • One row per room → no GROUP BY at all.
  • A single number → an aggregate with no GROUP BY.

WHERE vs HAVING — the distinction the exam loves. WHERE runs before grouping and cannot see SUM/COUNT. HAVING runs after grouping and exists precisely to filter on them. “customers who spent more than 5000 in total” is a HAVING; “orders after 2024-01-01” is a WHERE.

Joining: put the tables in a chain along the foreign keys. To get from Guest to Hotel in the hotel database you must pass through Books and Room — you cannot jump, because no column links them directly.

Small tools: DISTINCT removes duplicate rows (“listed only once”). LIKE 'A%' = starts with A; LIKE '%burg' = ends with burg. COUNT(*) counts rows; SUM(a*b) multiplies then totals.

Learning Lab 9 SQL query exercise sheet
More query practice: LearningLab09_en.pdf, p. 1. Same shapes as the Wrap-Up set below.
Wrap-Up Exercise 5 with all six hotel query prompts
The exact exercise worked below: LearningLabWrapUp.pdf, p. 3. Each subpart is answered first in relational algebra, then in SQL.
What to look at in a query prompt
  1. “Select the …” tells you the SELECT list. “the name and the number of visits” → two output columns, one of them a COUNT.
  2. “per / for each” means GROUP BY. “number of bookings per hotel” → group by hotel.
  3. “only once” means DISTINCT.
  4. “more than / below” after a total means HAVING. Before a total it means WHERE.
  5. “sorted / order by … descending” means ORDER BY … DESC. Easy mark; do not drop it.
  6. List the tables you must touch and chain them by foreign key before writing a single word of SQL.
The translation ladder used six timesAsked columns become π / SELECT. Row conditions become σ / WHERE. Links become ⋈ / JOIN ON. “Per” and totals become γ / GROUP BY. A condition on a total becomes σ after γ / HAVING. Requested order becomes extended τ / ORDER BY.

Wrap-Up Exercise 5 · Relational algebra → SQL for every subpart

six paired, corrected, output-checked answers

Write this — the exam answers

5.1.1 · Room IDs with price below €300

One output row represents one qualifying room. Path: ROOM → TYPE; filter TYPE.Price, then show ROOM.RoomID.

Relational algebra
πRoom.RoomID( Room ⋈Room.TypeID=Type.TypeID σType.Price<300(Type) )
SQL
SELECT r.ro_id FROM hm_room AS r JOIN hm_type AS t ON t.ty_id = r.ro_type WHERE t.ty_price < 300 ORDER BY r.ro_id;

Checked result: 1, 3, 4, 5, 6, 8, 9, 10.

5.1.2 · Room ID and type, area 20–50, ID descending

One row per room. “Between” is inclusive; classical RA has no order, so τ is an explicit extension.

Extended relational algebra
τRoom.RoomID ↓( πRoom.RoomID,Type.Name( σ20≤Room.LivingArea ∧ Room.LivingArea≤50(Room) ⋈Room.TypeID=Type.TypeID Type ) )
SQL
SELECT r.ro_id, t.ty_name FROM hm_room AS r JOIN hm_type AS t ON t.ty_id = r.ro_type WHERE r.ro_living_area BETWEEN 20 AND 50 ORDER BY r.ro_id DESC;

Checked result: IDs 10, 9, 8, 6, 5, 4, 3, 1, with their type names. The supplied solution’s strict >20 AND <50 is corrected to inclusive BETWEEN.

5.2.1 · Hotels offering a King Size Apartment, once each

One row per hotel name. Path: HOTEL → ROOM → TYPE; filter the type. π removes duplicates under relational set semantics; SQL needs DISTINCT.

Relational algebra
πHotel.Name( Hotel ⋈Hotel.HotelID=Room.HotelID Room ⋈Room.TypeID=Type.TypeID σType.Name='King Size Apartment'(Type) )
SQL
SELECT DISTINCT h.ho_name FROM hm_hotel AS h JOIN hm_room AS r ON r.ro_hotel = h.ho_id JOIN hm_type AS t ON t.ty_id = r.ro_type WHERE t.ty_name = 'King Size Apartment';

Checked result: Beach Hotel.

5.2.2 · Every hotel and its number of bookings

One row per hotel—including a hotel with zero bookings. COUNT/outer join require extended RA. Count a non-null booking key, not the null-extended row.

Extended relational algebra
γHotel.HotelID,Hotel.Name; COUNT(Booking.RoomID)→Visits( (Hotel ⟕Hotel.HotelID=Room.HotelID Room) ⟕Room.RoomID=Booking.RoomID Booking )
SQL
SELECT h.ho_name, COUNT(b.bo_room) AS visits FROM hm_hotel AS h LEFT JOIN hm_room AS r ON r.ro_hotel = h.ho_id LEFT JOIN hm_booking AS b ON b.bo_room = r.ro_id GROUP BY h.ho_id, h.ho_name ORDER BY h.ho_id;

Checked result: Grand Hotel 6; Beach Hotel 3; Bates Motel 3. The supplied inner joins are corrected because “all hotels” must preserve a zero-booking hotel.

5.3.1 · Guests who ever booked the Grand Hotel, once each

One output row per guest name. The only connection is the four-relation path GUEST → BOOKING → ROOM → HOTEL.

Relational algebra
πGuest.Name( Guest ⋈Guest.GuestID=Booking.GuestID Booking ⋈Booking.RoomID=Room.RoomID Room ⋈Room.HotelID=Hotel.HotelID σHotel.Name='Grand Hotel'(Hotel) )
SQL
SELECT DISTINCT g.gu_name FROM hm_guest AS g JOIN hm_booking AS b ON b.bo_guest = g.gu_id JOIN hm_room AS r ON r.ro_id = b.bo_room JOIN hm_hotel AS h ON h.ho_id = r.ro_hotel WHERE h.ho_name = 'Grand Hotel';

Checked result: Susanne Brandt, Paul Brunel, Mika Aikonen, Illes Mihaly, Dominica Valderama.

5.3.2 · Guests spending more than €800, with total spent

First compute one BookingCost per booking; then group per guest, sum, and filter the groups. PostgreSQL date subtraction yields the number of charged nights used by the supplied solution.

Extended relational algebra
Cost := πGuest.GuestID,Guest.Name, (Booking.EndDate−Booking.StartDate)×Type.Price→BookingCost( Guest ⋈Guest.GuestID=Booking.GuestID Booking ⋈Booking.RoomID=Room.RoomID Room ⋈Room.TypeID=Type.TypeID Type ) πGuest.Name,Spent( σSpent>800( γGuest.GuestID,Guest.Name; SUM(BookingCost)→Spent(Cost) ))
SQL
SELECT g.gu_name, SUM((b.bo_end_date - b.bo_start_date) * t.ty_price) AS spent FROM hm_guest AS g JOIN hm_booking AS b ON b.bo_guest = g.gu_id JOIN hm_room AS r ON r.ro_id = b.bo_room JOIN hm_type AS t ON t.ty_id = r.ro_type GROUP BY g.gu_id, g.gu_name HAVING SUM((b.bo_end_date - b.bo_start_date) * t.ty_price) > 800;

Checked result: Rubie Kub €3,380; Paul Brunel €1,170; Mika Aikonen €1,600; Antonia Valetta €4,270; Illes Mihaly €1,040; Dominica Valderama €1,920.

Why each translation works

5.1.1 and 5.1.2 are filter–join–project. Price belongs to TYPE, while LivingArea belongs to ROOM. Push each σ/WHERE to the relation that owns the filtered attribute, join through TypeID, then project/select exactly the requested columns. Sorting is presentation and comes last.

5.2.1 exposes the set-versus-bag difference. Relational algebra relations are sets, so π produces each hotel name once. SQL keeps duplicate result rows unless DISTINCT is requested.

5.2.2 combines two separate requirements. “Per hotel” triggers γ/GROUP BY; “all hotels” triggers ⟕/LEFT JOIN. With an outer join, COUNT(*) would count the preserved null row as one, so count the nullable right-side booking key.

5.3.1 is a path-finding question. Guest and Hotel have no direct common key. Every algebra bowtie and SQL JOIN corresponds to one FK→PK edge in the relational model; skipping BOOKING or ROOM creates a meaningless product.

5.3.2 has two grains. Before grouping, one row is one booking and the computed value is nights × nightly price. After γ/GROUP BY, one row is one guest and Spent is the sum. Because “more than €800” applies to that total, the algebra σ sits outside γ and SQL uses HAVING, not WHERE.

Paper recipe for any query Write the output grain; underline requested columns; circle row filters; draw the FK path; write σ/WHERE and ⋈/JOIN; add γ/GROUP BY only for “per/total”; put group thresholds outside γ/in HAVING; finish with π/SELECT and τ/ORDER BY.

RA ↔ SQL: σ=WHERE, π=SELECT DISTINCT, ⋈=JOIN, ⟕=LEFT JOIN, γ=GROUP BY/aggregate, σ after γ=HAVING, τ=ORDER BY.

Marks people throw away on SQL
  • Forgetting ORDER BY … DESC when the prompt says “descending”.
  • Putting an aggregate in WHERE. It must be HAVING.
  • Missing DISTINCT after “only once in the result set”.
  • Joining two tables that share no key — trace the chain instead.
  • Ending without a semicolon, or renaming a computed column without AS when the prompt asks to “show the amount”.

DRILL 6Knowledge questions — definitions you may be asked to state

🔴 Exam-core The final-exam slide lists “knowledge questions” as its own area; the architecture homework and lab are entirely of this type.

Foundation — the shape of a full-mark definition

A one-word answer rarely scores. Use the same four-beat structure every time, and keep it to three or four lines:

1. What it is one sentence, category first 2. How it works the mechanism in one sentence 3. Why it matters the problem it solves 4. Example one concrete instance from the course
Architecture of RDBMS homework questions
Typical knowledge-question source: HomeWork02_en.pdf, p. 1.

Answer bank · the definitions most likely to be asked

written to the four-beat shape

Write this — model answers

Primary key Column(s) that identify each row uniquely. Never NULL, never repeated. Enforced by the DBMS. Example: ho_id in hm_hotel. Foreign key Column holding a primary-key value of another table; it links the two. The DBMS rejects values that do not exist there (referential integrity). Example: ro_hotel → hm_hotel(ho_id). Functional dependency X → Y If two rows agree on X they must agree on Y — knowing X fixes Y. Used to find keys and to decide normal forms. Example: StudentID → Name. Normalization Splitting tables so each fact is stored once, guided by FDs. Removes update/insert/delete anomalies and redundancy. Cost: more joins when querying. 3NF In 2NF and no non-key attribute depends on another non-key attribute. Example violation: City → Country → CountryPopulation. Transaction / ACID A unit of work that must happen completely or not at all. Atomicity all-or-nothing · Consistency rules still hold · Isolation concurrent transactions do not corrupt each other · Durability committed data survives a crash. Three-level architecture (ANSI/SPARC) External = per-user views · Conceptual = the logical schema · Internal = physical storage. Separating them gives data independence: storage can change without breaking programs. DDL vs DML DDL defines structure: CREATE, ALTER, DROP. DML changes/reads data: INSERT, UPDATE, DELETE, SELECT. View A stored query used like a table. Simplifies access and can hide columns. Not stored data — computed on use. Index Extra structure making lookups fast. Speeds reads, slows writes, uses space. Trigger Procedure the DBMS runs automatically on INSERT/UPDATE/DELETE. Used for auditing or enforcing rules code cannot bypass.

Why — how to handle a definition you did not revise

Fall back on the four beats. Even without the textbook phrasing, “it is a kind of X, it works by Y, it solves Z, for example W” reads as understanding. Markers reward the mechanism and the consequence more than the exact wording.

Prefer a course example over a generic one. Naming hm_room.ro_hotel shows you can apply the idea to the material you were taught; naming “a table in some database” does not.

If asked to compare, give the trade-off. Normalization vs redundancy, index read-speed vs write-cost, view convenience vs recomputation. A comparison question wants both directions, not a list of virtues.

Watch the language. The exam is English and you may bring a dictionary — use it for the prompt wording rather than guessing what a term means. A misread verb (“list” vs “count”) changes the whole answer.

Now do thisCover the “Write this” blocks and redo each drill on paper — Drill 1 (ER), Drill 3 Task 1 (normalization), Drill 4 queries 1.4 and 1.5, and Drill 5 queries 5.2.2 and 5.3.2. Those five are the ones that transfer to the largest share of exam marks. Then use chapters 1–6 below for anything that still felt shaky.
1

ER modelling: turn prose into constraints

Draw what the requirements permit and forbid—not merely a picture of nouns.

🔴 Exam-core Prof. Scholz explicitly named ERM as a focus on 22 July 2026; the final-exam slide, Homework 03, Learning Labs 03–05, and Wrap-Up Task 1 corroborate it.

An ER answer earns its value from four decisions: entity boundaries, identifiers, relationship meaning, and cardinalities. Attributes are the easy part.

Entity

A thing with its own identity and several occurrences: Hotel, Room, Guest. Underline or otherwise mark the key attribute.

Relationship

A fact connecting occurrences: Hotel includes Room; Guest books Room. Dates belong to BOOKS because they describe that fact.

Cardinality

Ask in both directions: “one hotel includes how many rooms?” and “one room belongs to how many hotels?” Write both ends.

Recognition rules

WordingModel moveCheck
“each X has exactly one Y”X participates in an N:1 relationship to Y; X side is mandatory.Can an X exist with zero Y? No.
“zero or many”Optional many participation.Include 0 in the minimum if min/max notation is used.
“for each order/booking…”Attribute of the relationship, or an associative entity when the occurrence needs identity.Would the value change for a different pairing/event?
“types will grow”VehicleType is data in an entity, not five hard-coded subtypes.Adding a type requires INSERT, not schema change.
“either producer or retailer”Specialization. Mark disjointness; mark total only when every supertype occurrence must be one subtype.Can one company be both? Can it be neither?
Wrap-up page with hotel ER, relational model and DDL tasks
Real exercise: LearningLabWrapUp.pdf, p. 1. Attempt the English Task 1 on paper before reading the worked answer.

Wrap-Up 1 · Hotel ER model

independently checked answer

Exam answer

Given nouns & verbs
ER conventions
Cardinality decisions
Final model
Chen-style ER diagram for hotel booking database HOTEL INCLUDES ROOM IS OF TYPE GUEST BOOKS 1NN1MN hotel_id name room_id living_area type_id price guest_id start_date end_date address = (street, house_no, zip_code, city)name + composite address
Expected hand-drawn answer. Attribute ellipses are abbreviated to keep the relationship structure readable; list all attributes beside the diagram if space is tight.

HOTEL 1:N ROOM; ROOM N:1 TYPE; GUEST M:N ROOM through BOOKS(start_date, end_date). HOTEL and GUEST each have a composite address. Keys: hotel_id, room_id, type_id, guest_id.

Why each move is there

  • Room belongs to one hotel: the wording “hotels consist of rooms” and globally stated room ID support HOTEL 1:N ROOM.
  • Type is an entity: description and price depend on a reusable type, not on an individual room.
  • BOOKS is M:N: a guest may book several rooms over time and a room is booked by several guests over time.
  • Dates are relationship attributes: they vary per guest–room booking. They later participate in the booking key.
Fast hand-draw recipe
Rectangles and underlined IDs first → three verb diamonds → cardinalities in both directions → relationship dates → remaining attributes. Write the relational key warning room_id + guest_id + start_date in the margin.

M:N event → bridge(FK₁, FK₂, event discriminator, event attributes); include the discriminator in the key when repeats are allowed.

Two high-yield variants

History turns a simple link into an event

Homework 03 adds start/end dates to WORKS_FOR, HEADS, and BOSSES. Each becomes a history relation in the relational model. A useful key is normally the participants plus start_date; add CHECK (end_date IS NULL OR end_date > start_date).

Extensible type lists are data

Learning Lab 03 says CARESE will offer more vehicle types without changing the ER model. Therefore VEHICLE_TYPE is an entity; VEHICLE–TYPE is M:N, and RESERVATION links Customer, VehicleType, and Location with pickup/return dates.

Drill · Insurance model (Learning Lab 03.1)

generated solution

Exam answer

CUSTOMER 1:N CAR; CAR 1:N ACCIDENT (0 allowed on Accident side); POLICY M:N CAR; POLICY 1:N PREMIUM_PAYMENT. PAYMENT has period_start, period_end, due_date, received_date. Use IDs for all entities and VIN as a candidate key for CAR.

Breakdown

“Associated with” does not make Accident an attribute: accidents repeat and have their own facts. A payment is not a multivalued amount; it has dates and therefore deserves an entity. The prompt says customers own one or more cars, so Customer participation in OWNS is total.

Paper check Can one policy cover multiple cars? yes. Can one car be on several historical policies? the wording permits it, so M:N is safest unless a time rule says otherwise.

A repeating fact with its own dates/amounts is an entity or relationship occurrence, never a comma-separated attribute.

2

From ER model to relations and PostgreSQL

The model is not finished until every relationship has a home, every table has a key, and the constraints express the prompt.

🔴 Exam-core Prof. Scholz explicitly named the Relational Model as a focus on 22 July 2026; Wrap-Up Tasks 2–4 and Learning Labs 05 and 08 use the mapping pipeline.

Pipeline from requirements to checked DDL 1ER factsentities · IDsrelationshipscardinalities 2RelationsPK underlinedFK annotatedbridge keys 3Refinemerge 1:Nchoose domainstest normal forms 4DDLPK · FKNOT NULLCHECK · UNIQUE At every arrow ask: “What fact could this structure wrongly permit or forbid?”
Use this left-to-right order on paper. Do not jump directly from prose to SQL: the relational line catches missing keys before syntax hides the design error.

The mapping rules you must be able to reproduce

ER structureRelational mappingTypical key
Strong entityOne table containing atomic attributes.Entity identifier.
Composite attributeStore its components, not the parent label.Unchanged.
1:N relationshipMove the 1-side key into the N-side table as FK. Put relationship attributes there if each N occurrence has at most one relationship occurrence.N-side PK.
1:1 relationshipPlace FK on the mandatory side; add UNIQUE. Separate table if both optional or the relationship has a life of its own.FK is UNIQUE.
M:N relationshipCreate bridge with both FKs and relationship attributes.Both FKs, plus any event discriminator needed for repeats.
SubtypeSupertype table plus subtype table whose PK is also FK to supertype.Inherited supertype ID.
Recursive 1:NNullable self-FK on the child/subordinate row.Entity PK; self-FK is not the key.

Wrap-Up 2 · Correct relational model

exam-ready relation lines

Exam answer

HOTEL(hotel_id, name, street, house_no, zip_code, city) ROOM_TYPE(type_id, name, description, price) ROOM(room_id, hotel_id FK→HOTEL, type_id FK→ROOM_TYPE, living_area) GUEST(guest_id, name, street, house_no, zip_code, city) BOOKING(room_id FK→ROOM, guest_id FK→GUEST, start_date, end_date)

Primary key of BOOKING = (room_id, guest_id, start_date).

Breakdown

INCLUDES and IS_OF are 1:N, so their foreign keys move into ROOM. BOOKS remains a table because it is M:N and has dates. ZIP codes and house numbers are character data: leading zeroes and letters such as “15b” are meaningful.

Verified correction to the supplied solutionThe supplied primary key (bo_room, bo_guest) contradicts the prompt’s explicit requirement that one guest may book the same room at different dates. Adding bo_start_date distinguishes those occurrences. The refined supplied model also labels ZIP as integer although its own SQL correctly uses character data.
Paper recipe Write all entity relations → cross out 1:N relationship tables after moving their FK/attributes → keep M:N bridges → underline the smallest determinant that uniquely names each row → annotate every FK target.

1:N → FK on N; M:N → bridge; 1:1 → FK on mandatory side + UNIQUE; subtype PK is also FK.

Wrap-up data for hotel, rooms, guests and booking periods
Real exercise data: LearningLabWrapUp.pdf, p. 2. The source is deliberately not in 1NF; the inserts below place each fact into its normalized table.

Wrap-Up 3–4 · Complete DDL and population

PostgreSQL · corrected and complete

Exam answer

CREATE TABLE hm_hotel (
  ho_id integer PRIMARY KEY,
  ho_name varchar(255) NOT NULL,
  ho_street varchar(255) NOT NULL,
  ho_house_number varchar(50) NOT NULL,
  ho_zip_code varchar(50) NOT NULL,
  ho_city varchar(255) NOT NULL
);

CREATE TABLE hm_type (
  ty_id integer PRIMARY KEY,
  ty_name varchar(255) NOT NULL UNIQUE,
  ty_description varchar(255),
  ty_price numeric(10,2) NOT NULL CHECK (ty_price >= 0)
);

CREATE TABLE hm_room (
  ro_id integer PRIMARY KEY,
  ro_hotel integer NOT NULL REFERENCES hm_hotel(ho_id),
  ro_type integer NOT NULL REFERENCES hm_type(ty_id),
  ro_living_area numeric(10,2) NOT NULL CHECK (ro_living_area > 0)
);

CREATE TABLE hm_guest (
  gu_id integer PRIMARY KEY,
  gu_name varchar(255) NOT NULL,
  gu_street varchar(255) NOT NULL,
  gu_house_number varchar(50) NOT NULL,
  gu_zip_code varchar(50) NOT NULL,
  gu_city varchar(255) NOT NULL
);

CREATE TABLE hm_booking (
  bo_room integer REFERENCES hm_room(ro_id),
  bo_guest integer REFERENCES hm_guest(gu_id),
  bo_start_date date NOT NULL,
  bo_end_date date NOT NULL,
  PRIMARY KEY (bo_room, bo_guest, bo_start_date),
  CHECK (bo_end_date > bo_start_date)
);
The memorable column patternro_hotel integer NOT NULL REFERENCES hm_hotel(ho_id). Read it left to right: column → type → required → referenced parent. This inline form is equivalent to a separate one-column FOREIGN KEY clause. The 50/255 varchar sizes are consistent conventions for this exercise, not PostgreSQL presets.
INSERT INTO hm_hotel VALUES
(1,'Grand Hotel','Am Hauptplatz','1','84567','Pleinting'),
(2,'Beach Hotel','Strandvej','15b','1234','Copenhagen'),
(3,'Bates Motel','Park Avenue','59','01624','Fairvale');

INSERT INTO hm_type VALUES
(1,'Single Apartment','Nice apartment with bathroom and bed',130),
(2,'King Size Apartment','Nice apartment with king size bed and bathroom',260),
(3,'Mini Suite','Luxury apartment with king size bed, living room and bathroom',320),
(4,'Presidential Suite','Luxury apartment with king size bed, living room, bathroom and sauna',610);

INSERT INTO hm_room VALUES
(1,1,1,28),(2,1,3,64),(3,1,1,32),(4,2,2,44),(5,2,1,31),
(6,2,2,44),(7,2,4,110),(8,3,1,34),(9,3,1,32),(10,3,1,36);

INSERT INTO hm_guest VALUES
(1,'Susanne Brandt','Saskia-Geyer-Gasse','25','53672','Stuhr'),
(2,'Lorin Lee','Daniel-Geiger-Weg','3','82827','Biberach'),
(3,'Rubie Kub','Magdalena-Bühler-Allee','1','70119','Esslingen'),
(4,'Paul Brunel','Kieferweg','6','06145','Aschersleben'),
(5,'Mika Aikonen','Förstergasse','3','88888','Hinterwinkl'),
(6,'Antonia Valetta','Am Kai','12','28793','Radelshaven'),
(7,'Illes Mihaly','Oswald-Römer-Strasse','85','48732','Alfhausen'),
(8,'Renuga Sangalimuthu','Innerer Ring','119','10274','Berlin'),
(9,'John Smith','Am Rande','15','87934','Bofenhausen'),
(10,'Dominica Valderama','Falkenweg','9','58691','Mainburg');

INSERT INTO hm_booking VALUES
(3,1,'2024-06-03','2024-06-05'),(9,2,'2024-06-04','2024-06-09'),
(6,3,'2024-06-08','2024-06-21'),(2,1,'2024-06-09','2024-06-10'),
(4,4,'2024-06-09','2024-06-12'),(2,5,'2024-06-10','2024-06-15'),
(7,6,'2024-06-11','2024-06-18'),(3,7,'2024-06-11','2024-06-19'),
(8,8,'2024-06-13','2024-06-17'),(1,4,'2024-06-14','2024-06-17'),
(10,9,'2024-06-15','2024-06-20'),(2,10,'2024-06-15','2024-06-21');

Where the marks live

  • Structure: create referenced tables before tables that contain FKs.
  • Integrity: mandatory facts are NOT NULL; prices/areas/date order use CHECK.
  • Domains: use exact numeric for money and text-like types for ZIP/house number.
  • Population: one row per entity or event; the comma-separated source cells disappear.
No-calculator procedure For DDL, draw a five-row dependency order (Hotel, Type, Guest → Room → Booking), then write CREATE statements in that order. On paper, full constraint names are optional unless asked; correct columns and targets are not.

DDL audit: PK every table; FK target exists; mandatory→NOT NULL; domain→CHECK; exact money→numeric; identifiers such as ZIP/card/phone→text.

Constraint patterns worth recognizing

Change a schema

ALTER TABLE aircraft
  RENAME COLUMN range TO max_distance;

ALTER TABLE flight
  ALTER COLUMN status SET DEFAULT 'On Time';

ALTER TABLE airport
  ADD CHECK (airport_code ~ '^[A-Za-z]');

The regular expression tests the first character. The supplied range comparison >= 'aaa' AND <= 'ZZZ' is collation-dependent and reverses lexical case ranges in many collations.

Foreign-key actions

ON DELETE CASCADE removes dependent facts; SET NULL preserves the row but removes the link; RESTRICT/NO ACTION prevents the delete while references remain.

Never choose an action from habit: state the business effect. Message history, for example, may need a soft-deleted user rather than cascading all messages.

3

Normalization: make every fact live once

Use functional dependencies to prove the design; do not normalize by aesthetic instinct.

🔴 Exam-core Prof. Scholz explicitly named Normalization as a focus on 22 July 2026; it recurs in Homework 06–07, Learning Lab 07, the Wrap-Up, and Additional Exercises.

Functional dependencies and closure

A functional dependency X → Y means: whenever two valid rows agree on X, they must agree on Y. It is a statement about all valid states allowed by the semantics—not a coincidence in the sample rows.

Find a candidate key

  1. Put into your start set every attribute that never appears on any non-trivial FD right-hand side.
  2. Compute closure: if an FD’s left side is contained, add its right side.
  3. If closure contains every attribute, you have a superkey.
  4. Remove each start attribute once. If closure stops covering all attributes every time, the key is minimal.

Separate three words

Superkey: uniquely determines all attributes, possibly with extras.
Candidate key: minimal superkey.
Prime attribute: appears in at least one candidate key.

“Minimal” means no proper subset still determines the relation; it does not mean “fewest columns among all keys.”

Homework 06.2 · Candidate key by closure

machine-verified closure

Exam answer

R(A,B,C,D,E), F = { A→C, E→D, B→C }

Attributes absent from every RHS are A, B, E, so every key must contain ABE.

(ABE)+ = ABE → add C using A→C (or B→C) → add D using E→D = ABCDE.

Candidate key = {A,B,E}. R is not BCNF because A, B, and E are not superkeys although each determines a non-trivial attribute.

Minimality and normal forms

Remove A: BE cannot derive A. Remove B: AE cannot derive B. Remove E: AB cannot derive D or E. Therefore the superkey is minimal. It also violates 2NF because C depends on proper subsets A and B, and D depends on E.

No-calculator closure layout Write ABE | +C | +D = ABCDE. Under it, write three one-line removal tests. This is faster and more markable than prose.

Key by closure: start with attributes absent from RHS; expand; then prove minimality by removing each attribute once.

The four normal forms—precise enough for an exam

FormConditionViolation smell
1NFEach cell contains one value from its domain; no repeating group in one cell.aid = "1,5" or attractions = "Louvre, Eiffel Tower".
2NF1NF, and no non-prime attribute depends on a proper subset of any candidate key.With key (sid,aid), student name depends on sid alone.
3NFFor every non-trivial X→A, X is a superkey or A is prime.sid→class and class→leader causes leader to depend transitively on sid.
BCNFFor every non-trivial X→Y, X is a superkey.Any determinant that is not a superkey.
Safe wordingDo not define 3NF merely as “all non-key attributes are independent.” Use the determinant/prime-attribute rule above; it handles relations with multiple candidate keys correctly.
School table with repeating activity IDs, activity names and hours
Real exercise: HomeWork06_en.pdf, p. 1. The comma-separated cells make the displayed table non-1NF.

Homework 06.1 · School database to BCNF

complete by-hand solution

Exam answer

After splitting repeating groups, use SCHOOL(sid, name, class, leader, aid, activity, hours).

FDs: sid→name,class; class→leader; aid→activity; (sid,aid)→hours.

(sid,aid)+ = sid,aid,name,class,leader,activity,hours, so (sid,aid) is the candidate key.

STUDENT(sid, name, class FK→CLASS) CLASS(class, leader) ACTIVITY(aid, activity) PARTICIPATION(sid FK→STUDENT, aid FK→ACTIVITY, hours)

Each resulting determinant is a key of its relation, so the decomposition is BCNF under the stated FDs.

Classroom working example · build every stage

The original final relations above remain the answer. This example exposes the intermediate 1NF, 2NF, and 3NF schemas.

1NF ✓
Explode each activity list
SCHOOL_1NF(sid, aid, name, class, leader, activity, hours)
sid → name, class, leader and aid → activity are partial dependencies ↓
2NF ✓
Split student-only and activity-only facts
STUDENT_2NF(sid, name, class, leader)ACTIVITY(aid, activity)PARTICIPATION(sid, aid, hours)
sid → class → leader is transitive inside STUDENT_2NF ↓
3NF ✓
Split the class fact
STUDENT(sid, name, class FK→CLASS)CLASS(class, leader)ACTIVITY(aid, activity)PARTICIPATION(sid FK→STUDENT, aid FK→ACTIVITY, hours)
BCNF ✓
Unchanged from 3NF

Every determinant shown is a key of its own relation.

Dependency-to-table reasoning

  • The original display is not 1NF because aid/activity/hours contain lists. Explode into one row per student–activity.
  • Key is (sid,aid). Dependencies on sid and aid alone violate 2NF, so separate Student and Activity facts.
  • class→leader makes leader transitively dependent on sid, so separate Class.
  • hours describes one student in one activity and stays in the bridge.
Normalization decomposition of school relation SCHOOL · key (sid, aid)sid, name, class, leader, aid, activity, hours split by determinants STUDENTPK sidname, class FK CLASSPK classleader ACTIVITYPK aidactivity PARTICIPATIONPK/FK sid, aidhours Check: join on class and on sid/aid reconstructs the original 1NF rows.
One determinant, one home. The bridge stores only the fact that depends on the full composite key.
Decomposition check Every source attribute appears; all source facts can be reconstructed with joins; no table stores the same semantic fact twice; every non-trivial determinant in each result is a key.

Normalize by determinant: student facts→STUDENT, activity facts→ACTIVITY, class facts→CLASS, pair facts→bridge(sid,aid,…).

Additional exercise ec_order denormalized column list and normalization tasks
Strong exam-preparation source: LearningLabAdditionalExercise_en.pdf, p. 1.

Additional Exercises 2–3 · ec_order to 3NF

corrected against 1,280 source rows

Exam answer

customer_id→customer attributes; order_id→date, payment_id, customer_id; payment_id→card_number,payment_amount; item_id→name,unit_price; (order_id,item_id)→quantity.

Candidate key of the original 1NF relation: (order_id, item_id).

ALTER TABLE ec_order RENAME TO ec_order_old;

CREATE TABLE ec_customer (
  customer_id integer PRIMARY KEY, gender varchar(6),
  firstname varchar(50), lastname varchar(50), street varchar(75),
  house_number varchar(5), zip_code char(5), city varchar(75)
);
CREATE TABLE ec_order (
  order_id integer PRIMARY KEY, order_date date,
  customer_id integer NOT NULL REFERENCES ec_customer(customer_id)
);
CREATE TABLE ec_payment (
  payment_id bigint PRIMARY KEY, card_number varchar(20),
  payment_amount numeric(10,2), order_id integer NOT NULL UNIQUE
  REFERENCES ec_order(order_id)
);
CREATE TABLE ec_item (
  item_id integer PRIMARY KEY, item_name varchar(100),
  unit_price numeric(10,2)
);
CREATE TABLE ec_order_item (
  order_id integer REFERENCES ec_order(order_id),
  item_id integer REFERENCES ec_item(item_id),
  quantity integer NOT NULL CHECK (quantity > 0),
  PRIMARY KEY (order_id,item_id)
);

INSERT INTO ec_customer
SELECT DISTINCT or_customer_id,or_gender,or_firstname,or_lastname,
  or_street,or_house_number,or_zip_code,or_city FROM ec_order_old;
INSERT INTO ec_order
SELECT DISTINCT or_order_id,or_date,or_customer_id FROM ec_order_old;
INSERT INTO ec_payment
SELECT DISTINCT or_payment_id,or_card_number,or_payment_amount,or_order_id
FROM ec_order_old;
INSERT INTO ec_item
SELECT DISTINCT or_item_id,or_name,or_unit_price FROM ec_order_old;
INSERT INTO ec_order_item
SELECT or_order_id,or_item_id,or_quantity FROM ec_order_old;

-- Verified source range is 8.56 … 988.01, so this loses no rows.
ALTER TABLE ec_item ADD CONSTRAINT unit_price_bounds
  CHECK (unit_price BETWEEN 0 AND 10000);

DROP TABLE ec_order_old;

Classroom working example · build every stage

The FDs, candidate key, final five-table DDL, and data-copy statements above remain the original answer. This example shows the intermediate normal-form schemas.

1NF ✓
Atomic wide order-line relation

One row per (order_id, item_id); all cells are atomic.

order_id-only and item_id-only facts are partial dependencies ↓
2NF ✓
Separate order, item, and pair facts
ORDER_2NF(order_id, date, payment_id, card_number, payment_amount, customer_id, customer attributes)ITEM(item_id, name, unit_price)ORDER_ITEM(order_id, item_id, quantity)
customer_id and payment_id determine non-key details inside ORDER_2NF ↓
3NF ✓
Split the transitive customer and payment facts
CUSTOMER(customer_id, customer attributes)ORDER(order_id, date, customer_id FK)PAYMENT(payment_id, card_number, payment_amount, order_id UNIQUE FK)ITEM(item_id, name, unit_price)ORDER_ITEM(order_id, item_id, quantity)
BCNF ✓
Unchanged from 3NF

Each non-trivial determinant is a candidate key in its own relation; PAYMENT has candidate keys payment_id and order_id under the one-payment-per-order rule.

Corrections and verification

  • Quantity is not determined by item_id. It varies per order line; the correct FD is (order_id,item_id)→quantity. The supplied FD list places it under item_id.
  • City must be copied. The supplied customer INSERT selects seven values into an eight-column table and therefore fails; the corrected statement includes or_city.
  • Do not store both directions of the same 1:1 link. This design keeps order_id UNIQUE in Payment and omits duplicated payment_id from Order.
  • Verified cardinalities: 321 customers, 384 orders, 384 payments, 84 items, 1,280 order lines. No item ID maps to conflicting names/prices and no payment maps to multiple orders.
Copy-data recipe Rename source → create parent tables → INSERT DISTINCT parents → insert child/bridge tables → compare counts → add validated constraints → only then drop the old table.

Order-line FD: item_id→name,unit_price; (order_id,item_id)→quantity. Quantity belongs in ORDER_ITEM, not ITEM.

Learning Lab 07 abstract relation: the fast conclusion

R(A,B,C,D,E,F), F = {A→B, CD→A, BC→D, AE→F, CE→F}

machine-verified candidate keys

Exam answer

C and E never appear on a RHS, so every key contains CE. Closures show ACE, BCE, and CDE each determine all attributes; removing any attribute from each fails.

Candidate keys: ACE, BCE, CDE. Not BCNF: A→B has determinant A, which is not a superkey (and other violations can be shown similarly).

Caution

The supplied answer’s decomposition AB, BCD, AEF does not preserve every listed dependency (notably CD→A and CE→F) as local constraints. The task asks only for keys and the BCNF verdict. If a decomposition is explicitly requested, one verified lossless BCNF result is CEF, AB, ACD, CDE; it does not preserve BC→D and AE→F locally, illustrating the dependency-preservation trade-off.

Classroom status-ladder example

1NF is assumed. It is not in 2NF because CE→F makes non-prime F depend on a proper subset of every candidate key; therefore it is not in 3NF. It is not in BCNF because A→B has a determinant that is not a superkey. Highest normal form: 1NF.

Paper check Write the ladder 1NF → 2NF failure → 3NF failure → BCNF counterexample. One counterexample FD is enough for BCNF: name it and show its determinant’s closure is not all attributes.

BCNF proof of failure: exhibit one non-trivial X→Y with X⁺ ≠ all attributes; decompose only if asked, then check losslessness and dependency preservation separately.

4

Relational algebra: construct the result set

Read an expression from the inside out; write one operator for each phrase in the question.

🔴 Exam-core Prof. Scholz explicitly named Relational Algebra as a focus on 22 July 2026; the final-exam slide, Homework 05, and Learning Lab 06 corroborate it.

Operator vocabulary

OperatorMeaningSchema/result warning
σcondition(R)Select rows.Schema unchanged.
πattributes(R)Project columns.Relational algebra removes duplicates.
ρalias(R)Rename relation/attributes.Needed for self-joins and ambiguous names.
R ∪ S, R ∩ S, R − SSet combine/compare.R and S must be union-compatible: same arity and matching domains.
R × SEvery pair.Usually an intermediate before selection; size |R|×|S|.
R ⋈θ SJoin matching pairs by explicit condition.Safest when names overlap.
R ⋈ SNatural join on all same-named attributes.Convenient only when every same name is intended as a join key.
Natural-join trapIf two relations both contain name or semester, natural join uses all such equal-name columns. Rename first or use a theta join so the predicate is visible.
Relational algebra query built from inside out Base relationsStudent · Exam σ restrictgrade > 4 ⋈ connecton IDs π presentname, title Write expression ← outside-in; evaluate → inside-out Push σ near the base to shrink intermediates; delay π until join keys are no longer needed.
A query’s English order and execution nesting differ. Keep join keys until after the join.
Six relational-algebra exercises and an operation tree
Real exercise: LearningLab06.pdf, p. 5. The tables needed to calculate the result rows are on pp. 1–4.

Learning Lab 06.1 · All six queries

expressions + hand-checked results

Exam answers

1.1 Economics students

πNameStudy='Economics'(Student))

Miriam Seifert; Irina Romanova; Ramesh Venkatesh; Michele Bartoli; Rune Tronne; Gal Geva; Randy Rust.

1.2 Professors in rooms with two places

πProfessor.Name(Professor ⋈Professor.Room#=Room.Room# σPlaces=2(Room))

Anne Smith; Bettina Krause; Konstantin Pfeiffer.

1.3 Courses on Wednesday

πTitle(Lecture ⋈Lecture.Lecture#=TakesPlace.Lecture# σWeekday='Wednesday'(TakesPlace))

Operations Research; Programming Languages.

1.4 Students who passed both Operations Research and Information Systems

ORpass = πStudent#Grade≤4(Examines) ⋈Examines.Lecture#=Lecture.Lecture# σTitle='Operations Research'(Lecture)) ISpass = πStudent#Grade≤4(Examines) ⋈Examines.Lecture#=Lecture.Lecture# σTitle='Information Systems'(Lecture)) πName(Student ⋈ (ORpass ∩ ISpass))

Irina Romanova.

1.5 Students who attend no courses

NoAttend = πStudent#(Student) − πStudent#(Attends) πName(Student ⋈ NoAttend)

Ramesh Venkatesh.

1.6 Failed exams in WT2023

πStudent.Name,Lecture.Title(Student ⋈Student.Student#=Examines.Student# σSemester='WT2023' ∧ Grade>4(Examines) ⋈Examines.Lecture#=Lecture.Lecture# Lecture)
StudentCourse
Rune TronneOperations Research
Michele BartoliMacroeconomics
Michele BartoliIndustrial Economics
Yusuf MahouniInformation Systems

Where the reasoning sits

  • Both becomes set intersection after projecting to the same key schema.
  • None becomes all student keys minus keys appearing in Attends, then a join to recover names.
  • Failed is grade > 4.0 in the supplied German grading convention; semester and grade are selected before joins.
  • Projection to names is last so IDs remain available to join.
Trace-table layout Make tiny key-only intermediate sets in the margin: ORpass = {003,011,002}; ISpass = {001,003,008,009}; intersection = {003}; look up name once.

RA “both” → project same key then ∩; “none” → all keys − participating keys; join names only after set logic.

Learning Lab 06.2 · Operation tree result

complete trace

Exam answer

σName='Konstantin Pfeiffer'(Professor) → professor #004. Project Professor# → {004}. Join with TakesPlace on Professor# → lecture 002 WT2023 and lecture 003 WT2023.

WeekdayTimeslot
Thursday10–12
Wednesday14–16

The final projection removes all other columns; these two tuples remain.

Procedure

Start at leaves, write each intermediate schema as well as rows. A projection node can discard a future join key only if the join has already used it.

Paper recipe Under each tree node write schema: … and then its rows. If a column needed by the parent disappeared, your projection is too early.

Operation tree: evaluate bottom-up; record schema at every node; never project away a key needed above.

Homework 05: compact answer set

Professors:

πname(Professor) πnamearea_of_expertise='Computer Science'(Professor)) → Jane Doe; Jaqueline Jaques πname(Professor ⋈Professor.room_number=Room.room_number σplaces=3(Room)) → Ansgar Fromme; Jaqueline Jaques

Students:

πname,course_of_studycourse_of_study='Mathematics' ∨ course_of_study='Computer Science'(Student)) πStudent.name(Student ⋈ Attends ⋈ σtitle='Database Engineering'(Lecture)) → Mirjam Sloet; Josefine Stracker; Maria Durad; Eoin Seo-Hyun; Daniyal Romulus; Brunhild Nelu; Botros Eilidh Use ρold(Examines) and ρnew(Examines); select old.grade=5 ∧ old.semester='WT2022' ∧ new.semester='WT2023' with equal student and lecture keys → Josefine Stracker.

Definitions: natural join derives equality predicates from all shared attribute names; theta join uses an explicit predicate. Unary operators take one relation (σ, π, ρ); binary operators take two (∪, ∩, −, ×, joins).

5

SQL: translate wording into row grain

Before writing SELECT, decide what one output row represents. Then build joins, filters, grouping, and presentation in logical order.

🔴 Exam-core Prof. Scholz explicitly named SQL as a focus on 22 July 2026; the final-exam slide, Homework 08, Learning Lab 09, the Wrap-Up, and Additional Exercises corroborate it.

SQL logical processing order staircase 1 FROM / JOIN 2 WHERE 3 GROUP BY 4 HAVING 5 SELECT 6 DISTINCT 7 ORDER / LIMIT construct rowsform groupscalculate outputpresent result
Logical order explains why aliases from SELECT are usually unavailable in WHERE and why aggregate conditions belong in HAVING.

Question words → SQL moves

Prompt phraseSQL moveFrequent failure
“each / per”GROUP BY the requested row grain.Grouping by too many columns fragments totals.
“only once / distinct”SELECT DISTINCT.Assuming joins cannot duplicate.
“total more than …”SUM(...) and HAVING.Putting aggregate in WHERE.
“all hotels, plus count”Start at Hotel, use LEFT JOIN, count a non-null booking key.Inner join silently drops zero-booking hotels.
“never”Correlated NOT EXISTS.NOT IN becomes UNKNOWN when subquery yields NULL.
“between 20 and 50”BETWEEN 20 AND 50, inclusive.Writing strict >/< without evidence.
Hotel wrap-up SQL query tasks
Strong exam-preparation source: LearningLabWrapUp.pdf, p. 3.

Wrap-Up 5 · Every hotel query with verified output

12 bookings independently recomputed

Exam answers

-- 5.1.1 rooms below €300
SELECT r.ro_id
FROM hm_room r JOIN hm_type t ON t.ty_id=r.ro_type
WHERE t.ty_price < 300
ORDER BY r.ro_id;
-- → 1, 3, 4, 5, 6, 8, 9, 10

-- 5.1.2 area between 20 and 50, descending
SELECT r.ro_id, t.ty_name
FROM hm_room r JOIN hm_type t ON t.ty_id=r.ro_type
WHERE r.ro_living_area BETWEEN 20 AND 50
ORDER BY r.ro_id DESC;
-- → 10, 9, 8, 6, 5, 4, 3, 1 with their type names

-- 5.2.1 hotels offering a King Size Apartment
SELECT DISTINCT h.ho_name
FROM hm_hotel h
JOIN hm_room r ON r.ro_hotel=h.ho_id
JOIN hm_type t ON t.ty_id=r.ro_type
WHERE t.ty_name='King Size Apartment';
-- → Beach Hotel

-- 5.2.2 all hotels and number of bookings
SELECT h.ho_name, COUNT(b.bo_room) AS visits
FROM hm_hotel h
LEFT JOIN hm_room r ON r.ro_hotel=h.ho_id
LEFT JOIN hm_booking b ON b.bo_room=r.ro_id
GROUP BY h.ho_id,h.ho_name
ORDER BY h.ho_id;
-- → Grand Hotel 6; Beach Hotel 3; Bates Motel 3

-- 5.3.1 guests who ever booked Grand Hotel
SELECT DISTINCT g.gu_name
FROM hm_guest g
JOIN hm_booking b ON b.bo_guest=g.gu_id
JOIN hm_room r ON r.ro_id=b.bo_room
JOIN hm_hotel h ON h.ho_id=r.ro_hotel
WHERE h.ho_name='Grand Hotel';
-- → Susanne Brandt, Paul Brunel, Mika Aikonen, Illes Mihaly, Dominica Valderama

-- 5.3.2 guests spending more than €800
SELECT g.gu_name,
       SUM((b.bo_end_date-b.bo_start_date)*t.ty_price) AS spent
FROM hm_guest g
JOIN hm_booking b ON b.bo_guest=g.gu_id
JOIN hm_room r ON r.ro_id=b.bo_room
JOIN hm_type t ON t.ty_id=r.ro_type
GROUP BY g.gu_id,g.gu_name
HAVING SUM((b.bo_end_date-b.bo_start_date)*t.ty_price) > 800
ORDER BY g.gu_name;
GuestSpendBy-hand check
Antonia Valetta€4,2707 nights × €610
Dominica Valderama€1,9206 × €320
Illes Mihaly€1,0408 × €130
Mika Aikonen€1,6005 × €320
Paul Brunel€1,1703 × €260 + 3 × €130
Rubie Kub€3,38013 × €260

Corrections to supplied answers

  • BETWEEN is inclusive. The supplied strict >20 AND <50 happens to return the same data here but does not faithfully implement “between” at the endpoints.
  • “All hotels” requires LEFT JOIN. The supplied inner joins would remove a hotel with zero bookings. COUNT(b.bo_room) then returns 0 for the preserved row.
  • Night count: PostgreSQL date subtraction returns days; end date minus start date matches the supplied spending convention.
Paper output check For aggregation, write one line defining the group: “one row per guest.” Confirm every selected non-aggregate belongs to that grain. Then compute only the groups passing HAVING.

All parents + count children → parent LEFT JOIN child, GROUP BY parent key, COUNT(child non-null key).

Additional exercise price constraint and SQL selection tasks
Strong exam-preparation source: LearningLabAdditionalExercise_en.pdf, p. 2.

Additional Exercises 4 · Query patterns and verified facts

source dataset executed independently

Exam answers

-- 4.1.1 all customer names
SELECT firstname,lastname FROM ec_customer;

-- 4.1.2 customers with any order total > €5,000
SELECT c.firstname,c.lastname
FROM ec_customer c
WHERE EXISTS (
  SELECT 1 FROM ec_order o
  JOIN ec_order_item oi ON oi.order_id=o.order_id
  JOIN ec_item i ON i.item_id=oi.item_id
  WHERE o.customer_id=c.customer_id
  GROUP BY o.order_id
  HAVING SUM(oi.quantity*i.unit_price)>5000
);
-- → Khairiya al-Mustafa €5,282.34; Awni el-Huq €6,488.12;
--   Analisa Hogeda €5,169.99

-- 4.1.3 count customers who never bought a name beginning A
SELECT COUNT(*) FROM ec_customer c
WHERE NOT EXISTS (
  SELECT 1 FROM ec_order o
  JOIN ec_order_item oi ON oi.order_id=o.order_id
  JOIN ec_item i ON i.item_id=oi.item_id
  WHERE o.customer_id=c.customer_id AND i.item_name LIKE 'A%'
);
-- → 204

-- 4.2.1 orders newest first
SELECT * FROM ec_order ORDER BY order_date DESC;

-- 4.2.2 revenue by gender
SELECT c.gender,SUM(oi.quantity*i.unit_price) AS revenue
FROM ec_customer c JOIN ec_order o USING(customer_id)
JOIN ec_order_item oi USING(order_id)
JOIN ec_item i USING(item_id)
GROUP BY c.gender;
-- → female €241,582.99; male €277,355.37

-- 4.3.1 revenue per item
SELECT i.item_name,SUM(oi.quantity*i.unit_price) AS revenue
FROM ec_item i JOIN ec_order_item oi USING(item_id)
GROUP BY i.item_id,i.item_name;

-- 4.3.2 items with total revenue below €12,000
SELECT i.item_name,SUM(oi.quantity*i.unit_price) AS revenue
FROM ec_item i JOIN ec_order_item oi USING(item_id)
GROUP BY i.item_id,i.item_name
HAVING SUM(oi.quantity*i.unit_price)<12000;
-- → 70 items

-- 4.3.3 products ordered by customers in a city ending “burg”
SELECT DISTINCT i.item_name
FROM ec_customer c JOIN ec_order o USING(customer_id)
JOIN ec_order_item oi USING(order_id)
JOIN ec_item i USING(item_id)
WHERE c.city LIKE '%burg';
-- → 28 distinct product names

Why these are robust

The “ever” query uses a correlated EXISTS whose inner grouping is one order. The “never” query is NULL-safe. Product queries group by the stable ID plus displayed name. The dataset outputs were calculated from all 1,280 rows, not copied from the solution PDF.

Paper recipe Underline the requested output grain (“customer”, “gender”, “item”). Build the FROM path on IDs. Apply row filters. Group only if the question asks per/total. Put aggregate thresholds in HAVING.

SQL order: FROM/JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT.

Airline insert, update and aircraft SQL tasks
Real exercise: HomeWork08_en.pdf, p. 1. Page 2 continues with routing queries.

Homework 08 · Airline queries

corrected scheduled-time semantics

Exam answers

INSERT INTO aircraft(aircraft_code,model,range)
VALUES('NEW','Airbus A400',10000);

UPDATE flight
SET actual_arrival=actual_arrival+INTERVAL '45 minutes',
    status='Delayed'
WHERE flight_id=5;

-- models with range > 5,000
SELECT model FROM aircraft WHERE range>5000;
-- Airbus A330-200; Airbus A380; Boeing 777-200LR

-- planned flights per model on 15 June
SELECT a.model,COUNT(*) AS flights
FROM flight f JOIN aircraft a USING(aircraft_code)
WHERE f.scheduled_departure::date=DATE '2024-06-15'
GROUP BY a.model;
-- A318 6; A330-200 3; A380 1; B757-300 3; B777-200LR 2

-- distinct models scheduled to arrive in Munich on 15 June
SELECT DISTINCT a.model
FROM flight f JOIN aircraft a USING(aircraft_code)
JOIN airport p ON p.airport_code=f.arrival_airport
WHERE p.city='Munich'
  AND f.scheduled_arrival::date=DATE '2024-06-15';
-- Airbus A318; Boeing 757-300; Boeing 777-200LR

-- distinct direct destinations from Madrid, sorted
SELECT DISTINCT arrival.city
FROM flight f
JOIN airport origin ON origin.airport_code=f.departure_airport
JOIN airport arrival ON arrival.airport_code=f.arrival_airport
WHERE origin.city='Madrid'
  AND f.scheduled_departure::date=DATE '2024-06-15'
ORDER BY arrival.city;
-- Chennai; Jakarta; Munich; Reykjavik

-- Munich → Reykjavik with exactly one feasible stop
SELECT f1.scheduled_departure,f2.scheduled_arrival,
       f2.scheduled_arrival-f1.scheduled_departure AS duration,
       stop.city AS stopover
FROM flight f1
JOIN airport origin ON origin.airport_code=f1.departure_airport
JOIN flight f2 ON f2.departure_airport=f1.arrival_airport
JOIN airport stop ON stop.airport_code=f1.arrival_airport
JOIN airport destination ON destination.airport_code=f2.arrival_airport
WHERE origin.city='Munich' AND destination.city='Reykjavik'
  AND f2.scheduled_departure>f1.scheduled_arrival
  AND f1.scheduled_departure::date=DATE '2024-06-15';
-- Helsinki: 04:30→13:20 (9:50), 04:30→18:25 (14:55),
--           11:45→18:25 (7:40), elapsed with time-zone offsets.

-- cities touched by no Boeing departure/arrival that day
SELECT p.city FROM airport p
WHERE NOT EXISTS (
  SELECT 1 FROM flight f JOIN aircraft a USING(aircraft_code)
  WHERE a.model LIKE 'Boeing%'
    AND (
      (f.departure_airport=p.airport_code AND f.scheduled_departure::date=DATE '2024-06-15')
      OR
      (f.arrival_airport=p.airport_code AND f.scheduled_arrival::date=DATE '2024-06-15')
    )
);
-- → Madrid

Verified corrections

  • The prompt asks what is planned; use scheduled, not actual, timestamps.
  • The supplied direct-city query omits DISTINCT.
  • The supplied one-stop answer omits the requested duration and compares actual times. The corrected query both checks the layover and shows elapsed duration.
  • The supplied “no Boeing” answer joins a departure flight and an arrival flight at the same airport, mis-parenthesizes AND/OR, and can exclude the wrong cities. Correlated NOT EXISTS matches the English directly.
Time-zone check PostgreSQL timestamptz subtraction compares absolute instants. A cast to date uses the session time zone; in this exercise the intended calendar date is the displayed schedule date.

Routing self-join: f1.arrival=f2.departure AND f2.scheduled_departure>f1.scheduled_arrival; duration=f2.arrival−f1.departure.

6

Knowledge questions: compact explanations that earn marks

Use definition → mechanism → consequence → tiny example. Avoid empty slogans such as “ACID makes data safe.”

🔴 Exam-core “Knowledge questions” is explicitly named on the final-exam slide; architecture, ACID, pages, buffering, and WAL dominate 02_Architecture.pdf and Homework 02.

DBMS, schema, and the three levels

Database vs DBMS

A database is the organized persistent data plus its schema. A DBMS is the software that defines, queries, secures, coordinates, and recovers that data. PostgreSQL is a DBMS; one named database inside it is not.

Three-schema architecture

External: user/application views. Conceptual: global logical schema. Internal: physical files, pages, indexes. Mappings provide logical and physical data independence.

Homework 02.1 · Why Excel is not an RDBMS

exam-ready knowledge answer

Exam answer

Excel can store tables and evaluate formulas, but it does not satisfy core relational-DBMS requirements: it lacks a DBMS-managed relational catalog and declarative integrity, complete set-level data language, transparent logical/physical data independence, transaction isolation/recovery, and centrally enforced authorization. A spreadsheet cell grid is therefore not an RDBMS merely because rows and columns resemble a relation.

Evidence link to Codd’s themes

Use two or three concrete rules, not all thirteen: an active online catalog queried through the same language, comprehensive relational data sublanguage, integrity independence, and set-level insert/update/delete. Excel may imitate pieces, but enforcement remains in user conventions and files.

Paper recipe State the conclusion first, name three DBMS properties, and connect each to what Excel does not centrally enforce.

RDBMS ≠ grid: DBMS-managed catalog + declarative constraints + set language + transactions/recovery + data independence.

ACID: property, failure prevented, example

PropertyPrecise meaningFailure it prevents
AtomicityA transaction’s effects occur entirely or not at all.Debit succeeds but credit is missing.
ConsistencyA committed transaction takes the database from one constraint-valid state to another, assuming correct transaction logic.Committed FK/CHECK violation.
IsolationConcurrent transactions observe behavior allowed by the chosen isolation level, approaching a serial execution at the strongest level.Lost updates, dirty/non-repeatable/phantom reads as governed by level.
DurabilityAfter commit is acknowledged, effects survive a crash through durable logging/storage.A confirmed booking disappears after power loss.
Consistency caveatACID consistency does not mean “the data is factually true.” It means declared invariants are preserved. The DBMS cannot know that a guest typed the wrong city unless a rule detects it.

Pages, buffer pool, WAL, checkpoint

Write-ahead logging and checkpoint flow TransactionUPDATE + COMMIT WAL buffer / logchange record firstflush before commit reply Buffer poolcached 8 KiB pagesmodified page = dirty Durable WALredo after crashcheckpoint record Data filesheap + index pagesdirty pages flushed later recovery order WAL rule: the log record becomes durable before the corresponding dirty data page.
Commit need not flush every dirty table page immediately. Durable WAL makes redo possible; checkpoints bound the recovery starting point.

Why pages exist

Storage and memory transfer data in blocks, so the DBMS groups tuples into fixed-size pages (8 KiB by default in PostgreSQL). A page carries a header, item pointers, tuple data, and free space. Page IDs make caching, replacement, and disk I/O manageable.

A slotted page lets item identifiers remain stable while variable-length tuples move within the page.

Row vs column layout

Row store: all attributes of a tuple together—good for OLTP reads/writes of whole rows. Column store: values of one attribute together—good for scans/aggregation and compression in OLAP. This is a workload trade-off, not “column is newer and better.”

Homework 02.3 · Checkpoints

PostgreSQL 18 documentation checked 20 Jul 2026

Exam answer

A checkpoint flushes dirty data pages and writes a checkpoint record to WAL so crash recovery can begin from the corresponding redo point. PostgreSQL 18 starts a checkpoint when checkpoint_timeout expires or max_wal_size is about to be exceeded; current defaults are 5 minutes and 1 GB. A 1-second timeout would force dirty-page flushing far too often and, with full-page writes, increase WAL volume after every checkpoint, causing heavy I/O and latency.

Current primary-source confirmation

The explanation and defaults are from the official PostgreSQL 18 WAL Configuration documentation. The slides correctly motivate WAL-before-page and dirty-buffer flushing; this official page confirms the current defaults.

Paper recipe Define checkpoint → say what is flushed/recorded → explain recovery benefit → state the performance trade-off → answer why 1 second is harmful.

Checkpoint = flush dirty pages + checkpoint WAL record; too frequent ⇒ repeated I/O and more full-page WAL; PG18 default timeout 5 min.

Homework 01.3 · Capacity without a calculator

Sensor-table feasibility and storage limit

numerically verified · assumptions exposed

Exam answer

8 million machines × at most 500 sensors = 4,000,000,000 sensor tables. One reading = 8-byte timestamp + 4×8-byte numeric = 40 bytes. At 100 Hz: 4,000 bytes/s per sensor.

Payload-only time = 32 TiB ÷ 4,000 B/s ≈ 278.7 years.

Page-cap cross-check: floor(8192/40)=204 payload readings/page; (2³²−1) pages × 204 ÷ 100 readings/s ≈ 277.6 years.

One table per sensor is not feasible in one PostgreSQL database: 4.0 billion relations exceeds the current 1,431,650,303 relations/database limit, before indexes and practical overhead. Use shared measurement tables keyed by machine_id and sensor_id, with partitioning. The payload-only lifetime is about 278 years; real tuple/page/index overhead makes the practical value lower.

Independent discrepancy record

The supplied solution’s “about 272 years due to the page limit” is not reproducible from the stated 40-byte payload and 8 KiB pages: those assumptions give 277.6 years. Actual PostgreSQL rows require tuple headers and line pointers, but incorporating those would reduce the result far more and requires layout assumptions not stated in the exercise.

Current hard limits are confirmed in the official PostgreSQL 18 limits table.

No-calculator working Write the exact quotient first. For an estimate: 32 TiB ≈ 35×10¹² bytes; 4,000 B/s = 4×10³; quotient ≈ 8.75×10⁹ s; divide by ≈3.15×10⁷ s/year → ≈278 years.

Capacity: rate = samples/s × bytes/sample; lifetime = limit/rate; state payload/overhead assumptions and compare schema object count to DB limits.

Short knowledge answers from the remaining slides

File system problems

Redundancy/inconsistency, isolated formats, difficult ad-hoc access, integrity rules in application code, weak concurrency control, and fragile atomicity/recovery. A DBMS centralizes schema, query, constraint, transaction, security, and recovery services.

Buffer replacement and dirty pages

Reads first seek a page in the buffer pool; on a miss, the DBMS loads it and may evict a victim. A clean victim needs no write; a dirty victim must be written after its WAL is durable. Pinning prevents eviction while a page is in use.

OLTP vs OLAP

OLTP: many short concurrent transactions, point reads/updates, current operational data. OLAP: fewer long scans/aggregations over large histories. Workload shapes indexes, layout, and normalization/denormalization choices.

Codd rule caution

The rules describe a relational system ideal: information as table values, guaranteed access by relation/key/column, systematic NULL handling, online catalog, relational language, view updating where possible, set-level writes, independence, integrity, and distribution independence.

🟠 Exam-practical Prof. Scholz said all semester topics remain relevant on 22 July 2026, but views, procedures, functions, and triggers were not among the five focus areas and do not appear in the two exam-preparation sets.

ObjectOne-line distinctionPostgreSQL cue
ViewNamed stored query; ordinary view stores definition, not rows.CREATE VIEW … AS SELECT …
ProcedureInvoked action; may support transaction control when called appropriately.CALL p(...)
FunctionReturns a value/set and can appear in expressions/queries.SELECT f(...)
TriggerAutomatically invokes a trigger function before/after/instead of an event.CREATE TRIGGER …

⚪ Low priority Installation commands, pgAdmin/psql navigation, and tool-specific ER export occur only in setup-oriented labs, not the exam-preparation tasks.

🗑️ Slide noise Decorative title/review divider slides and stock imagery repeat structure but contribute no assessable method.

7

The mock-equivalent 90-minute paper rehearsal

Prof. Scholz confirmed that a specific iLearn learning lab is comparable to a mock exam. The email did not name it; the integrated Wrap-Up lab is the strongest local match. One route, no calculator, no memory sheet.

🔴 Exam-core Instructor briefing, 22 July 2026: a specific iLearn learning lab is mock-equivalent; learning labs and homework define the focus.

  1. 0:00–0:05 · Scan. Read every verb, circle output forms, and reserve the last five minutes. If the real paper prints points, replace this timing with point-proportional timing.
  2. 0:05–0:17 · Knowledge. From memory: DBMS vs file system; ACID; database page; WAL/checkpoint and why a 1-second checkpoint is harmful.
  3. 0:17–0:42 · Design. Complete LearningLabWrapUp Tasks 1–3: Chen ER, relational lines, corrected keys, and DDL skeleton.
  4. 0:42–1:02 · Normalize. On Additional Exercises 2–3: write FDs, key, five 3NF tables, copy order, and unit-price constraint.
  5. 1:02–1:15 · Relational algebra. Do Learning Lab 06 Tasks 1.4, 1.5, 1.6 and the operation-tree result.
  6. 1:15–1:25 · SQL. Write Wrap-Up 5.2.2 and 5.3.2 plus Additional 4.1.3. State one output row’s grain for each.
  7. 1:25–1:30 · Audit. Check bridge discriminator; PK/FK; inclusive boundaries; LEFT JOIN; aggregate/HAVING; DISTINCT; aliases; boxed answers.
Visible solution mapKnowledge answers are in Chapter 6; Wrap-Up design/DDL in Chapters 1–2; Additional normalization in Chapter 3; Learning Lab 06 in Chapter 4; SQL in Chapter 5. Mark by method: recognition, schema, execution, or check. Redo only the failed method on a blank half-page.

The error list to read before handing in

  1. A repeated booking/event has a bridge key that omits the date discriminator.
  2. An identifier that can begin with zero or contain letters is declared numeric.
  3. A natural join accidentally uses a shared non-key name.
  4. A projection removes the key needed by the next join.
  5. WHERE is used for an aggregate threshold instead of HAVING.
  6. An inner join removes required zero-count parents.
  7. COUNT(*) on a LEFT JOIN reports one for the null-extended row.
  8. NOT IN is vulnerable to NULL, or the anti-join is scoped to the wrong customer.
  9. Actual timestamps are used where the prompt says planned/scheduled.
  10. The final relation/result, units, or requested order is not shown.
T

Exam toolkit & compact glossary

The last-page reference: recognize the output language, write the minimum complete answer, and run one decisive check.

🟠 Exam-practical Synthesizes the output types named on the final-exam slide and the failure modes repeated across Wrap-Up, Additional Exercises, homework, and labs.

Recognize → write → check

If the prompt says…Put this on paperFast invariant
“Draw/model the requirements”Entities with keys, relationships, attributes, and both cardinalities.Read every relationship sentence from both ends.
“Transform into relations / DDL”One relation line per table, underlined PK, labelled FKs; then constraints.Every FK targets a declared PK or UNIQUE key.
“Find keys / normalize”FDs, closure of each minimal key, highest normal-form test, decomposition.Every fact appears once and the original facts can be reconstructed by joins.
“Express in relational algebra”Inside-out expression; rename when names collide; final projection last.All attributes needed by later joins survive until those joins.
“For each / total / more than”SQL with explicit joins, GROUP BY at the requested grain, HAVING for group filters.One output row represents exactly the thing requested after “each/per”.
“All, including none / never”LEFT JOIN + COUNT(non-null child key), or correlated NOT EXISTS.Mentally test a parent with zero matching child rows and a NULL in the subquery.
“Explain”Definition → mechanism → consequence → tiny example.Replace any slogan with the failure it prevents.

Reproduce from memory

  • Hotel ER structure and the repeat-booking discriminator.
  • ER → relation mapping for entity, 1:N, 1:1, M:N, multivalued, and recursive cases.
  • Closure recipe plus the exact 2NF, 3NF, and BCNF tests.
  • Relational-algebra operators and inside-out construction.
  • SQL logical order: FROM/JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT.
  • ACID meanings and the WAL-before-data rule.

Draw / trace on blank paper

  • One Chen ER model with cardinalities added last.
  • One wide row decomposed by determinant into entity and bridge tables.
  • One relational-algebra operation tree, starting from base relations.
  • One SQL row-grain trace: joined rows → WHERE survivors → groups → HAVING survivors → output.
  • One WAL sketch: transaction sends log and dirty page; log becomes durable first.

Glossary you can actually use

TermPrecise meaningPlain reading / exam use
EntityA distinguishable kind of object with its own occurrences and identifier.A noun that deserves its own rectangle and later its own table.
RelationshipAn association among entity occurrences; it may have attributes.A verb-shaped fact such as Guest BOOKS Room; dates describe the booking.
CardinalityThe permitted minimum and maximum number of related occurrences.The answer to “how many from each side?” Include zero when participation is optional.
Candidate keyA minimal set of attributes that functionally determines every attribute of a relation.Its closure is everything, and removing any member breaks that property.
Primary key (PK)The candidate key chosen to identify rows; its values are unique and non-null.The row’s declared identity.
Foreign key (FK)Attributes whose non-null values must match a referenced candidate key.The stored link to a parent row; usually placed on the N side of 1:N.
Functional dependency X → YAny two legal rows equal on X must also be equal on Y.X fixes Y. It is a rule over all valid states, not an accident in today’s data.
DeterminantThe left-hand side X of a functional dependency X → Y.The attributes that decide a fact’s value and therefore suggest that fact’s home table.
Prime attributeAn attribute belonging to at least one candidate key.Needed for the formal 2NF/3NF tests; “prime” does not mean “primary-key only”.
3NFFor each non-trivial X → A, X is a superkey or A is prime.Permits the prime-attribute exception; BCNF does not.
Selection σA relational-algebra operator that keeps rows satisfying a predicate.The WHERE-like row filter.
Projection πA relational-algebra operator that keeps named attributes and removes duplicate tuples.The SELECT-list-like column choice, but with set semantics.
JoinA combination of related tuples satisfying a predicate.Pair rows on keys; never leave the predicate implicit when same-named non-keys exist.
NULLA marker for missing or inapplicable information, not a value equal to anything.Comparisons yield UNKNOWN; use IS NULL and distrust NOT IN with nullable results.
Row grainThe real-world fact represented by one output row.Say “one row per hotel/customer/order”; it tells you the GROUP BY columns.
TransactionA unit of work governed by atomicity, consistency, isolation, and durability.The boundary within which writes commit together or roll back together.
WALWrite-ahead logging: the recovery log record is durable before its changed data page.Log first, page later; recovery can redo/undo after failure.
CheckpointA recovery marker accompanied by flushing dirty pages according to DBMS policy.Shortens recovery’s starting distance; doing it constantly creates extra I/O.
Final 60-second hand-in auditBox the requested output. Check both ER cardinalities; every table’s PK/FK; bridge discriminator; closure minimality; final RA projection; every SQL join predicate; WHERE versus HAVING; zero-row preservation; DISTINCT; scheduled versus actual time; date boundaries; requested ordering; and units or result rows.
A

Source exercise answer atlas

Complete compact answers for every supplied exercise set. Core exam archetypes above remain the primary study route; this atlas closes subparts and lets you drill by original numbering.

1 · Introduction

HomeWork01_en.pdf · Tasks 1–3

generated/verified solution

Answers

1 Install and connect. Install PostgreSQL with pgAdmin, start the server, connect in pgAdmin to host localhost, port 5432, maintenance DB postgres; in psql use psql -U postgres -d postgres. Verify with SELECT version(); and SELECT current_database(),current_user;.

2 Name/history. PostgreSQL descends from the POSTGRES project at UC Berkeley, itself a successor to Ingres; “SQL” was added to the name as SQL support became central. Final line: POSTGRES + SQL → PostgreSQL.

3 Capacity. 8,000,000×500 = 4,000,000,000 tables, exceeding the current relations/database limit. Per sensor: 100×(8+4×8)=4,000 B/s; 32 TiB/4,000 B/s = 278.731 payload-only years. Page-only cross-check = 277.643 years; use shared/partitioned measurements, not one table/sensor.

Checks

Connection queries prove both server and identity. The storage result excludes tuple headers, page headers, item pointers, indexes, and operational headroom; state that assumption. The 272-year supplied page answer is recorded as non-reproducible from the stated numbers.

What to write For a research/setup task, show the command and the verification query; for capacity, show units on every line.

Rate×time=capacity; always state payload and storage-overhead assumptions.

LearningLab01_en.pdf · Tasks 1, 2.1–2.6, 3.1–3.4

independently generated solution

Answers

1. Use one paper sheet per relation; stable IDs link sheets rather than copying names.

2.1. USER(user_id,nickname,first_name,last_name,birthday); CHAT(chat_id,title,created_at,created_by); CHAT_MEMBER(chat_id,user_id); MESSAGE(message_id,chat_id,author_id,reply_to,text,created_at). Create 6 User rows, 3 Chat rows, 9 membership rows (4+2+2 with one local user reused as appropriate), and 20 Message rows (10+5+5). Access a conversation by selecting MESSAGE rows with chat_id and sorting created_at; index message(chat_id,created_at).

2.2. Birthday belongs once in USER; lookup by user_id/nickname. Index nickname if it is a frequent unique search key.

2.3. Delete MESSAGE WHERE author_id=:u; USER remains, so birthday remains. With replies, use ON DELETE SET NULL for reply_to or delete replies in safe order.

2.4. Global latest: order all messages by created_at DESC, message_id DESC, take first. Per chat: ROW_NUMBER() OVER(PARTITION BY chat_id ORDER BY created_at DESC,message_id DESC)=1, or PostgreSQL DISTINCT ON (chat_id).

2.5. Update one CHAT row. 2.6. Update one USER row; messages reference the ID. Copying the name on every message would require many edits and cause inconsistency.

3.1. Point lookup by PK is fast; scanning message text or counting by unindexed surname prefix is slower. Index known access paths, but no single set of indexes optimizes every read and write: indexes cost storage and update work.

3.2. Concurrent edits need a transaction and a conflict policy. Lock the row briefly (SELECT … FOR UPDATE) or use optimistic version checking; keep transactions short. Last-writer-wins is fast but may lose an update.

3.3. Working memory holds only a small changing set; a DB buffer/cache holds hot pages while persistent storage retains the complete set. 3.4. Compute AVG(age) by scanning birthdays; an index usually cannot remove all aggregation work. A maintained summary can be faster but must be updated correctly; computing age from birthday avoids a stale stored age.

Design lesson

Identifiers separate identity from mutable labels; membership and messages are repeating facts; indexing is workload-specific; concurrency needs a defined isolation/conflict rule; cached/derived aggregates trade write complexity for read speed.

Paper check Rename a user and a chat in your model. If more than one fact row changes, you duplicated descriptive data.

Store mutable entity facts once; reference stable IDs; index the actual (filter,join,sort) access path.

2 · Architecture and PostgreSQL basics

HomeWork02_en.pdf · Tasks 1–3

complete concise answer

Answers

1. Excel lacks DBMS-managed relational catalog, comprehensive relational data language, declarative integrity/data independence, and transaction/concurrency/recovery services; therefore it is not an RDBMS.

2. A database page is the fixed-size unit the DBMS moves between disk and buffer pool. PostgreSQL commonly uses 8 KiB pages containing a header, item pointers, tuples, and free space. Pages amortize I/O and support addressing, caching, replacement, and recovery.

3. A checkpoint flushes dirty pages and records a WAL recovery point. PostgreSQL 18 defaults: 5 min timeout and 1 GB max WAL trigger. One second means frequent dirty-page writes and extra full-page WAL, harming throughput/latency.

Check

Each answer gives definition, mechanism, and consequence. Official PostgreSQL 18 WAL documentation is linked in Chapter 6.

Exam form Three sentences per concept are enough when each sentence has a job.

Page = I/O/cache unit; WAL precedes dirty page; checkpoint bounds redo but costs I/O.

LearningLab02_en_.pdf · Tasks 1, 2.1–2.8, 3.1–3.2

SQL answer + integrity audit

Answers

-- 1 in psql
\l+             -- databases and sizes
\du             -- roles

-- 2.1–2.2 run as an administrative role
CREATE ROLE lecture LOGIN CREATEDB PASSWORD 'choose-a-password';
CREATE DATABASE lecture OWNER lecture;
-- reconnect to database lecture as lecture
CREATE SCHEMA messenger AUTHORIZATION lecture;
SET search_path TO messenger;

-- 2.3–2.7
CREATE TABLE me_user(
 us_id bigint PRIMARY KEY,us_nickname varchar(50),
 us_lastname varchar(50),us_firstname varchar(50),us_birthday date);
CREATE TABLE me_chat(
 ch_id bigint PRIMARY KEY,ch_title varchar(255),
 ch_created_at timestamp,ch_created_by bigint REFERENCES me_user);
CREATE TABLE me_chatuser(
 cu_userid bigint REFERENCES me_user,
 cu_chatid bigint REFERENCES me_chat,
 PRIMARY KEY(cu_userid,cu_chatid));
CREATE TABLE me_message(
 ms_id bigint PRIMARY KEY,
 ms_chat bigint REFERENCES me_chat,
 ms_refer bigint REFERENCES me_message(ms_id),
 ms_text text,ms_created_at timestamp,
 ms_created_by bigint REFERENCES me_user);

-- 3.2 after executing MessengerData.sql
SELECT * FROM messenger.me_message;
INSERT INTO messenger.me_message
 (ms_id,ms_chat,ms_refer,ms_text,ms_created_at,ms_created_by)
SELECT 11,c.ch_id,NULL,'I will be back.',CURRENT_TIMESTAMP,u.us_id
FROM messenger.me_chat c CROSS JOIN messenger.me_user u
WHERE c.ch_title='Saturday Night Fever' AND u.us_nickname='terminator';
\copy messenger.me_message TO 'messages.csv' CSV HEADER

2.8 integrity checks. Personal/group chats: structurally yes (membership count is not constrained). Delete a user’s messages but retain birthday: yes, delete Message rows only. Delete User yet retain their name in messages: no under the supplied schema/FK; use soft deletion/anonymized User row or an explicit author-name snapshot. Replies: yes through nullable self-FK ms_refer.

3.1. Execute MessengerData.sql in database lecture; verify counts: 5 users, 3 chats, 9 memberships, 10 messages before the new insert.

Integrity lesson

The lab’s supplied schema cannot satisfy every checklist item simultaneously. A foreign key preserves the author row, while deleting the author would violate it; a soft-delete policy is the normalized solution when history must remain attributable.

Operational check After each load run SELECT COUNT(*) per table and test an FK violation inside a transaction that you roll back.

Historical identity: keep/soft-delete parent, or deliberately snapshot display name; do not promise a behavior the FK schema forbids.

3 · Relational design

HomeWork03.pdf · Tasks 1–3

ER/temporal solution

Answers

1. COMPANY(company_id,name,legal_form) 1:N DEPARTMENT(department_id,name); EMPLOYEE(employee_id,name,birthday) works for exactly one Department; Department has one head Employee; EMPLOYEE has a recursive 1:N BOSSES relation (one boss to many subordinates). COMPANY has a disjoint, total specialization into PRODUCER(production_capacity) and RETAILER(storage_capacity), because “either … or …” excludes both/neither.

2. Replace current-valued links with temporal relationships: WORKS_FOR(employee,department,start_date,end_date), HEADS(employee,department,start_date,end_date), BOSSES(boss,subordinate,start_date,end_date). Suggested keys: (employee_id,start_date) for works/head history when an employee can hold one such role at an instant; (boss_id,subordinate_id,start_date) for boss history. Add end>start and business rules for non-overlap if required.

3. Monst-ER Park is an external interactive practice activity and has no written solution artifact. Completion requires playing the site; it is safe to skip in this three-day exam route after the paper drills.

Check

Task 2 changes cardinality over time: do not leave department_id/head_id/boss_id as single current fields if history is required. A company’s subtype attributes live only in subtype entities.

Hand draw Add dates to diamonds, not Employee. Write disjoint/total beside the specialization.

When a relationship changes over time, model its occurrences with start/end; key includes participants plus start.

LearningLab03.pdf · Tasks 1–4

complete model specifications

Answers

1 Insurance. CUSTOMER(customer_id,name) 1:N CAR(vin,model); CAR 1:N ACCIDENT(accident_id,date,…), with zero accidents allowed; POLICY(policy_id,…) M:N CAR; POLICY 1:N PREMIUM_PAYMENT(payment_id,period_start,period_end,due_date,received_date,amount). “One or more” means total participation on Customer→Car, Policy→Car, and Policy→Payment sides.

2 CARESE. LOCATION(location_id,address) 1:N VEHICLE(vehicle_id,brand,seats); VEHICLE M:N VEHICLE_TYPE(type_id,name). CUSTOMER supertype (customer_id,name,address,phone) has disjoint subtypes PRIVATE(birthday,credit_card) and BUSINESS(vat,discount_category). RESERVATION is a ternary event linking Customer, VehicleType, and Location with pickup_date and return_date; add reservation_id or a composite event key. New types are rows.

3 Requirements. Record Lecture ID/title/description/type; semester offerings; professor assignments; rooms, weekdays, and timeslots; student attendance; exams, examiner/location; each student’s grade; prerequisites. Clarify whether two professors may co-teach, one room hosts overlapping lectures, repeated attempts, and tutor limits.

4 Lecture ER. PROFESSOR 1:N TEACHES LECTURE per Semester; LECTURE M:N STUDENT through ATTENDS(Semester); LECTURE N:M ROOM through TAKES_PLACE(Semester,Weekday,Timeslot); EXAM belongs to Lecture and has student attempts/examiner/grade; LECTURE has recursive M:N PREREQUISITE. Use offering (lecture,semester) as the anchor when semester-specific facts repeat.

Check

Requirements analysis names unresolved constraints rather than guessing. Ternary Reservation is justified because the same customer/type can be reserved at different locations and dates.

Paper check For each “one or more,” mark minimum participation; for each future list, verify an INSERT can extend it.

Growing classifications are entity rows; reservations/offerings are event entities when three dimensions and dates jointly identify the fact.

LearningLab04.pdf · Tasks 1.1–1.6 and 2

pgAdmin model translated to DDL

Answers

CREATE SCHEMA moviemanager;
CREATE TABLE moviemanager.movie(
 movie_id bigint PRIMARY KEY,title varchar(200) NOT NULL,
 publication_date date);
CREATE TABLE moviemanager.actor(
 actor_id bigint PRIMARY KEY,first_name varchar(80),
 last_name varchar(80),stage_name varchar(120),birthday date);
CREATE TABLE moviemanager.library(
 library_id bigint PRIMARY KEY,name varchar(120) NOT NULL,
 address text);
CREATE TABLE moviemanager.movie_actor(
 movie_id bigint REFERENCES moviemanager.movie,
 actor_id bigint REFERENCES moviemanager.actor,
 PRIMARY KEY(movie_id,actor_id));
CREATE TABLE moviemanager.library_movie(
 library_id bigint REFERENCES moviemanager.library,
 movie_id bigint REFERENCES moviemanager.movie,
 PRIMARY KEY(library_id,movie_id));
CREATE TABLE moviemanager.opening_hours(
 library_id bigint REFERENCES moviemanager.library,
 weekday smallint CHECK(weekday BETWEEN 1 AND 7),
 opens time,closes time,PRIMARY KEY(library_id,weekday),
 CHECK(closes>opens));

1.4 explanation. pgAdmin converts each M:N relation into a junction table because a foreign key on only one side can represent at most 1:N. 1.6. Generate SQL, inspect PK/FK targets and schema qualification, execute, then compare catalog tables to the model.

2. The supplied lecturemanager.sql implements Room, Professor, Student, Lecture, Attends, Teaches, Examines, TakesPlace, and Prerequisite with bridge keys. Import into schema lecturemanager; verify with \dt lecturemanager.* and catalog/ER view.

Check

Opening hours repeat by day, so one pair of open/close columns in Library is insufficient. A bridge has both foreign keys and a composite primary key to prevent duplicate pairs.

Tool-independent evidence Even if pgAdmin is unavailable, the relational schema and generated DDL are the assessable design result.

M:N in an ER tool becomes a junction table with both FKs and usually their composite PK.

4 · Relational model and algebra

HomeWork04_en.pdf · Tasks 1–3

complete relational answer

Answers

1. Union = {007 James Bond, 008 Hans-Dieter Kurz, 013 Carla Chester, 014 Jodie Leer, 021 Anna Koivonnen, 023 Wladimir Ivanov, 042 Simon Jones, 123 Tawfik Hamed}. Intersection = {007 James Bond, 042 Simon Jones}. Table1−Table2 = {013 Carla Chester, 014 Jodie Leer, 123 Tawfik Hamed}. (The reverse difference would be {008 Hans-Dieter Kurz, 021 Anna Koivonnen, 023 Wladimir Ivanov}.)

2. character(n)/char(n)/bpchar(n): fixed-length and blank-padded. character varying(n)/varchar(n): variable length with limit. text: variable unlimited length. PostgreSQL’s lengthless bpchar is variable unlimited length with trailing spaces semantically insignificant; lengthless character means character(1). For general strings PostgreSQL recommends text or varchar; see the official PostgreSQL 18 character-type documentation.

3.

COMPANY(company_id,name,legal_form)PRODUCER(company_id PK/FK→COMPANY,production_capacity)RETAILER(company_id PK/FK→COMPANY,storage_capacity)DEPARTMENT(department_id,name,company_id FK→COMPANY)EMPLOYEE(employee_id,name,birthday)WORKS_FOR(employee_id FK, start_date,department_id FK,end_date)HEADS(department_id FK,start_date,employee_id FK,end_date)BOSSES(boss_id FK,subordinate_id FK,start_date,end_date)

Checks

Set operators use whole tuples and remove duplicates. History keys include start date. Producer/Retailer inherit Company identity. The supplied relation listing names both recursive columns “EmployeeID”; distinct role names are required.

Paper check State the direction of set difference and annotate role names on recursive FKs.

Set difference is directional; recursive relation columns need role names such as boss_id and subordinate_id.

LearningLab05.pdf · Tasks 1.1–1.3, 2.1–2.2, 3.1–3.3

refined relational solution

Answers

1.1 Order database. CUSTOMER(customer_id,name); CATEGORY(category_id,name); PRODUCT(product_id,name,category_id FK); ORDERS(customer_id FK,product_id FK).

1.2 extension. Model CATEGORY 1:N recursive parent; PRODUCT 1:N VERSION; an ORDER event for customer/date/time and ORDER_LINE for version, quantity, and price. This permits the same customer/version at different times and simultaneous product versions.

1.3 refined model. CUSTOMER(customer_id,name); CATEGORY(category_id,name,parent_id FK→CATEGORY nullable); PRODUCT(product_id,name,category_id FK); VERSION(version_id,product_id FK,description); CUSTOMER_ORDER(order_id,customer_id FK,ordered_at); ORDER_LINE(order_id FK,version_id FK,quantity,unit_price). Check quantity>0 and unit_price≥0.

2.1 Lecture model. PROFESSOR(professor_id,name,expertise,room_id FK); ROOM(room_id,places); STUDENT(student_id,name,course_of_study); LECTURE(lecture_id,title,type,description); ATTENDS(lecture_id,student_id,semester); TEACHES(lecture_id,semester,professor_id); EXAMINES(lecture_id,student_id,semester,professor_id,grade,location); TAKES_PLACE(lecture_id,semester,room_id,weekday,timeslot); PREREQUISITE(lecture_id,prerequisite_id).

2.2 evaluation. Multiple courses/student: yes. Duplicate student names: yes (ID is key). One professor in a room: possible. Three professors in one room: possible (room FK is not UNIQUE). Same lecture in different semesters: yes because semester is in Attends key. Two professors teaching same lecture/semester: no under TEACHES PK(lecture,semester). A professor can sit in a room where another teaches: yes; no constraint links office occupancy to teaching.

3.1 tutors. TUTOR(student_id PK/FK→STUDENT); SUPPORTS(lecture_id,semester,student_id FK→TUTOR). PK(lecture_id,semester) enforces at most one tutor.

3.2 books. BOOK(book_id,title,publisher); AUTHOR(author_id,name); BOOK_AUTHOR(book_id,author_id); RECOMMENDED(lecture_id,book_id). 3.3 each M:N becomes the two-FK bridge just listed.

Check

A surrogate order_id separates the event from its customer/product pair. The TEACHES key and SUPPORTS key are business constraints, not only technical choices.

Requirement test Try inserting the same version twice at different ordered_at values and a second tutor for one offering. First must succeed; second must fail.

Choose bridge keys to encode the promised multiplicity: semester in repeated offerings; PK(lecture,semester) for at-most-one tutor.

HomeWork05_en.pdf and LearningLab06.pdf

all requested algebra parts

Answers

Homework 05 1.1–1.2 and 2.1–2.2: expressions and result names are in Chapter 4 under “Homework 05.” Natural vs theta join and unary/binary definitions are stated there.

Learning Lab 06 1.1–1.6 and 2: all expressions, result rows, and the operation-tree trace are in Chapter 4.

Learning Lab 06 3.1 IMDB.

1 πname(Movies) 2 πfirst_name,last_namegender='F'(Actors)) 3 πd.first_name,d.last_namem.name='Aliens'mMovies ⋈m.id=md.movie_id ρmdMovies_Directors ⋈md.director_id=d.id ρdDirectors)) 4 πd.first_name,d.last_namedDirectors ⋈d.id=dg.director_id σgenre='Drama'∧prob≥0.5dgDirectors_Genres)) 5 πm.name,m.yearfirst_name='Arnold'∧last_name='Schwarzenegger'(Actors) ⋈ Roles ⋈ Movies ⋈ σgenre='Thriller'(Movies_Genres))

3.2 reformulation. Push selections genre='Drama'∧prob≥0.5, actor name, and genre='Thriller' to their base relations before joins; project to required IDs/labels only after retaining join keys. This reduces intermediate tuples without changing set semantics.

Check

The chapter answers keep schemas compatible for intersection/difference and use renaming for repeated relations. IMDB result rows depend on the supplied ReLaX dataset/tool; the algebra above is the requested answer and was aligned with RelaX_Solution.txt.

Performance comparison Estimate intermediate size: early σ never increases row count; therefore it usually reduces join work.

Equivalent RA reformulation: push σ down; retain join keys; project late enough to preserve joins.

5 · Normalization and DDL

HomeWork06_en.pdf · Tasks 1.1–1.4, 2.1–2.3

complete answer

Answers

1.1–1.3. Full FDs, key, normal-form analysis, and BCNF decomposition are in Chapter 3. 1.4 SQL:

CREATE SCHEMA school;
CREATE TABLE school.class(
 class_id varchar(3) PRIMARY KEY,leader varchar(100) NOT NULL);
CREATE TABLE school.student(
 sid integer PRIMARY KEY,name varchar(100) NOT NULL,
 class_id varchar(3) NOT NULL REFERENCES school.class);
CREATE TABLE school.activity(
 aid integer PRIMARY KEY,activity varchar(80) NOT NULL UNIQUE);
CREATE TABLE school.participation(
 sid integer REFERENCES school.student,
 aid integer REFERENCES school.activity,
 hours integer NOT NULL CHECK(hours>=0),
 PRIMARY KEY(sid,aid));

2.1. Candidate key ABE. 2.2. Not BCNF because A→C, B→C, and E→D have determinants that are not superkeys. 2.3. A 2NF violation requires a non-prime attribute to depend on a proper subset of a candidate key. A one-attribute key has no non-empty proper subset, so such partial dependency cannot occur.

Check

The supplied SQL omits foreign keys from Student to Class and Participation to its parents; the corrected DDL includes them. Splitting “10b” into numeric level + class letter is optional unless the semantics require querying those parts.

Paper proof Say “single-attribute keys have no proper non-empty subset”—that is the exact reason for Task 2.3.

2NF violation requires composite candidate key + non-prime attribute depending on a proper subset.

LearningLab07_en.pdf · Tasks 1.1–1.3, 2.1–2.3, 3.1–3.2

complete normalization answer

Answers

1.1. StudentID→Name,Gender; (StudentID,Unit)→Grade. Unit alone determines no other stored attribute. 1.2. Candidate key: (StudentID,Unit). 1.3. Original relation: 1NF yes; 2NF no because StudentID→Name,Gender is partial on (StudentID,Unit); therefore 3NF no and BCNF no. Final BCNF relations: STUDENT(StudentID,Name,Gender) and STUDENT_UNIT(StudentID,Unit,Grade), with StudentID as FK→STUDENT. Check grade 0–100 and gender in ('M','F','X').

2.1 CIA. Before 1NF: City→Country,CityPopulation,CountryPopulation,Capital,Attractions-list and Country→CountryPopulation. After 1NF: City→Country,CityPopulation,CountryPopulation,Capital and Country→CountryPopulation; City does not determine Attraction. 2.2. Candidate key before 1NF: City; after 1NF: (City,Attraction). Country is not a candidate key because Country+={Country,CountryPopulation}. 2.3. Original relation: 1NF no because Attractions contains a list; therefore 2NF, 3NF, and BCNF no. Final BCNF relations: COUNTRY(Country,CountryPopulation), CITY(City,Country FK→COUNTRY,CityPopulation,Capital), and CITY_ATTRACTION(City,Attraction), with City as FK→CITY.

3.1. Candidate keys ACE, BCE, CDE (closure-verified). 3.2. Not BCNF; A→B alone is a counterexample because A is not a superkey. No decomposition is requested; the supplied three-table decomposition does not preserve every listed dependency locally.

Checks

Exactly one capital per country is a cross-row business rule: a partial unique index on country where capital is true enforces at most one; “at least one” needs a deferred assertion/trigger or transaction workflow. It is not solved merely by normalization.

1NF check If one displayed cell becomes several rows, recompute the key after exploding it.

After removing a repeating group, recompute the candidate key; the repeated value often joins the old key.

HomeWork07_en.pdf · Tasks 1.1–1.3, 2.1–2.2

complete DDL answer

Answers

1.1. FDs: IID→CID,Items,Date,Amount and CID→Name,City; key IID. Assuming Name is one atomic display value, the table is 1NF and 2NF (single-column key), but not 3NF/BCNF because CID is not a superkey. Decompose CUSTOMER(CID,Name,City) and INVOICE(IID,CID FK,Items,Date,Amount); both BCNF. Splitting first/last name is a separate domain/design choice, not required by 1NF.

Classroom working example · stage labels

1NF: INVOICE_1NF(IID,CID,Name,City,Items,Date,Amount). 2NF: unchanged because IID is a one-column key. 3NF: split IID→CID→Name,City into CUSTOMER and INVOICE. BCNF: unchanged because IID and CID are keys of their own relations.

1.2. A PostgreSQL schema is a namespace inside the currently connected database. Therefore connect to lecture first, create invoiceschema, and schema-qualify both table names:

-- current database: lecture
CREATE SCHEMA invoiceschema;
CREATE TABLE invoiceschema.customer(
 cu_id integer PRIMARY KEY,
 cu_firstname varchar(255) NOT NULL,
 cu_lastname varchar(255) NOT NULL,
 cu_city varchar(255) NOT NULL);
CREATE TABLE invoiceschema.invoice(
 in_id integer PRIMARY KEY,
 in_customer integer NOT NULL REFERENCES invoiceschema.customer(cu_id),
 in_items integer NOT NULL CHECK(in_items>0),
 in_date date NOT NULL,
 in_amount numeric(10,2) NOT NULL CHECK(in_amount>=0));

The qualified form needs no search-path assumption. If Name stayed atomic in Task 1.1, use one cu_name column instead of first and last name.

1.3. ER: CUSTOMER 1:N INVOICE; keys CID/IID; invoice attributes Items, Date, Amount. Exporting with pgAdmin is a tool action; the model is the assessable output.

2.1 true/false. More than 1,000 aircraft impossible: false (char(3) has far more values). Each airport has exactly one city value: true per NOT NULL column, though several airports may share a city. Same departure/arrival airport forbidden: false, no such CHECK. Equal scheduled departure/arrival: true, impossible, because arrival>departure. Delayed flights selectable: true from scheduled vs actual/status. Aircraft cannot leave before it arrived: false; no cross-flight constraint.

2.2.

ALTER TABLE aircraft RENAME COLUMN range TO max_distance;
ALTER TABLE flight ALTER COLUMN status SET DEFAULT 'On Time';
ALTER TABLE airport ADD CHECK(airport_code ~ '^[A-Za-z]');

Check

The supplied Task 1.2 answer omits the requested CREATE SCHEMA; adding it and qualifying the tables is the complete answer. A column being mandatory proves one city value per airport row, not a real-world uniqueness claim. Cross-row chronology between flights requires a much richer schedule constraint.

True/false form Answer first, then point to the exact PK/NOT NULL/CHECK/FK—or absence thereof.

Schema truth comes only from declared constraints; plausible real-world rules are not enforced unless encoded.

LearningLab08_en.pdf · Tasks 1, 2.1–2.5, 3

relations + alteration SQL

Answers

1. Use the Lecture relations in Learning Lab 05 above; the supplied LearningLab08.sql creates all nine tables with PK/FK constraints in schema lectureschema. The composite keys make semester-specific attendance/teaching/exam/placement facts unique and BCNF under the intended determinants.

-- 2.1 split name safely (populate before dropping old)
ALTER TABLE lm_student ADD COLUMN st_firstname varchar(50);
ALTER TABLE lm_student ADD COLUMN st_lastname varchar(50);
-- UPDATE with a reviewed parsing rule; names are not reliably split by first space.
ALTER TABLE lm_student DROP COLUMN st_name;

-- 2.2–2.3
ALTER TABLE lm_lecture ADD UNIQUE(le_title);
ALTER TABLE lm_examines ALTER COLUMN ex_grade SET NOT NULL;

-- 2.4 remove references, then room
ALTER TABLE lm_professor DROP COLUMN pr_room;
ALTER TABLE lm_takes_place DROP COLUMN tp_room;
DROP TABLE lm_room;

-- 2.5
CREATE TABLE lm_assistant(
 assistantnumber integer PRIMARY KEY,
 firstname varchar(50),lastname varchar(50),
 professor integer NOT NULL REFERENCES lm_professor(pr_number));

3 shopping tables.

CREATE TABLE customer(customer_id integer PRIMARY KEY,company varchar(120));
CREATE TABLE article(article_id integer PRIMARY KEY,name varchar(120));
CREATE TABLE purchase(
 customer_id integer REFERENCES customer,
 article_id integer REFERENCES article,
 bought_at timestamp,quantity integer CHECK(quantity>0),
 unit_price numeric(10,2) CHECK(unit_price>=0),
 PRIMARY KEY(customer_id,article_id,bought_at));
CREATE TABLE newsletter(
 newsletter_id integer PRIMARY KEY,topic varchar(120),publish_date date,name varchar(120));
CREATE TABLE subscription(
 customer_id integer REFERENCES customer,
 newsletter_id integer REFERENCES newsletter,
 PRIMARY KEY(customer_id,newsletter_id));

Check

Adding NOT NULL fails if current grades contain NULL; inspect and repair first. DROP … CASCADE is shorter but hides what is removed, so explicit dependent-column removal is safer for an exam explanation. Name parsing needs a domain rule or manual review.

ALTER order Add → populate/validate → constrain → drop old. For deletion, remove FK dependencies before the referenced table.

Safe migration: add new structure, populate, validate, constrain, then remove old structure.

6 · Data manipulation and selection

HomeWork08_en.pdf · Tasks 1, 2.1–2.2, 3.1–3.2

complete answer

Answers

1. The W3Schools quiz is an external ungraded practice activity and has no stable written result; it is safe to skip after source-aligned SQL drills. 2.1–2.2 and 3.1–3.2: all INSERT, UPDATE, six corrected SELECT statements, explanations, and verified result rows appear in Chapter 5 under “Homework 08.”

Corrections retained

Use scheduled dates for “planned,” DISTINCT for unique cities/models, return the requested duration, check layover order, and express “no Boeing event” with correlated NOT EXISTS. The supplied solution misses or mis-scopes each of these points.

Paper check Annotate every timestamp as scheduled or actual before writing the query.

Temporal query: match the prompt’s clock (scheduled/actual), event (departure/arrival), date, and ordering.

LearningLab09_en.pdf · Tasks 1.1–1.4, 2.1–2.3

complete AdventureWorks SQL

Answers

SET search_path TO sales;

-- 1.1 Customers
SELECT COUNT(*) FROM customer;
SELECT territoryid,COUNT(*) FROM customer
GROUP BY territoryid ORDER BY COUNT(*) DESC;
SELECT * FROM customer WHERE territoryid IS DISTINCT FROM 1;
SELECT customerid FROM customer
GROUP BY customerid
HAVING COUNT(DISTINCT territoryid)>1;
-- no rows are possible if customerid is the table PK and one row has one territoryid

-- 1.2 Territory
SELECT * FROM salesterritory;
SELECT name FROM salesterritory
WHERE countryregioncode='US' ORDER BY name;

-- 1.3 SalesOrderHeader
SELECT onlineorderflag,COUNT(*) AS orders
FROM salesorderheader GROUP BY onlineorderflag;
SELECT orderdate::date AS day,COUNT(*) AS orders
FROM salesorderheader GROUP BY orderdate::date
HAVING COUNT(*)>100 ORDER BY day;
-- inspect returned dates for month-/quarter-end or promotion patterns

-- 1.4 SalesOrderDetail
SELECT productid,COUNT(DISTINCT salesorderid) AS orders
FROM salesorderdetail GROUP BY productid ORDER BY orders DESC;
SELECT productid,SUM(orderqty) AS units
FROM salesorderdetail GROUP BY productid ORDER BY units DESC;
SELECT productid,SUM(orderqty*unitprice) AS revenue
FROM salesorderdetail GROUP BY productid ORDER BY revenue DESC;
SELECT SUM(orderqty*unitprice) AS total_revenue
FROM salesorderdetail;

-- 2.1 Customers
SELECT DISTINCT h.customerid,t.name AS territory
FROM salesorderheader h
JOIN salesterritory t ON t.territoryid=h.territoryid
WHERE h.orderdate::date=DATE '2012-05-01';

SELECT h.customerid,SUM(d.orderqty) AS units
FROM salesorderheader h JOIN salesorderdetail d USING(salesorderid)
WHERE d.productid=729 GROUP BY h.customerid;

SELECT DISTINCT h.customerid
FROM salesorderheader h
JOIN salesterritory t ON t.territoryid=h.territoryid
WHERE h.orderdate>=DATE '2011-10-01'
  AND h.orderdate<DATE '2012-01-01'
  AND t.countryregioncode='DE';

SELECT h.customerid,SUM(d.orderqty*d.unitprice) AS revenue
FROM salesorderheader h JOIN salesorderdetail d USING(salesorderid)
GROUP BY h.customerid ORDER BY revenue DESC LIMIT 10;

-- 2.2 Product
SELECT d.productid,SUM(d.orderqty*d.unitprice) AS revenue
FROM salesorderheader h JOIN salesorderdetail d USING(salesorderid)
WHERE h.orderdate>=DATE '2011-08-01'
  AND h.orderdate<DATE '2011-09-01'
GROUP BY d.productid ORDER BY revenue DESC;

-- 2.3 Sales: corrected territory join
SELECT t.name AS territory,r.name AS salesreason,
       SUM(d.orderqty*d.unitprice) AS revenue
FROM salesterritory t
JOIN salesorderheader h ON h.territoryid=t.territoryid
JOIN salesorderdetail d USING(salesorderid)
JOIN salesorderheadersalesreason hr USING(salesorderid)
JOIN salesreason r USING(salesreasonid)
GROUP BY t.territoryid,t.name,r.salesreasonid,r.name
ORDER BY t.name,r.name;

Corrections and checks

  • IS DISTINCT FROM 1 includes customers whose territory is NULL; !=1 does not.
  • One grouped online/offline query gives labelled rows. The supplied UNION can merge equal counts and does not label which is which.
  • Use half-open date ranges (>= start AND < next period) so timestamps on the last day are included.
  • The supplied 2.3 predicate soh.territoryid=soh.territoryid is always true and creates a Cartesian multiplication. The correct join is Header.territoryid = Territory.territoryid.
Dataset note Adventureworks.zip was visually/inventory inspected and contains install.sql plus CSV data. PostgreSQL was not available locally, so these statements were schema-checked against the supplied solution/data definitions but live result counts are not claimed.

Join audit: every JOIN needs a predicate connecting left to right; reject self-equalities such as h.territoryid=h.territoryid.

7 · Exam preparation sets

LearningLabWrapUp.pdf · Tasks 1–5.3

all parts completed above

Answer map

1 ER: Chapter 1 visual and answer. 2 relational model + normalization: Drill Lab 2 maps the model, states all semantic FDs and keys, and proves every corrected relation BCNF; Chapter 2 gives the relation lines. 3 DDL: Chapter 2 complete five-table SQL. 4 population: Chapter 2 all 3 hotels, 4 types, 10 rooms, 10 guests, and 12 bookings. 5.1–5.3: Drill Lab 5 pairs relational algebra with SQL for every subpart and checks the results; Chapter 5 repeats the final SQL set.

Discrepancies handled

Booking PK includes start date; ZIP is character; BETWEEN is inclusive; all-hotels count uses LEFT JOIN. These changes are explicitly documented at the point of use.

Practice This is the closest supplied item to an integrated mock. Attempt it in one uninterrupted block before consulting Chapters 1, 2, and 5.

Integrated order: ER → relations → constraints → normalized inserts → queries → output checks.

LearningLabAdditionalExercise_en.pdf · Tasks 1–4.3

all parts completed above

Answer map

1 import: execute OrderDatabase.sql into lecture; it creates schema ecommerce and ec_order. 2.1–2.3: Chapter 3 gives corrected FDs, key, five 3NF tables, all copy statements, and source drop order. 3: Chapter 3 verifies existing unit prices 8.56–988.01, then adds a BETWEEN 0 AND 10000 CHECK without dropping data. 4.1–4.3: Chapter 5 gives all eight query answers plus verified facts from 1,280 rows.

Discrepancies handled

Quantity depends on (order,item), customer load includes city, and “never A” uses NOT EXISTS rather than NULL-sensitive NOT IN.

Practice First write only relation names/keys/FKs. Then fill attributes and SQL. This prevents getting lost in the wide original row.

Wide-table normalization: mark determinants above columns, draw one table per determinant, keep pair-specific facts in the bridge.

S

Evidence, provenance, and honest limits

This appendix explains what supports the priorities and where uncertainty remains.

Priority basis

Highest: Prof. Scholz’s 22 July briefing, the official exam plan, and the final-exam slide. Focus evidence: learning labs and homework, with the Wrap-Up as the strongest local match for the unnamed mock-equivalent iLearn lab. Scope: all semester material remains relevant. No past exams were present, so this book never claims “N of M past exams.”

Verification performed

Every page of every supplied PDF was rendered and visually reviewed. Numerical closures, storage calculations, hotel totals, airline results, and the full order dataset were independently recomputed. Supplied solutions were treated as fallible evidence.

Exact remaining limitationsNo syllabus, past-exam paper/cover, point structure, grading rubric, or pass threshold was supplied. The 22 July briefing does not identify the mock-equivalent iLearn lab by title; the Wrap-Up identification is a transparent inference from the local course structure. PostgreSQL was not installed in the workspace, so PostgreSQL-specific DDL was checked semantically and against official documentation/source schemas rather than executed on a live server. AdventureWorks result counts are therefore not asserted. External game/quiz activities require user interaction and have no stable written answer.

Source traceability

The table maps every supplied course artifact to its learner-facing use. “Supplied solution, checked” means it informed the answer but was not trusted without comparison.

SourcePagesRoleUsed in
1-Introduction/01_Introduction.pdf40lecture/scope sourceCh. 6 capacity/DBMS; Atlas §1
1-Introduction/HomeWork01_en.pdf1exercise/data sourceCh. 6 capacity/DBMS; Atlas §1
1-Introduction/LearningLab01_en.pdf3exercise/data sourceCh. 6 capacity/DBMS; Atlas §1
1-Introduction/New-Features-of-PostgreSQL-18.txtlecture/scope sourceCh. 6 capacity/DBMS; Atlas §1
1-Introduction/SolutionHomeWork01.pdf2supplied solution, checkedCh. 6 capacity/DBMS; Atlas §1
2-Architecture-of-RDBMS/02_Architecture.pdf57lecture/scope sourceCh. 6 architecture/WAL; Atlas §2
2-Architecture-of-RDBMS/Homework_Architecture-of-RDBMS/HomeWork02_en.pdf1exercise/data sourceCh. 6 architecture/WAL; Atlas §2
2-Architecture-of-RDBMS/Learning-Lab_PostgreSQL-Basics/CreateMessengerTables.sqlexercise/data sourceCh. 6 architecture/WAL; Atlas §2
2-Architecture-of-RDBMS/Learning-Lab_PostgreSQL-Basics/LearningLab02_en_.pdf3exercise/data sourceCh. 6 architecture/WAL; Atlas §2
2-Architecture-of-RDBMS/Learning-Lab_PostgreSQL-Basics/MessengerData.sqlexercise/data sourceCh. 6 architecture/WAL; Atlas §2
3-Relational-Design/03_Design.pdf60lecture/scope sourceCh. 1 ER; Atlas §3
3-Relational-Design/Homework_ER-model/HomeWork03.pdf1exercise/data sourceCh. 1 ER; Atlas §3
3-Relational-Design/Homework_ER-model/SolutionHomeWork03.pdf2supplied solution, checkedCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Model/LearningLab03.pdf2exercise/data sourceCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Model/SolutionLearningLab03.pdf3supplied solution, checkedCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Modelling-with-PostgreSQL/LearningLab04.pdf2exercise/data sourceCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Modelling-with-PostgreSQL/lecturemanager.pgerdexercise/data sourceCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Modelling-with-PostgreSQL/lecturemanager.sqlexercise/data sourceCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Modelling-with-PostgreSQL/moviemanager_extended.pgerdexercise/data sourceCh. 1 ER; Atlas §3
3-Relational-Design/Learning-Lab_ER-Modelling-with-PostgreSQL/moviemanger_extended.sqlexercise/data sourceCh. 1 ER; Atlas §3
4-Relational-Model/04_RelationalModel.pdf68lecture/scope sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Homework_Relational-Algebra/HomeWork05_en.pdf1exercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Homework_Relational-Algebra/RelaX_HomeWork05.txtexercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Homework_Relational-Algebra/RelaX_Lecture.txtexercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Homework_Relational-Model/HomeWork04_en.pdf2exercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Homework_Relational-Model/SolutionHomeWork04.pdf3supplied solution, checkedCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Learning-Lab_Relational-Algebra/LearningLab06.pdf6exercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Learning-Lab_Relational-Algebra/RelaX_IMDB_sample.txtexercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Learning-Lab_Relational-Algebra/RelaX_Solution.txtsupplied solution, checkedCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Learning-Lab_Relational-Algebra/SolutionLearningLab06.pdf7supplied solution, checkedCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Learning-Lab_Relational-Model/LearningLab05.pdf2exercise/data sourceCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/Learning-Lab_Relational-Model/SolutionLearningLab05.pdf6supplied solution, checkedCh. 2/4 mappings & RA; Atlas §4
4-Relational-Model/ReLaX.txtlecture/scope sourceCh. 2/4 mappings & RA; Atlas §4
5-Data-Definition-Language_SQL/05_DataDefinition.pdf58lecture/scope sourceCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Homework_Creating-Tables/HomeWork07_en.pdf3exercise/data sourceCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Homework_Creating-Tables/SolutionHomeWork07.pdf4supplied solution, checkedCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Homework_Normalization/HomeWork06_en.pdf2exercise/data sourceCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Homework_Normalization/SolutionHomeWork06.pdf6supplied solution, checkedCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Learning-Lab_Creating-Relations/LearningLab08.sqlexercise/data sourceCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Learning-Lab_Creating-Relations/LearningLab08_en.pdf2exercise/data sourceCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Learning-Lab_Normalization/LearningLab07_en.pdf3exercise/data sourceCh. 2/3 DDL & normalization; Atlas §5
5-Data-Definition-Language_SQL/Learning-Lab_Normalization/SolutionLearningLab07.pdf6supplied solution, checkedCh. 2/3 DDL & normalization; Atlas §5
6-Data-Manipulation-and-Selection-Language_SQL/06_DataManipulation.pdf57lecture/scope sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/Homework_Data-Manipulation-and-Selection/CreatingAirlineTables.sqlexercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/Homework_Data-Manipulation-and-Selection/HomeWork08_en.pdf2exercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/Homework_Data-Manipulation-and-Selection/SolutionHomeWork08.pdf2supplied solution, checkedCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/Learning-Lab_SQL-Queries/Adventureworks.zipexercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/Learning-Lab_SQL-Queries/LearningLab09_en.pdf2exercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/Learning-Lab_SQL-Queries/SolutionLearningLab09.pdf4supplied solution, checkedCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/SQL-Island.txtlecture/scope sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/SQL-Scripts/CreateViewAndTrigger.sqlexercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/SQL-Scripts/DataDefinition_Sales.sqlexercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/SQL-Scripts/DataInsert_Sales.sqlexercise/data sourceCh. 5 SQL; Atlas §6
6-Data-Manipulation-and-Selection-Language_SQL/SQL-Scripts/DataManipulation_en.sqlexercise/data sourceCh. 5 SQL; Atlas §6
7-Exam-Preparation/Learning-Lab_Additional-Exercises/LearningLabAdditionalExercise_en.pdf2exercise/data sourceCore worked examples and rehearsal
7-Exam-Preparation/Learning-Lab_Additional-Exercises/OrderDatabase.sqlexercise/data sourceCore worked examples and rehearsal
7-Exam-Preparation/Learning-Lab_Additional-Exercises/SolutionLearningLabAdditionalExercise.pdf5supplied solution, checkedCore worked examples and rehearsal
7-Exam-Preparation/Learning-Lab_Wrap-Up/LearningLabWrapUp.pdf3exercise/data sourceCore worked examples and rehearsal
7-Exam-Preparation/Learning-Lab_Wrap-Up/SolutionLearningLabWrapUp.pdf6supplied solution, checkedCore worked examples and rehearsal

Correction register you should remember

Supplied locationIssueCorrect exam move
Wrap-Up booking DDLPK(room,guest) forbids repeat dates.Add start_date to PK.
Wrap-Up refined modelZIP labelled integer.Use character/varchar.
Wrap-Up hotel countInner join omits zero visits.LEFT JOIN and COUNT(child key).
Additional FDsitem_id→quantity is false.(order_id,item_id)→quantity.
Additional customer loadCity omitted from 8-column INSERT.Select or_city too.
Homework 07 Task 1.2Supplied answer omits CREATE SCHEMA and schema qualification.Connect to lecture; create invoiceschema; create invoiceschema.customer and invoiceschema.invoice.
Homework 07 airport CHECKLexical range is not a reliable starts-with-letter test.Regex ~ '^[A-Za-z]'.
Homework 08 routesActual times, omitted DISTINCT/duration, broken anti-join.Use scheduled event semantics and NOT EXISTS.
Learning Lab 09 salesAlways-true territory self-join.h.territoryid=t.territoryid.