James Gillespie's High School · Higher Computing Science 2026–27
Completed:
📁 File in OneNote: Higher Computing Science → Database Design & Development → DDD4
Answer before the lesson begins — it's fine if you're unsure.
DDD2 introduced the primary key (the attribute that uniquely identifies a record, underlined on an ER diagram) and the foreign key (an attribute linking to another entity's primary key, marked with an asterisk). Every entity in the Craigmillar Community Sports Club database uses a single-attribute primary key so far: memberID, classCode, instructorRef, and bookingRef. This lesson introduces a third kind of key — one made from more than one attribute at once.
A compound key is a primary key made up of two or more attributes combined, used when no single attribute on its own is guaranteed to be unique, but the combination of two attributes together is. This typically happens in a resolving entity — a table that exists to link two other entities — where neither foreign key alone identifies a unique record, but the pair of them together might.
To see a genuine compound key in action, this section uses a small, separate example: a college's StudentModule entity, recording which students are enrolled on which modules, where the college's rule is that a student can only enrol on a given module once. Neither studentID alone (one student enrols on many modules) nor moduleCode alone (one module has many students) is unique by itself — but the combination of a specific student and a specific module is unique, because the rule guarantees no repeats. That combination, studentID + moduleCode, is the compound key.
It's natural to ask why Booking — which also links two entities, Member and Class — doesn't use memberID + classCode as a compound key the same way. The difference is the underlying rule: a sports club member is generally allowed to book the same class more than once (rejoining after a cancellation, booking a repeating weekly slot across several separate transactions). That means the combination of memberID and classCode is not guaranteed to be unique for Booking, the way studentID + moduleCode is for StudentModule. This is exactly why Booking has its own single-attribute primary key, bookingRef, instead — a compound key only works when the combination itself is genuinely always unique, and here it isn't.
A data dictionary is a table that documents every attribute of every entity in a database, in one place, before any table is actually built. For each attribute it records: which entity it belongs to, its name, whether it's a primary key (PK) or foreign key (FK), its data type, and its field size. The Higher course requires a data dictionary covering three or more entities — the sports club's four-entity database comfortably meets this.
Every attribute needs one of five data types: text (names, codes, addresses — anything alphanumeric), number (values used in calculations, like capacity or feePerSession), date (calendar dates, like dateJoined), time (clock times, like startTime), or Boolean (true/false values, like qualified or attended). Choosing the right type matters for both storage and validation — DDD5 builds directly on the data dictionary's type column when it adds validation rules.
Text attributes need a maximum field size stated in characters — large enough for realistic data, but not wastefully large. postcode might be sized at 8 characters (covering the longest realistic UK postcode with a space), while surname might be sized at 25. Number, date, time, and Boolean attributes don't need a character-count field size the way text does, so their field size column is often left blank or marked "n/a".
You may remember referential integrity from National 5: the rule that a foreign key value must always exist as a primary key value in its own table — for example, a Booking record's memberID must match a memberID that genuinely exists in Member. This is useful revision, but referential integrity is not part of the Higher DDD content statement and won't appear in an auto-checked question in this course — it's included here purely as a reminder of the underlying reason foreign keys work the way they do.
StudentModule, recording enrolments. Rule: a student can enrol on a given module only once.studentID alone: not unique, since one student enrols on several modules.moduleCode alone: not unique either, since one module has several students.studentID + moduleCode together is unique, because the rule rules out repeats. This is the compound key.Both studentID and moduleCode are underlined together — that's how a compound key is shown, as opposed to a single underlined attribute.
memberID, firstName, surname, address, town, postcode, dateJoined.memberID as the primary key (PK); none of Member's other attributes are foreign keys.dateJoined, which is a date.| Entity | Attribute | PK/FK | Data type | Field size |
|---|---|---|---|---|
| Member | memberID | PK | Text | 6 |
| Member | firstName | — | Text | 20 |
| Member | surname | — | Text | 25 |
| Member | address | — | Text | 40 |
| Member | town | — | Text | 20 |
| Member | postcode | — | Text | 8 |
| Member | dateJoined | — | Date | n/a |
bookingRef, memberID, classCode, bookingDate, attended.bookingRef as PK, and both memberID and classCode as FK — matching the entity box's asterisks from DDD2.bookingDate, Boolean for attended.| Entity | Attribute | PK/FK | Data type | Field size |
|---|---|---|---|---|
| Booking | bookingRef | PK | Text | 8 |
| Booking | memberID | FK | Text | 6 |
| Booking | classCode | FK | Text | 6 |
| Booking | bookingDate | — | Date | n/a |
| Booking | attended | — | Boolean | n/a |
Instructor's entity box (DDD2) lists: instructorRef (PK), firstName, surname, qualified. Build its data dictionary row-by-row: state a sensible data type and field size for each attribute.
| Entity | Attribute | PK/FK | Data type | Field size |
|---|---|---|---|---|
| Instructor | instructorRef | PK | Text | 6 |
| Instructor | firstName | — | Text | 20 |
| Instructor | surname | — | Text | 25 |
| Instructor | qualified | — | Boolean | n/a |
When asked to "exemplify" a data dictionary, produce an actual table with real column headers (entity, attribute, PK/FK, data type, field size) and real rows filled in for at least three entities — not just a description of what a data dictionary contains. State field sizes as specific numbers, not vague terms like "short" or "long".
qualified (in Instructor) be given?startTime (in Class) be given?postcode be stored as text rather than number, even though it looks numeric?📁 File this in OneNote under:
Higher Computing Science → Database Design & Development → DDD4
Suggested timing: 8 min warm up · 15 min notes (compound keys & data dictionary theory) · 15 min worked examples · 5 min now you try · 20 min Task Set B · 5–10 min Task Set C / review, if time allows.
Key misconception: pupils often assume any resolving/linking entity automatically needs a compound key. Booking is the deliberate counter-example in this lesson — model the "check whether the combination is genuinely unique" test explicitly, rather than pattern-matching "linking entity = compound key".
Referential integrity note: this is N5 revision only, kept to the info box — do not build an auto-checked question around it, since it is confirmed absent from the Higher DDD content statement (see ddd/DDD.md §1 and §9).
SQA command words covered: "exemplify" (produce an actual data dictionary table with real values — see the exam tip box), "describe".
Extension suggestion: pupils who finish Task Set C early could attempt the full data dictionary for all four sports club entities from memory, then check every row against DDD2's entity boxes.