← AS/A Level

CS · Chapter 11

Cambridge AS & A Level · Part 1 · Chapter 11

Databases

Why a file of text lines falls apart, how a relational database fixes it, and how to design, normalise and query one. Every figure, question, task and exam question from the chapter is here, plus a working SQL playground loaded with the book's theatrical-agency database.

Guru Jazzy
Chapter 11 opener: linked tables of data spread across the world

🎯 Learning objectives

By the end of this chapter you should be able to:

  • show understanding of the limitations of a file-based approach to storing and retrieving data
  • describe the features of a relational database that address those limitations
  • use the terminology of the relational model
  • use an entity–relationship (E–R) diagram to document a design
  • show understanding of the normalisation process
  • explain why a set of tables is, or is not, in 3NF
  • produce a normalised design from a description, a set of data or a set of tables
  • show understanding of the features a DBMS provides to solve the problems of a file-based approach
  • show how the software tools in a DBMS are used in practice
  • know that the DBMS creates and modifies the structure using its DDL, and queries and maintains data using its DML
  • know that the industry standard for both is SQL
  • understand given SQL DDL and write simple DDL commands
  • write an SQL script to query or modify data stored in at most two tables

📄 11.01 Limitations of a file-based approach

Data integrity problems in a single file

A theatrical agency books bands and wants a computerised system built from text files. One file holds a line per band member: name, contact details, banking details, band name, band agent name and agent contact details. The agency uses it to contact members (directly or through the agent) and to pay them after a gig.

Here is a snapshot of just three fields (given name, family name, band name) from a file that might have a thousand lines or more:

XiangfeiJhaComputerKidz
MaheshRavuruITWizz
DylanStoddart
GrahamVandanaITWizz
VandanaGrahamITWizz
MaheshRavuruITWizz
PreciousOlsenComputerKidz
PreciousOlsenITWizz
  • Vandana Graham was first typed with her names in the wrong order. A correct line was added later, but the wrong one was never deleted. No validation check could have spotted the original mistake.
  • Dylan Stoddart has no band name. Validation (a presence check) should have caught that.
  • Precious Olsen appears twice with different bands: duplicated and inconsistent data.
  • An error you cannot see: a band name could be typed for a band that does not exist.

The cause is the lack of built-in control when data is entered. A database can prevent these problems, or at least make them much less likely.

🔎 Lab: diagnose the file

What is wrong with each line? (Some lines are fine on their own.)

The data privacy issue with a single file

The one file was designed so that the finance section could find banking details and the recruitment section could find contact details. But you cannot control access to part of a file, so recruitment staff can also read members' banking details. A database system handles data privacy properly.

Data redundancy and possible inconsistency in multiple files

To fix privacy, the agency gives each department its own file (Table 11.01):

Table 11.01 Data to be held in the department files
DepartmentMember namesBank detailsBand nameGig detailsAgent details
Contract✔✔✔
Finance✔✔✔
Publicity✔✔
Recruitment✔✔✔

Table 11.01 Data to be held in the department files

Now the same data sits in several files: data redundancy. The data is still useful; the point is that once stored it should not need storing again. In a file-based system redundancy cannot be avoided, and it leads to inconsistency, from mistakes in the original entry or in later edits to one copy but not another. Removing data redundancy is one of the main aims of the database approach.

Data redundancy: the same data stored more than once.

Data dependency concerns

Traditionally a programmer wrote a program and defined the files it used. Each department has its own programs, and each programmer must know exactly how the data is laid out ("the fourth item on a line is the band name"). That is data dependency: the programs depend on the file structure.

  • Departments' files probably share data, but nothing is planned for sharing files.
  • If the data changes (say, bands start using extra session musicians), the files must be rewritten, so every program that reads them must be rewritten too. With a database, existing programs keep working; only programs that use the new data need writing.
  • Files designed for specific programs are poor at supporting new applications, such as an information system analysing years of gigs. Extracting that from these files would be slow and complex.

🔑 11.02 The relational database

In the relational model each item of data is stored in a relation, a special kind of table (the name comes from mathematical set theory). A relational database is a collection of relations.

A table is created by giving it a name and then naming its attributes. In a design, the attribute names are listed in brackets after the table name (Figure 11.01):

Member(MemberID, MemberGivenName, MemberFamilyName, BandName, …)
Band(BandName, AgentID, …)

Figure 11.01 Two tables in a database design for the theatrical agency

MemberIDMemberGivenNameMemberFamilyNameBandName…
0005XiangfeiJhaComputerKidz…
0009MaheshRavuruITWizz…
0001DylanStoddartComputerKidz…
0025VandanaGrahamITWizz…

Table 11.02 Logical view of the Member table

BandNameAgentID…
ComputerKidz01…
ITWizz07…

Table 11.03 Logical view of the Band table

Each attribute is a column, and the entries beneath it are attribute values. It is only a logical view: the relational model defines no order for the columns (or rows). Some products let you open a table and look at it, but in true relational spirit you inspect data with a query.

Relation: the special type of table used in a relational database.
Attribute: a column in a relation that contains values.
Tuple: a row in a relation storing data for one instance of the relation.

A row is formally a tuple, though people often say "record" and call the values "fields". In Table 11.02 each tuple is one band member. A tuple is a set of atomic values: each attribute has one value or no value.

🗝️ Keys

The most important idea in the relational model is the primary key: one attribute, or a combination, whose value in every tuple exists and is unique. Every table must have one.

If several attributes are guaranteed unique, each is a candidate key; one is chosen as the primary key and the others become secondary keys. Often there is no candidate key at all, so one is invented, as MemberID was for Member. The primary key is underlined in a design.

The DBMS refuses to insert a primary-key value that already exists, so every tuple is unique, which helps data integrity. The primary key also gives a unique reference to any value a query selects.

Tables are usually related to each other through a foreign key.

Primary key: an attribute or combination of attributes for which there is a value in each tuple and that value is unique.
Candidate key: a key that could be chosen as the primary key.
Secondary key: a candidate key that has not been chosen as the primary key.
Foreign key: an attribute in one table that refers to the primary key in another table.

In Figure 11.01 the Band table is created first, with BandName as its primary key (band names are guaranteed unique). Then Member is created with MemberID as primary key and BandName as a foreign key referencing Band. From then on the DBMS rejects any Member tuple whose BandName is not already in Band. That is referential integrity, another way the relational model protects data integrity.

Referential integrity: the use of a foreign key to ensure that a value can only be entered in one table when the same value already exists in the referenced table.
Question 11.01 BandName is a primary key for the Band table. Does this mean that as a foreign key in the Member table it must have unique values? Explain your reasoning.
Model answer

No. Uniqueness only applies where BandName is the primary key (in Band). In Member, BandName is a foreign key: several members belong to the same band, so the same value appears in many tuples (ITWizz appears twice in Table 11.02). The only rule for a foreign key is that each value must already exist as a primary-key value in Band.

🧪 Lab: the DBMS guards your keys

Try to break the rules. Add a member to a band that doesn't exist, reuse a MemberID, or delete a band that still has members. The DBMS (this page) refuses, just as a real one would.

Band PK BandName
BandNameAgentID
Member PK MemberID FK BandName
MemberIDGivenFamilyBandName

Insert a member

Insert or delete a band

🔗 11.03 Entity–relationship modelling

Database design can use stepwise refinement, a top-down method that breaks the job into simple steps, adding detail at each one (see also Chapter 12, Section 12.08). In database design that means an entity–relationship (E–R) diagram, produced by a database designer or a systems analyst working with one.

An entity (strictly, an entity type) can be a thing, a type of person, an event, a transaction or an organisation. Crucially, it must have a number of instances. An entity is something that will become a table.

Worked example 11.01

Creating an entity–relationship diagram for the theatrical agency

The starting point is a statement of the requirement:

The agency needs a database to handle bookings for bands. Each band has a number of members. Each booking is for a venue. Each booking might be for one or more bands.

Step 1: Choose the entities

Look for the nouns. Ignore "agency" (there is only one). Choose Booking, Band, Member and Venue, each with many instances. Each booking is for a gig, but the Booking entity can hold the gig data.

Step 2: Identify the relationships

This takes experience; aim not to define too many. Choose Booking with Venue, Booking with Band, and Band with Member. A Member–Venue relationship exists too, but it is handled indirectly through the others.

Figure 11.02A preliminary entity–relationship diagram: Member, Band, Booking, Venue

Step 3: Decide the cardinalities

Each line actually defines two relationships, a "forward" one and a "backward" one. Each is described as one of: one-to-one (1:1), one-to-many (1:M), many-to-one (M:1) or many-to-many (M:M).

Member–Band. One member belongs to only one band (the agency must confirm this), and one band has many members, so Member to Band is M:1. The crow's foot sits at the "many" end:

Figure 11.03The M:1 relationship between Member and Band

More detail: a member must belong to a band, and a band must have more than one member:

Figure 11.04The M:1 relationship with more detail: a member must belong to exactly one band; a band has one or more members

Each end now carries two symbols: one for the minimum cardinality and one for the maximum. Here they happen to match. Documenting that a member must belong to a band matters: it means no Member tuple can be created without a valid BandName in Band.

Booking–Venue. One booking is for exactly one venue; one venue can host many bookings, but a venue might never have been booked (the circle means zero):

Figure 11.05The M:1 relationship between Booking and Venue: a venue can have zero bookings

Band–Booking. One booking can be for many bands and one band has many bookings (hopefully!), so this is M:M. A new band may have no booking yet, and a booking may be for just one band:

Figure 11.06The M:M relationship between Band and Booking

Step 4: Create the full E–R diagram

Name each relationship:

Figure 11.07The E–R diagram for the theatrical agency’s booking database

A reading always starts from one entity. Reading Figure 11.08 forwards and then backwards:

One Band is booked for zero or many Bookings.
One Booking is for one or many Bands.

Figure 11.08Part of the annotated E–R diagram

🛠️ Lab: crow's-foot builder

Set the minimum and maximum at each end. The diagram and both reading sentences update, the same way you read Figure 11.08.

Question 11.02 If you are deciding on the cardinality of the relationship between two entities, does it matter which one is put on the left and which one on the right?
Model answer

Not for the relationship itself, but it does change how you describe it. Member–Band drawn with Member on the left is M:1; swap the boxes and the same relationship reads 1:M. What matters is that the symbols stay at the correct ends (the crow's foot at the Member end) and that you read the diagram consistently, starting from one entity.

Tip: Be careful not to confuse the two completely different terms relation (a table) and relationship (a link between entities).

🎮 Name that cardinality

Read the statement and choose the cardinality, left entity to right entity.

🧩 11.04 A logical entity–relationship model

A fully annotated E–R diagram like Figure 11.07 is a conceptual model: it does not depend on any particular way of building the system. To implement it as a relational database, convert it to a logical model, starting from a simplified diagram showing only cardinalities.

  • 1:M needs no further work: the entity at the "many" end gets a foreign key referencing the primary key of the entity at the "one" end.
  • 1:1 has several implementation options, but such relationships are extremely rare and not needed here.
  • M:M is the problem. A foreign key holds a single value, so it cannot hold the many references needed. Or: each table would need a foreign key to the other, so neither could be created first.

The solution is a link entity. For Band and Booking:

Figure 11.09A link entity, Band-Booking, inserted to resolve the M:M relationship
Extension Question 11.01 Is it possible to annotate these relationships?
Model answer

Yes. Band → Band-Booking: one Band appears in zero or many Band-Booking tuples; each Band-Booking tuple is for exactly one Band. Booking → Band-Booking: one Booking appears in one or many Band-Booking tuples (every booking is for at least one band); each Band-Booking tuple is for exactly one Booking. So both new relationships are 1:M with the crow's feet at the link entity, and the minimums carry over from Figure 11.06.

The link entity now holds two foreign keys, one referencing Band and one referencing Booking. Every entity becomes a table, so the keys can be summarised in a key table:

Table namePrimary keyForeign key
MemberMemberIDBandName
BandBandName
Band-BookingBandName & BookingIDBandName, BookingID
BookingBookingIDVenueName
VenueVenueName

Table 11.04 A key table for the agency booking database

Primary keys follow the uniqueness rule. The link entity cannot use BandName or BookingID alone, but the compound primary key of both works.

Task 11.01 An organisation books cruises for passengers. Each cruise visits a number of ports. Create a conceptual E–R diagram and convert it to a logical E–R diagram. Create a key table for the database that could be implemented from the design.
Model answer

Entities: Passenger, Cruise, Port.

Conceptual: Passenger M:M Cruise (a passenger can go on many cruises; a cruise carries many passengers). Cruise M:M Port (a cruise visits many ports; a port is visited by many cruises).

Logical: resolve each M:M with a link entity. Passenger 1:M Booking M:1 Cruise, and Cruise 1:M Visit M:1 Port.

Table namePrimary keyForeign key
PassengerPassengerID
CruiseCruiseID
BookingPassengerID & CruiseIDPassengerID, CruiseID
PortPortName
VisitCruiseID & PortNameCruiseID, PortName

If a cruise can call at the same port twice, add VisitDate to Visit's compound key.

🧹 11.05 Normalisation

Normalisation is a design technique for building a set of table designs from a list of data items. It can also improve existing table designs.

Tip: In Chapter 16 you will meet a completely different use of the word normalisation (for floating-point numbers).
Worked example 11.02

Normalising data for the theatrical agency

Start from a booking data sheet the agency might use:

Figure 11.10Example booking data sheet

Ignoring headings, the data items are a set of attributes:

(BookingID, VenueName, VenueAddress1, VenueAddress2, Date,
  (BandName, NumberOfMembers, Headlining))

The outer brackets start a table design. The inner brackets mark a repeating group: several bands per booking. A relational table needs single rows and atomic values, so the only way to store this in one table is with tuples like Table 11.05, which duplicates the BookingID, the venue data and the date:

BookingIDVenueNameVenueAddress1VenueAddress2DateBandNameNumberOfMembersHeadlining
2016/023Cambridge International TheatreCamsideCA123.06.2016ComputerKidz5Y
2016/023Cambridge International TheatreCamsideCA123.06.2016ITWizz3N
2016/023Cambridge International TheatreCamsideCA123.06.2016DeadlyDuo2N

Table 11.05 Data stored in an unnormalised table

Step 1: Conversion to first normal form (1NF)

Split the data into two groups, written as table definitions with names and primary keys. The non-repeating attributes form one table:

Booking(BookingID, VenueName, VenueAddress1, VenueAddress2, Date)

The repeating group needs a compound primary key, plus a foreign key back to the first table:

Band-Booking(BandName, BookingID(fk), NumberOfMembers, Headlining)

Neither table now has data redundancy, which is one aspect of 1NF. In each table the attributes depend on the primary key.

Step 2: Conversion to second normal form (2NF)

Look at each non-key attribute: does it depend on both parts of the compound key? Any that depend on only one part move to a new table. NumberOfMembers depends only on BandName:

Booking(BookingID, VenueName, VenueAddress1, VenueAddress2, Date)
Band-Booking(BandName(fk), BookingID(fk), Headlining)
Band(BandName, NumberOfMembers)

Booking is unchanged: a table with a single-attribute key is automatically in 2NF once it is in 1NF. Band-Booking now has two foreign keys. A table in 2NF either has a single primary key, or a compound key with every non-key attribute dependent on both parts.

Step 3: Conversion to third normal form (3NF)

Look for non-key dependencies: a non-key attribute that depends on another non-key attribute. VenueAddress1 and VenueAddress2 depend on VenueName, so they move to a fourth table:

Band(BandName, NumberOfMembers)
Band-Booking(BandName(fk), BookingID(fk), Headlining)
Booking(BookingID, Date, VenueName(fk))
Venue(VenueName, VenueAddress1, VenueAddress2)

Again a new foreign key keeps the reference to the newly created table. These four tables match four of the entities of the logical E–R model, with the keys from Table 11.04. That will not always happen: a logical E–R diagram describes a 2NF set of entities, but not necessarily a 3NF set.

Repeating group: a set of attributes that have more than one set of values when the other attributes each have a single value.

To summarise: in 3NF, every non-key attribute depends on the key, the whole key and nothing but the key.

🪜 Lab: step through Worked example 11.02

Pick a stage. Yellow marks what changed at that step.

Question 11.03 In Step 2 of Worked example 11.02, why is the Headlining attribute not placed in the Band table?
Model answer

Headlining depends on both parts of the compound key. Whether a band headlines is a fact about one band at one booking: ComputerKidz headlined booking 2016/023 but might be a support act at another. In the Band table it could only hold one value per band, as if a band always (or never) headlined.

🎮 Where does it go in 3NF?

Attributes from Worked example 11.02. Which 3NF table holds each one as a non-key attribute?

Task 11.02 Normalise the data shown in Figure 11.11.
Figure 11.11An order form
Model answer

Unnormalised. Totals are calculated, so they are not stored.

(OrderNo, OrderDate, CustomerNo, CustomerName, CustomerAddress1, CustomerAddress2,
 SalesRepNo, SalesRepName, (ProductNo, Description, Quantity, PricePerUnit))

1NF: move the repeating group out with a compound key.

Order(OrderNo, OrderDate, CustomerNo, CustomerName, CustomerAddress1, CustomerAddress2, SalesRepNo, SalesRepName)
OrderLine(OrderNo(fk), ProductNo, Description, Quantity, PricePerUnit)

2NF: Description and PricePerUnit depend on ProductNo only.

Order(OrderNo, OrderDate, CustomerNo, CustomerName, CustomerAddress1, CustomerAddress2, SalesRepNo, SalesRepName)
OrderLine(OrderNo(fk), ProductNo(fk), Quantity)
Product(ProductNo, Description, PricePerUnit)

3NF: customer details depend on CustomerNo, and SalesRepName depends on SalesRepNo (both non-key attributes).

Order(OrderNo, OrderDate, CustomerNo(fk), SalesRepNo(fk))
OrderLine(OrderNo(fk), ProductNo(fk), Quantity)
Product(ProductNo, Description, PricePerUnit)
Customer(CustomerNo, CustomerName, CustomerAddress1, CustomerAddress2)
SalesRep(SalesRepNo, SalesRepName)

Things to discuss: if each customer always has the same sales rep, SalesRepNo belongs in Customer rather than Order. If prices change over time, the price actually charged should also be kept in OrderLine.

🗄️ 11.06 The Database Management System (DBMS)

The database approach

A database is not just a collection of data. It is an implementation that follows the rules of a theoretical model. About 40 years ago ANSI (the American National Standards Institute) proposed a three-level model: the external level, the conceptual level and the internal level.

Figure 11.12The ANSI three-level architecture for the theatrical agency database
Internal level: the physical storage on disk. Its details (the internal schema) are known only here, controlled by the DBMS software. Only the people who wrote the DBMS know the storage structure, and the software copes with changes to the storage medium.
Conceptual level: one single, universal view of the whole database, controlled by the database administrator (DBA). Its conceptual schema (or logical schema) describes how the data is organised as a user or programmer sees it.
External level: the individual user and programmer views. Each view has an external schema saying which parts of the database it can reach, and one view can support several user programs.

Views are also a security tool for the DBA. Users or groups get access rights for their view: for example, read but not amend, or access to only some of the tables.

Data management system (DBMS): software that controls access to data in a database.
Database administrator (DBA): a person who uses the DBMS to customise the database to suit user and programmer requirements.
Book note: the key-term box says "Data management system", but DBMS stands for Database Management System, as the section heading says. Use the full name in exams.

🎮 Which ANSI level?

🧰 The facilities provided by a DBMS

Databases range from a simple system for one person to a large organisation's central database. Some DBMS facilities only matter in large organisations run by a DBA.

Whatever the size, a database can be created with SQL (next section), though most DBMSs offer alternatives:

  • a developer interface: tools to create tables and define attributes and their data types, and to build a user interface;
  • a query processor to create and run queries; a query extracts and manipulates data;
  • a report generator to present formatted output. Programmers can put queries and reports into the user interface.
Developer interface: gives access to software tools provided by a DBMS for creating tables.
Query processor: software tools provided by a DBMS to allow creation and execution of a query.
Query: used to select data from a database subject to defined conditions.

DBMS functions likely to be used by a DBA

  • Setting up user and programmer views and their access rights.
  • The data dictionary: hidden from everyone but the DBA, it holds metadata: definitions of every table and attribute, and how the physical storage is organised.
  • Performance features, especially indexes. For a table with many attributes and many tuples, an index is a secondary table holding one attribute's values (unique ones, primary or secondary key) with pointers to the matching tuples. Searching the index is much quicker than searching the full table.
  • Integrity: if a transaction starts but a system problem stops it finishing, the database could be left in an undefined state. A built-in feature should prevent this.
  • Backup of the stored data, as with any system.
Index: a small secondary table used for rapid searching which contains one attribute from the table being searched and pointers to the tuples in that table.

⚡ Lab: full-table scan vs index

A Member table with 2000 tuples, stored in the order they were added. Find one MemberID by scanning every tuple, or by searching a sorted index (binary search) and following its pointer.

Table scan

Index search

Press the button.
Discussion point: How many of the above concepts are recognisable in your experience of using a database? (Think of your school's student-records system, a library catalogue or an online shop: who has which view? Where would an index help?)

💻 11.07 Structured Query Language (SQL)

SQL is the language a DBMS provides for every operation on a relational database. Even when a package offers high-level tools, they produce SQL behind the scenes.

Data Definition Language (DDL)

DDL creates or alters tables: the structure only, never the data. Some DDL for the database designed in Worked example 11.02:

CREATE DATABASE BandBooking;
CREATE TABLE Band (
    BandName varchar(25),
    NumberOfMembers integer);
ALTER TABLE Band ADD PRIMARY KEY (BandName);
ALTER TABLE Band-Booking ADD FOREIGN KEY (BandName REFERENCES
Band(BandName);
Book errors: (1) The last command is missing a bracket. It should read ADD FOREIGN KEY (BandName) REFERENCES Band(BandName);. (2) A real DBMS will not accept a hyphen in a table name: Band-Booking is read as "Band minus Booking". Use Band_Booking (or quote the name). The playground below uses Band_Booking.

General points about writing SQL:

  • SQL is a sequence of commands, each ending with ;, and a command can take more than one line.
  • It is not case sensitive. This book uses upper case for commands and lower case for data types; table and attribute names keep their own capitals.
  • Items in a list are separated by commas; the list in CREATE TABLE is enclosed in parentheses.
  • A primary or foreign key can be defined inside CREATE TABLE, or added afterwards with ALTER TABLE (which can also add extra attributes).
  • Every attribute needs a data type. Names vary by DBMS, but you can always set a character length in brackets: BandName varchar(25) allows up to 25 characters.
  • Data-type names you may meet: character, varchar, boolean, integer, real, date, time (lower case here; often upper case elsewhere).
Task 11.03 For the database defined in Worked example 11.02, complete the DDL for creating the four tables. Use varchar(8) for BookingID, integer for NumberOfMembers, date for Date, character for Headlining and varchar(25) for all other data.
Model answer
CREATE TABLE Band (
    BandName varchar(25),
    NumberOfMembers integer,
    PRIMARY KEY (BandName));

CREATE TABLE Venue (
    VenueName varchar(25),
    VenueAddress1 varchar(25),
    VenueAddress2 varchar(25),
    PRIMARY KEY (VenueName));

CREATE TABLE Booking (
    BookingID varchar(8),
    Date date,
    VenueName varchar(25),
    PRIMARY KEY (BookingID),
    FOREIGN KEY (VenueName) REFERENCES Venue(VenueName));

CREATE TABLE Band_Booking (
    BandName varchar(25),
    BookingID varchar(8),
    Headlining character,
    PRIMARY KEY (BandName, BookingID),
    FOREIGN KEY (BandName) REFERENCES Band(BandName),
    FOREIGN KEY (BookingID) REFERENCES Booking(BookingID));

Create Band and Venue before the tables that refer to them. You could instead create plain tables and add keys with ALTER TABLE, as the book does.

✍️ Data Manipulation Language (DML)

DML has three uses: inserting data when the database is created, modifying or removing data, and reading data.

Inserting

INSERT INTO Band ('ComputerKidz', 5);
INSERT INTO Band-Booking (BandName, BookingID)
VALUES ('ComputerKidz', '2016/023');

The first, shorter form works if you know the attribute order. The second is safer: it names the attributes, then gives the values. Both use parentheses; each tuple needs its own INSERT; the attributes have a defined order, but the table itself has no concept of the tuples being ordered.

Book note: standard SQL (and every DBMS you are likely to use) needs VALUES in the short form too: INSERT INTO Band VALUES ('ComputerKidz', 5);.

Querying with SELECT

A query always starts with SELECT: attributes after SELECT, table after FROM, with parts separated by spaces.

SELECT BandName FROM Band;

SELECT BandName, NumberOfMembers
FROM Band;

SELECT * FROM Band;

The * means all attributes. Attribute lists are separated by commas without parentheses. ORDER BY sorts the output:

SELECT BandName, NumberOfMembers
FROM Band
ORDER BY BandName;

BandName is unique in Band, but it repeats in Band-Booking. To list each band that has a booking only once, use GROUP BY:

SELECT BandName
FROM Band-Booking
GROUP BY BandName;

A WHERE clause adds a condition. Long queries read best on separate lines:

SELECT BandName
FROM Band-Booking
WHERE Headlining = 'Y'
GROUP BY BandName;

SELECT BandName, NumberOfMembers
FROM Band
WHERE NumberOfMembers > 2
ORDER BY BandName;

The first gives one output line per band that has headlined; the second leaves out the duos.

Aggregate functions

SUM, COUNT and AVG work on one attribute across many tuples and return one value, so they are called aggregate functions.

SELECT Count(*)
FROM Band;

SELECT AVG(NumberOfMembers)
FROM Band;

SELECT SUM(NumberOfMembers)
FROM Band;
Book error: the book says SELECT Count(*) FROM Band; "displays the number of members in a band". It actually counts the tuples, so it gives the number of bands. Count(*) is special because it needs no attribute. Try it in the playground.

Joining two tables

A query can use a join condition. The most common is an inner join. Each attribute is given its full name, table name then attribute name separated by a dot:

SELECT VenueName, Date
FROM Booking
WHERE Band-Booking.BookingID = Booking.BookingID
AND Band-Booking.BandName = 'ComputerKidz';
Book error: both tables must be listed after FROM, otherwise Band-Booking is unknown: FROM Booking, Band_Booking.

How it works: Band-Booking is searched for tuples where BandName is ComputerKidz; for each one the BookingID is noted; Booking is searched for tuples with that BookingID; for each one found, VenueName and Date are output. Some versions of SQL require an explicit INNER JOIN:

SELECT table1.column1, table2.column2...
FROM table1
INNER JOIN table2
ON table1.common_field = table2.common_field;

Changing and removing data

If ComputerKidz recruits an extra member:

UPDATE Band
SET NumberOfMembers = 6
WHERE BandName = 'ComputerKidz';

Forget the WHERE clause and every band gets 6 members. DELETE needs the same care. If ITWizz disbands:

DELETE FROM Band-Booking
WHERE BandName = 'ITWizz';
DELETE FROM Band
WHERE BandName = 'ITWizz';

Deleting from Band first gives an error, because BandName is a foreign key in Band-Booking and every entry there must have a matching value in Band.

▶️ SQL playground

A real SQL engine (SQLite, compiled to WebAssembly) running in your browser, loaded with the agency's 3NF database: Band, Member, Venue, Booking, Band_Booking. Foreign keys are switched on, so the wrong-order DELETE really fails. Tap an example from the book, edit it, and press Run. Changes stay until you reset.

Ctrl + Enter
Press Run to load the database.
Challenges to try in the playground
  1. List the VenueName and Date of every booking, newest first.
  2. How many bookings has each band had? (Hint: COUNT(*) with GROUP BY.)
  3. List the names of the bands booked at Cambridge International Theatre.
  4. Give every member of DeadlyDuo's band a new BandName; what does the database do, and why?

Answers:

SELECT VenueName, Date FROM Booking ORDER BY Date DESC;

SELECT BandName, COUNT(*) FROM Band_Booking GROUP BY BandName;

SELECT Band_Booking.BandName
FROM Band_Booking, Booking
WHERE Band_Booking.BookingID = Booking.BookingID
AND Booking.VenueName = 'Cambridge International Theatre';

UPDATE Member SET BandName = 'NoSuchBand' WHERE BandName = 'DeadlyDuo';
-- fails: FOREIGN KEY constraint (referential integrity)

📌 Summary

  • A database offers better ways of ensuring data integrity than a file-based approach.
  • A relational database is made of tables of a special type; each table has a primary key and may contain foreign keys.
  • Entity–relationship modelling is a top-down approach to database design.
  • Normalisation starts with a collection of attributes and converts them into first, then second and finally third normal form.
  • A database architecture gives the user a conceptual level interface to the stored data.
  • A DBMS provides a data dictionary, indexing, control of user access rights and backup procedures.
  • SQL includes DDL commands for establishing a database and DML commands for creating queries.
Reflection point: Did you find normalisation difficult? It would be surprising if you didn't. Get as much practice as possible: many past exam papers contain examples to try.

🃏 Key-term flashcards

Tap a card to flip it.

✅ Quick quiz

📝 Exam-style questions

Write your answer first, then open the model answer. These are my own mark-scheme-style points, not official mark schemes.

Question 1 A relational database stores data about subjects students are studying. Some data from one table (student name, tutor group, personal tutor, subject, level, subject teacher):

Xiangfei3MUBComputingADER
Xiangfei3MUBMathsABNN
Xiangfei3MUBPhysicsASDAB
Mahesh2BARHistoryASIJM
Mahesh2BARGeographyASCAB
  • Relation/table: the whole set of student–subject data.
  • Attribute: a column of values, e.g. the subject column (Computing, Maths…).
  • Tuple: one row, one instance, e.g. Xiangfei, 3, MUB, Computing, A, DER.
  • No attribute names (column headings) and no table name are shown, and they must be defined first.
  • No primary key has been identified, and every table needs one.
  • No single attribute is unique: the student name repeats, subjects could repeat for other students.
  • Solution: use a compound primary key (StudentName + Subject), or better, add a unique StudentID and key on StudentID + Subject.

Yes: every attribute holds a single atomic value and there is no repeating group inside a tuple; each subject is in its own row. (Note the redundancy, such as the tutor group repeated, which later normal forms remove.)

(i) Any three: data is in two tables (relations); Student has primary key StudentName; StudentSubject has a compound primary key StudentName + Subject; StudentName in StudentSubject is a foreign key referencing Student; there are no repeating groups and values are atomic.

(ii) A primary key must be unique, but two students can share a name. The second student could not be entered, or their subjects would be mixed up. Use a StudentID instead.

(iii) Tutor depends on TutorGroup, which is a non-key attribute (a non-key dependency), not directly on the key. Move it into a new table, TutorGroup(TutorGroup, Tutor), leaving TutorGroup as a foreign key in Student.

(a) Client, Dinner, Dish, Venue, Staff.

(b) Client–Dinner, Dinner–Dish, Dinner–Venue, Dinner–Staff.

(c)

  • Client 1:M Dinner: a client can book many dinners; each dinner is for one client (crow's foot at Dinner).
  • Dinner M:M Dish: a dinner offers many dishes; a dish appears on the menu of many dinners (crow's feet both ends; a link entity, Menu, would resolve it).
  • Venue 1:M Dinner: a dinner is held at one venue; a venue can host many dinners (crow's foot at Dinner).
  • Dinner M:M Staff: several staff serve one dinner; one member of staff works at many dinners.
Exam question 3: a travel agency booking form

(a)

(BookingNumber, HotelName, HotelAddress1, HotelAddress2, Rating,
 (Date, RoomType, NumberOfRooms, RoomRate))

The inner bracket is the repeating group.

(b)

Booking(BookingNumber, HotelName, HotelAddress1, HotelAddress2, Rating)
BookingRoom(BookingNumber(fk), Date, RoomType, NumberOfRooms, RoomRate)

(c) Modify BookingRoom: it has a compound key, and RoomRate depends only on RoomType, not on the whole key.

BookingRoom(BookingNumber(fk), Date, RoomType(fk), NumberOfRooms)
Room(RoomType, RoomRate)

Date and RoomType are needed in the key because the same booking has several dates and several room types on the same date. (Strictly the rate belongs to a room type at a hotel; with more than one hotel, Room's key would be HotelName + RoomType.)

(d) Booking: HotelAddress1, HotelAddress2 and Rating depend on HotelName, a non-key attribute. Fix: Hotel(HotelName, HotelAddress1, HotelAddress2, Rating) with HotelName as a foreign key in Booking.

Question 4 A small database has three tables:

STUDENT(StudentID, StudentName, StudentOtherName, DateOfBirth)
SUBJECT(SubjectName, SubjectTeacher)
TUTORIAL(StudentID(fk), SubjectName(fk), WeekNumber, Day, PeriodNumber)
CREATE TABLE STUDENT (
    StudentID VARCHAR(6),
    StudentName VARCHAR(20),
    StudentOtherName VARCHAR(20),
    DateOfBirth DATE);

CREATE TABLE SUBJECT (
    SubjectName VARCHAR(20),
    SubjectTeacher VARCHAR(30));

CREATE TABLE TUTORIAL (
    StudentID VARCHAR(6),
    SubjectName VARCHAR(20),
    WeekNumber INTEGER,
    Day VARCHAR(9),
    PeriodNumber INTEGER);

Any two. Marks for the correct structure (brackets, commas, semicolon) and sensible data types.

ALTER TABLE SUBJECT ADD PRIMARY KEY (SubjectName);
ALTER TABLE TUTORIAL ADD FOREIGN KEY (StudentID) REFERENCES STUDENT(StudentID);
ALTER TABLE TUTORIAL ADD FOREIGN KEY (SubjectName) REFERENCES SUBJECT(SubjectName);
SELECT StudentName, StudentOtherName
FROM STUDENT
ORDER BY DateOfBirth;

This lists the oldest first (earliest date of birth). For youngest first, add DESC; either should be accepted if explained.

TUTORIAL's primary key (StudentID + SubjectName) allows only one tutorial per student per subject. A second tutorial in another week would duplicate the key and be rejected. WeekNumber (or week + day + period) must be part of the key.

(i) Database Management System.

(ii) Any two, described: create different views so each group only sees the data it needs (e.g. teachers see attendance but not home addresses); set access rights per user/group (read-only vs amend); require user IDs and passwords; schedule regular backups.

(iii) Use the query processor to create and run a query (without programming) that selects data meeting conditions, e.g. the contact details of every student absent today.

(iv) Any three: data stored once and linked by keys, so no redundancy and no inconsistent copies; program–data independence, so programs need not change when the structure changes; access control per view solves the privacy problem; validation and referential integrity stop invalid entries.

(i) ClassID is the primary key of CLASS and appears as a foreign key in CLASS-GROUP.

(ii) Many-to-one: many CLASS-GROUP tuples for one STUDENT (one student attends many classes).

SELECT StudentID, FirstName
FROM STUDENT
WHERE TutorGroup = '10B'
ORDER BY LastName;

SELECT STUDENT.LastName
FROM STUDENT, CLASS_GROUP
WHERE STUDENT.StudentID = CLASS_GROUP.StudentID
AND CLASS_GROUP.ClassID = 'CS1';

Cambridge International AS & A Level Computer Science 9608, Paper 11 Q8, June 2016

  • Less data redundancy: member details stored once, so no inconsistent copies.
  • Better data integrity: validation, and referential integrity stop a booking for a class or member that doesn't exist.
  • Program–data independence: the structure can change without rewriting every program.
  • Easy queries in SQL (e.g. who is booked into a class) without writing file-handling code.
  • Security: views and access rights for different staff.

Each reason: 1 mark identified + 1 explained.

Exam question 6b: the MEMBER, CLASS and BOOKING entities

MEMBER 1 —< M BOOKING M >— 1 CLASS. One member makes many bookings and one class has many bookings; each booking is for one member and one class. BOOKING is the link entity resolving the M:M between MEMBER and CLASS.

CREATE TABLE CLASS (
    ClassID VARCHAR(5),
    Description VARCHAR(30),
    StartDate DATE,
    ClassTime TIME,
    NoOfSessions INTEGER,
    AdultsOnly BOOLEAN,
    PRIMARY KEY (ClassID));

Cambridge International AS & A Level Computer Science 9608, Paper 12 Q9, November 2016

Guru Jazzy · Cambridge AS & A Level Computer Science · Chapter 11 Databases · Figures from the Cambridge coursebook (Langfield & Duddell) · Model answers are my own