Taking the Spreadsheet Row Apart

We have decided to use a relational database. The next question is which tables to build. A good place to start is the spreadsheet, because it already holds the facts we care about. It just holds them in the wrong shape.

Here is one row from the course history we saw earlier, written out one fact per line:

Term:                Fall 2026
Course number:       EN.601.226
Course title:        Data Structures
Credits:             4
Professor:           Ali Madooei
Professor email:     madooei@jhu.edu
Meeting time:        Mon/Wed/Fri 10:00
Room:                Hackerman B17
Subject area:        Computer science
Degree requirement:  CS core

Ten facts in one row. They look alike because they sit side by side, but they are not facts about the same thing.

Here is a test that separates them. Suppose the department offers Data Structures again the following year, with a different professor, in a different room. Which of these facts change, and which stay the same?

The course number does not change. The title does not change. The credits do not change. The subject area does not change. These are facts about the course itself, and they are true of EN.601.226 no matter who teaches it or when it runs.

The term changes. The professor changes. The meeting time changes. The room changes. These are facts about one particular offering of that course.

The spreadsheet cannot keep these two kinds of fact apart. It has one row for each course a student took, so that row has to carry both kinds at once. A relational database can keep them apart, by giving each kind of thing its own table.

Here is a table for courses:

Course number Title Credits Subject area
EN.500.112 Gateway Computing: JAVA 3 Computer science
EN.601.220 Intermediate Programming 4 Computer science
EN.601.226 Data Structures 4 Computer science
EN.601.229 Computer System Fundamentals 3 Computer science

Now apply the same test to the professor. Suppose a professor changes their email address. One of the requirements says that an administrator must be able to update a professor’s name or email address. If the email sits in the row for every offering, then changing it means finding every offering that professor has ever taught and editing each one. Miss a single row and the record disagrees with itself. The name and the email are facts about the professor, not about the offering, so the professor gets a table as well:

Name Email
Sara More more@cs.jhu.edu
Joanne Selinski joanne@cs.jhu.edu
Ali Madooei madooei@jhu.edu
David Hovemeyer daveho@cs.jhu.edu

That leaves the facts that really do belong to a single offering:

Term Meeting time Room
Fall 2025 Mon/Wed/Fri 10:00 Croft B32
Spring 2026 Tue/Thu 13:00 Maryland 309
Fall 2026 Mon/Wed/Fri 10:00 Hackerman B17
Spring 2027 Tue/Thu 14:00 Hodson 210

Read that last table on its own and you will see that something is missing. The third row says that something meets on Monday, Wednesday and Friday at ten in Hackerman B17 during Fall 2026. It does not say that the something is Data Structures. It does not say who teaches it. The two facts that tied this row to the rest of the record were the ones we just moved out.

Two things from the original row are still unplaced.

The degree requirement belongs with the course rather than with the offering, since EN.601.226 counts toward the same requirements whoever teaches it. But we saw earlier that one course can count toward several requirements, and we still do not have a way to write that down. We will come back to it.

The student is the other one. A history entry records that a particular student took a particular offering. That is the whole point of the application, and it has the same gap the offerings table has. There is no way yet for the entry to say which offering it means.

Splitting the row bought us something real. The title of Data Structures is written once instead of once per student. A professor’s email is written once instead of once per offering. When a room changes, one row changes, and every student sees the new room. That is the promise from the previous section, carried out.

It also cost us something. Facts that used to sit together in one row are now spread across several tables, and so far nothing says how they go back together. We know what we want. The offering row should point at its course and at its professor, and a history entry should point at its offering. We called that a link earlier, and we have been using the word without ever saying what a link is made of.

So that is the next question. How does a row in one table say which row in another table it means?