Database Design & Development · Design

DDD4 — Compound keys and data dictionaries

📅 Thu 22 Oct 2026
~100–110 minutes · double period
Learning intentions
Success criteria
Warm up — what do you already know?

Answer before the lesson begins — it's fine if you're unsure.

WU1
1. On an ER diagram, a primary key is shown ___, and a foreign key is marked with an ___.
WU2
2. Which entity in the Craigmillar Community Sports Club database is the resolving entity for the many-to-many relationship between Member and Class?
WU3
3. National 5 recap: what is a field called if it uniquely identifies each record in a table?

Key vocabulary

Primary key
The attribute (or combination of attributes) that uniquely identifies each record in an entity.
Foreign key
An attribute that links to the primary key of another entity, marked with an asterisk.
Compound key
A primary key made up of two or more attributes together, used when no single attribute alone is unique.
Data dictionary
A table documenting every attribute of every entity: its name, whether it's a PK/FK, its data type, and its field size.
Data type
The kind of value an attribute stores — text, number, date, time, or Boolean.
Field size
The maximum length or precision of an attribute's value — for example, a text field's maximum character count.

Compound keys and data dictionaries

Recap: primary and foreign keys

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.

What is a compound key?

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.

Worked example scenario — Student enrolment on Modules

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.

Why doesn't Booking use a 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.

What is a data dictionary?

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.

Choosing a data type

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.

Choosing a field size

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".

National 5 recap — referential integrity

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.

Primary key memberID Uniquely identifies each record alone. Shown: underlined Foreign key memberID * Links to the primary key of another entity. Shown: marked with * Compound key studentID * moduleCode * Two+ attributes together are unique; neither alone is. Shown: purple dotted underlines
A solid orange underline marks a normal single-attribute primary key. This course uses a purple dotted underline on every oval that belongs to one compound key, so the shared key is visually distinct; this extra compound-key style is a course convention, not a form shown in SQA Appendix 9. An attribute that is also a foreign key still keeps its asterisk, as both StudentModule key attributes do here.

Worked examples

Example 1 — Identifying a compound key
1
Entity: StudentModule, recording enrolments. Rule: a student can enrol on a given module only once.
2
Check studentID alone: not unique, since one student enrols on several modules.
3
Check moduleCode alone: not unique either, since one module has several students.
Check the combination: studentID + moduleCode together is unique, because the rule rules out repeats. This is the compound key.
StudentModule compound-key entity diagram The studentID and moduleCode attribute ovals both have asterisks because they are foreign keys, and both have this course's purple dotted compound-key underline because together they form one primary key. enrolmentDate is unmarked. StudentModule studentID * moduleCode * enrolmentDate
↔ Scroll horizontally if needed. The two purple dotted underlines mark studentID and moduleCode as parts of the same compound primary key; they do not mean two separate primary keys. The asterisk on each name remains because each attribute is also a foreign key. The purple dotted underline is this course's convention for making a compound key visually distinct, not a form shown in SQA Appendix 9.
Example 2 — Building the data dictionary for Member
1
List every attribute shown in the connected ovals around Member in DDD2's ER diagram: memberID, firstName, surname, address, town, postcode, dateJoined.
2
Mark memberID as the primary key (PK); none of Member's other attributes are foreign keys.
3
Assign a data type to each: all text, except dateJoined, which is a date.
Assign a field size to each text attribute, sized realistically for the data. See the table below.
EntityAttributePK/FKData typeField size
MembermemberIDPKText6
MemberfirstNameText20
MembersurnameText25
MemberaddressText40
MembertownText20
MemberpostcodeText8
MemberdateJoinedDaten/a
Example 3 — Building the data dictionary for Booking
1
List every attribute shown in Booking's connected ovals: bookingRef, memberID, classCode, bookingDate, attended.
2
Mark bookingRef as PK, and both memberID and classCode as FK — matching the asterisks in DDD2's Booking attribute ovals.
3
Assign data types: text for the three key fields, date for bookingDate, Boolean for attended.
Boolean and date attributes don't need a character-based field size — see the table below.
EntityAttributePK/FKData typeField size
BookingbookingRefPKText8
BookingmemberIDFKText6
BookingclassCodeFKText6
BookingbookingDateDaten/a
BookingattendedBooleann/a
Now you try

DDD2's Instructor diagram shows these connected attribute ovals: instructorRef (PK), firstName, surname, qualified. Build its data dictionary row-by-row: state a sensible data type and field size for each attribute.

EntityAttributePK/FKData typeField size
InstructorinstructorRefPKText6
InstructorfirstNameText20
InstructorsurnameText25
InstructorqualifiedBooleann/a
⚠️ Common mistakes — examiner feedback
📝 Exam tip

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".

Task Set B — Core questions
Work through all questions. Written answers use self-assessment — compare with the model answer.
B1
A primary key made up of two or more attributes combined is called a ___ key.
B2
Why doesn't Booking use a compound key of memberID + classCode?
B3
Name the five data types in the order shown in the “Choosing a data type” paragraph above. Use lowercase and separate each item with a comma followed by one space.
B4
What data type should the attribute qualified (in Instructor) be given?
B5
What data type should startTime (in Class) be given?
B6
Build the full data dictionary row-by-row for the Class entity (classCode, className, instructorRef, dayOfWeek, startTime, capacity, feePerSession), stating PK/FK, data type, and field size for each.
Model answer
B7
Why should postcode be stored as text rather than number, even though it looks numeric?
B8
In the StudentModule example, which two attributes form the compound key? Write both names in either order, joined by a plus sign.
B9
Explain what a data dictionary is and why it's produced at the design stage, before any database table is actually built.
Model answer
Task Set C — Extension · Beyond the specification
Optional challenge questions. Not required for your exam.
C1
If the club's booking rules changed so a member could only ever book a given class once (no repeat bookings), would Booking's primary key design need to change? Explain.
One possible answer
C2
feePerSession stores a currency value (e.g. £6.50). Is "Number" alone a complete enough data type for it, or does it need something extra specified? Explain.
One possible answer
C3
A proposed ClubSession entity has classCode, sessionDate, startTime, and attendanceTotal. The rule is that the same class can run only once at any particular date and start time. Decide whether classCode + sessionDate + startTime is a suitable compound key, explain why, and state how it would be marked across the three connected attribute ovals.
One possible answer

📁 File this in OneNote under:
Higher Computing Science → Database Design & Development → DDD4

📌 Teacher notes — Shift+T to hide

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 ER diagram and its connected attribute ovals.