Databases
Normalisation to third normal form, entity relationship modelling, SQL, indexing, transactions and the ACID properties.
Structure and normalisation
Key terms
- Entity: something data is stored about, becoming a table
- Attribute: a property of an entity, becoming a field
- Record or tuple: one row
- Primary key: an attribute uniquely identifying each record
- Composite key: a primary key made of two or more attributes together
- Foreign key: an attribute in one table that is the primary key of another, creating the link
- Secondary key: an additional indexed field used for searching
Relationships
- One to one: rare, and usually a sign the tables should be merged
- One to many: the most common. The foreign key goes on the many side
- Many to many: cannot be implemented directly and must be resolved with a linking table holding foreign keys to both
Normalisation
First normal form (1NF). No repeating groups, and every field holds a single atomic value. Each record is uniquely identifiable.
Second normal form (2NF). In 1NF, and every non key attribute depends on the whole primary key, not just part of a composite key.
Third normal form (3NF). In 2NF, and no non key attribute depends on another non key attribute. There are no transitive dependencies.
The usual summary: every non key attribute depends on the key, the whole key, and nothing but the key.
Why normalise
- Removes redundancy, so the same fact is stored once
- Removes update anomalies, where changing a fact in one place leaves other copies wrong
- Removes insertion anomalies, where a record cannot be added without unrelated data
- Removes deletion anomalies, where deleting a record destroys unrelated information
- Reduces storage and improves data consistency
The cost is more tables and therefore more joins, which can slow complex queries. This is why some analytical systems deliberately denormalise for read performance.
- One table for students. Each row is a student, each column a field.
- A primary key: one field whose value is different in every row.
- A second table for courses, with its own primary key.
- A foreign key in one table holds the primary key of the other.
- That link is why the data is stored once and not repeated.
SQL, indexing and transactions
Querying
SELECT Name, Grade
FROM Students
WHERE Year = 11 AND Grade >= 7
ORDER BY Grade DESC;
SELECT Students.Name, Courses.Title
FROM Students
INNER JOIN Enrolments ON Students.ID = Enrolments.StudentID
INNER JOIN Courses ON Enrolments.CourseID = Courses.ID
WHERE Courses.Title LIKE 'Comp%';
SELECT Year, COUNT(*) AS Total, AVG(Grade) AS MeanGrade
FROM Students
GROUP BY Year
HAVING COUNT(*) > 5;Modifying
INSERT INTO Students (Name, Year, Grade) VALUES ('Aisha', 11, 8);
UPDATE Students SET Grade = 9 WHERE Name = 'Aisha';
DELETE FROM Students WHERE Year = 13;
CREATE TABLE Courses (
ID INTEGER PRIMARY KEY,
Title VARCHAR(60) NOT NULL,
Credits INTEGER
);
ALTER TABLE Courses ADD Department VARCHAR(40);This is one of the most damaging mistakes in professional practice, and it is entirely preventable.
Indexing
An index is a separate structure mapping the values of a field to the locations of matching records.
- Searches and sorts on that field become far faster, since the whole table need not be scanned
- Every insert, update and delete becomes slower, because the index must also be maintained
- The index consumes additional storage
Index fields that are searched frequently. Do not index fields that are written far more often than they are read.
Transactions and ACID
A transaction is a group of operations treated as a single indivisible unit.
- Atomicity. All operations succeed or none do. A transfer that debits one account must not fail after the debit but before the credit.
- Consistency. The database moves from one valid state to another, with all rules and constraints satisfied.
- Isolation. Concurrent transactions do not interfere. The result matches some sequential ordering of them.
- Durability. Once committed, changes survive a crash or power failure, guaranteed by writing to non volatile storage.
Concurrency control
- Record locking prevents two users modifying the same record simultaneously, but can produce deadlock where each transaction waits for a record the other holds
- Timestamp ordering gives each transaction a timestamp and resolves conflicts by ordering, avoiding deadlock at the cost of restarting some transactions
- Serialisation ensures the outcome of concurrent transactions matches some sequential execution of them
- Each clause has a job: SELECT picks columns, FROM names the table, WHERE picks rows, ORDER BY sorts.
- WHERE keeps the rows that meet the condition and drops the rest.
- The result has only the selected columns, in the order asked for.
- Atomicity: a transaction is all or nothing.
- Consistency: the database goes from one valid state to another, and the rules always hold.
- Isolation: concurrent transactions do not see each other's half finished work.
- Durability: committed data survives a crash.
Key terms you must be able to define
- Entity
- Something that data is stored about, implemented as a table.
- Primary key
- An attribute or set of attributes uniquely identifying each record in a table.
- Foreign key
- An attribute in one table that is the primary key of another, forming the link between them.
- Composite key
- A primary key made up of two or more attributes together.
- Normalisation
- Organising data to remove redundancy and eliminate update, insertion and deletion anomalies.
- Third normal form
- A table in second normal form with no non key attribute depending on another non key attribute.
- Transitive dependency
- A non key attribute depending on another non key attribute rather than directly on the key.
- Linking table
- A table resolving a many to many relationship by holding foreign keys to both entities.
- Index
- A structure mapping field values to record locations, speeding searches at the cost of slower writes.
- Transaction
- A group of database operations treated as a single indivisible unit.
- ACID
- Atomicity, Consistency, Isolation and Durability, the guarantees a reliable transaction system provides.
- Deadlock
- A state where two transactions each hold a lock the other needs, so neither can proceed.
Flashcards
Say the definition out loud before you flip the card. Retrieving it from memory is what builds recall, reading it again is not.
Reach the top grade on this topic
- Apply 1NF, 2NF and 3NF to an actual table rather than reciting the definitions
- Name the anomalies removed by normalisation: update, insertion and deletion
- Resolve a many to many relationship with a correctly described linking table
- Write SQL with joins, aggregate functions and GROUP BY, not just SELECT and WHERE
- Explain each ACID property with a concrete failure it prevents
- State the cost of indexing as well as the benefit
Mistakes that cost marks here
- Reciting normal form definitions without applying them to the table in the question.
- Putting the foreign key on the wrong side of a one to many relationship. It belongs on the many side.
- Implementing a many to many relationship directly rather than with a linking table.
- Forgetting the WHERE clause on UPDATE or DELETE.
- Describing indexing as purely beneficial, with no mention of slower writes or extra storage.
- Confusing atomicity with consistency. Atomicity is all or nothing, consistency is about valid states.
The ACID properties exist because of one question: what happens if the power fails halfway through moving money between two accounts? Every serious database is built around making that question answerable.
Knowledge check
Exam-style questions
Five written questions in the style of the real paper. Write a full answer, then let the marker check it against the mark scheme.
- LAn attribute in one table that is the primary key of another table
- LIt creates the link between the two tables
A foreign key is an attribute in one table which holds values drawn from the primary key of another table. It is the mechanism that creates a relationship between the two, allowing each record in the first table to be associated with exactly one record in the second, and it is what makes joins possible when querying data spread across several tables.
- LNormalisation removes redundant duplicated data
- LUpdate anomalies are avoided, since a fact is changed in only one place
- LInsertion anomalies are avoided, so records can be added independently
- LDeletion anomalies are avoided, so removing a record does not destroy unrelated data
- LLess storage is used and data consistency is improved
Normalising to third normal form ensures that every non key attribute depends on the key, the whole key and nothing but the key, which means each individual fact is stored in exactly one place. The most important consequence is the elimination of anomalies. Without normalisation, an update anomaly occurs when a fact stored in several rows is changed in one of them and not the others, leaving the database internally inconsistent with no indication of which copy is right. An insertion anomaly occurs when a new record cannot be added because unrelated information is missing, for example being unable to record a new course until a student has enrolled on it. A deletion anomaly occurs when removing a record destroys information that was only stored there, such as losing all record of a department because its last employee left. Normalisation also reduces the total storage required, since data is not duplicated across many rows, and it improves overall data integrity because there is only ever one authoritative copy of each fact to keep correct.
- LSelects the required columns from the correct tables
- LJoins Students to Enrolments on the student ID
- LJoins Enrolments to Courses on the course ID
- LUses correct SQL syntax throughout
SELECT Students.Name, Courses.Title FROM Students INNER JOIN Enrolments ON Students.ID = Enrolments.StudentID INNER JOIN Courses ON Enrolments.CourseID = Courses.ID; The Enrolments table is the linking table resolving the many to many relationship between students and courses, so two joins are needed. The first connects each student to their enrolment records by matching the student ID, and the second connects each enrolment to the course it refers to by matching the course ID. Because the columns Name and Title come from different tables, they are qualified with their table names to avoid ambiguity.
- LAtomicity means all operations in the transaction succeed or none do
- LGives an example such as a bank transfer not leaving money missing
- LConsistency means the database moves from one valid state to another
- LIsolation means concurrent transactions do not interfere with one another
- LDurability means committed changes survive a system failure
- LTogether they guarantee the database remains reliable despite failures and concurrency
Atomicity means that a transaction is indivisible: either every operation within it completes or none of them does. The standard example is transferring money between accounts, where debiting one account and crediting the other must happen together, since a failure between the two would make money simply disappear. Consistency means that a transaction takes the database from one valid state to another, with every rule, constraint and relationship still satisfied when it completes, so a transaction that would violate a foreign key constraint is rejected rather than applied. Isolation means that transactions running at the same time do not interfere with each other, and the result is as though they had run one after another in some order, which prevents one transaction reading data another has partially modified. Durability means that once a transaction has been committed, its changes are permanent and will survive a crash or power failure, which is achieved by writing to non volatile storage and maintaining a transaction log that can be replayed after a restart. Together these four properties are what allow a database to be trusted with financial and other critical data despite hardware failures and thousands of simultaneous users.
- LA student can take several courses, so there is a many to many relationship
- LCourseTitle depends on CourseID rather than on the whole key
- LThis is a partial dependency violating second normal form
- LTutorName depends on CourseID, which is a transitive dependency violating third normal form
- LCreate a Students table and a Courses table
- LCreate a linking table holding StudentID and CourseID as foreign keys
The table is not in third normal form for several reasons. Because a student can take more than one course and a course has many students, the relationship is many to many, so identifying a row requires a composite key of StudentID and CourseID. Once that is recognised, StudentName depends only on StudentID and CourseTitle depends only on CourseID, so both are partially dependent on part of the composite key rather than on the whole of it, which breaks second normal form and causes the student's name and the course title to be repeated in every row. TutorName is worse still: it depends on CourseID, which is not itself the whole key, so it is a transitive dependency and breaks third normal form. The consequences are redundancy and anomalies, since changing a course title requires updating many rows and deleting the last enrolment on a course loses all record of that course and its tutor. The correct structure is three tables. A Students table holds StudentID as its primary key with StudentName. A Courses table holds CourseID as its primary key with CourseTitle and TutorName, or with a TutorID foreign key if tutors need their own table. An Enrolments linking table holds StudentID and CourseID as foreign keys, together forming its composite primary key, which resolves the many to many relationship into two one to many relationships and stores each fact exactly once.