How do we define the structure of a database and enforce rules on the data it can hold?
Define database schemas with CREATE TABLE, choosing data types and enforcing PRIMARY KEY, FOREIGN KEY, NOT NULL and UNIQUE constraints
A focused answer to the H2 Computing outcome on defining schemas. CREATE TABLE, choosing appropriate data types, and enforcing primary key, foreign key, NOT NULL and UNIQUE constraints to protect data integrity.
Reviewed by: AI editorial process; not yet individually human-reviewed
Have a quick question? Jump to the Q&A page
Jump to a section
What this dot point is asking
SEAB wants you to define a database's structure with CREATE TABLE, choose appropriate data types for columns, and apply constraints - PRIMARY KEY, FOREIGN KEY, NOT NULL, UNIQUE - that the database enforces automatically. The core idea is that the schema encodes the rules of the data once, so invalid data is rejected at the source rather than checked by every program.
The answer
CREATE TABLE
Data Definition Language (DDL) defines structure. CREATE TABLE names a table and lists its columns, each with a name and a data type:
CREATE TABLE Book (
BookID INTEGER,
Title VARCHAR(120),
Year INTEGER,
Price DECIMAL(6, 2)
);
Choosing data types
The type fixes what a column may hold and how it is stored:
INTEGERfor whole numbers (IDs, counts).DECIMAL(p, s)for exact fractional values such as money.VARCHAR(n)for variable-length text up to characters;CHAR(n)for fixed length.DATE/DATETIMEfor dates and times.BOOLEANfor true/false flags.
A correct type gives validation, efficient storage and the right operations - dates can be compared and sorted, numbers can be summed.
Constraints that enforce rules
Constraints are rules the database guarantees:
- PRIMARY KEY - unique and not null; identifies each row.
- FOREIGN KEY ... REFERENCES - the value must match a primary key in another table (referential integrity).
- NOT NULL - the column must always have a value.
- UNIQUE - no two rows may share the value (without it being the primary key).
CREATE TABLE Student (
StudentID INTEGER PRIMARY KEY,
Name VARCHAR(60) NOT NULL,
Email VARCHAR(120) UNIQUE,
ClassID INTEGER,
FOREIGN KEY (ClassID) REFERENCES Class(ClassID)
);
Why enforce rules in the schema
Putting rules in the schema means every application using the database obeys them automatically. A NOT NULL name cannot be bypassed by a buggy program; a UNIQUE email is guaranteed even under concurrent inserts. The database becomes the single guardian of integrity.
Examples in context
Example 1. Preventing bad sign-ups. A registration system declares Email VARCHAR(120) UNIQUE NOT NULL. Even if two people submit the same email at the same instant, the database rejects the second, so duplicate accounts cannot exist - a guarantee the web form alone could not make.
Example 2. Money columns. An invoicing schema uses Amount DECIMAL(10, 2) rather than a floating-point type, so totals are exact to the cent. The choice of type is a design decision that directly prevents the rounding errors that plague binary floating point for currency.
Try this
Q1. Which constraint guarantees a column has no duplicate values but is not the primary key? [1 mark]
- Cue.
UNIQUE.
Q2. Why store a price as DECIMAL rather than as a floating-point type? [2 marks]
- Cue.
DECIMALstores the value exactly, avoiding the rounding errors of binary floating point that would corrupt money totals.
Q3. State the two guarantees a PRIMARY KEY constraint provides. [2 marks]
- Cue. The value is unique across rows and is never null.
Exam-style practice questions
Practice questions written in the style of SEAB exam questions on this dot point, with worked answer explainers. The year tag is the paper they imitate, not the source.
Original6 marksWrite SQL CREATE TABLE statements for Class(ClassID, ClassName) and Student(StudentID, Name, Email, ClassID), where StudentID is the primary key, every student must have a name, emails must be unique, and each student belongs to an existing class. Identify the constraint that enforces each rule.Show worked answer →
CREATE TABLE Class (
ClassID INTEGER PRIMARY KEY,
ClassName VARCHAR(20) NOT NULL
);
CREATE TABLE Student (
StudentID INTEGER PRIMARY KEY,
Name VARCHAR(60) NOT NULL,
Email VARCHAR(120) UNIQUE,
ClassID INTEGER,
FOREIGN KEY (ClassID) REFERENCES Class(ClassID)
);
The constraints map to the rules:
PRIMARY KEYonStudentIDmakes it unique and not null, identifying each student.NOT NULLonNameforces every student to have a name.UNIQUEonEmailstops two students sharing an email.FOREIGN KEY (ClassID) REFERENCES Class(ClassID)ensures each student's class exists, enforcing referential integrity.
Markers reward correct types, the primary key, the NOT NULL and UNIQUE constraints on the right columns, and a foreign key referencing the existing Class table.
Original4 marksExplain why a database designer chooses specific data types for columns, and give two consequences of using an inappropriate type, such as storing a date or a phone number as plain text.Show worked answer →
A data type declares what kind of value a column holds (integer, decimal, fixed or variable text, date, boolean), which lets the database validate input, store it efficiently, and support the right operations on it.
Two consequences of an inappropriate type:
Loss of validation and operations. A date stored as text is not checked for validity and cannot be compared or sorted chronologically or have date arithmetic applied; '2026-13-40' would be accepted as a string.
Inefficiency and inconsistency. Text takes more space than a compact numeric or date type, and free-form text invites inconsistent formats (phone numbers with or without spaces or country codes), making matching and searching unreliable.
Markers reward that types enable validation, efficient storage and correct operations, and two genuine consequences such as no validation/wrong sorting and wasted space/inconsistency.
Related dot points
- Describe the relational model in terms of tables, rows, attributes, primary keys and foreign keys, and explain referential integrity
A focused answer to the H2 Computing outcome on the relational model. Tables, rows and attributes, primary and foreign keys, relationships between tables, and how referential integrity keeps data consistent.
- Write SQL queries using SELECT with WHERE, ORDER BY, JOIN, GROUP BY and aggregate functions, and modify data with INSERT, UPDATE and DELETE
A focused answer to the H2 Computing outcome on SQL queries. SELECT with WHERE and ORDER BY, joining tables, grouping with aggregate functions, and modifying rows with INSERT, UPDATE and DELETE.
- Normalise a relational design to first, second and third normal form, explaining the anomalies each form removes
A focused answer to the H2 Computing outcome on normalisation. First, second and third normal form, the insertion, update and deletion anomalies they remove, and how to decompose a table step by step.
- Model a problem domain with an entity-relationship diagram, identifying entities, attributes, relationships and cardinality, and map it to tables
A focused answer to the H2 Computing outcome on ER modelling. Entities, attributes and relationships, one-to-one, one-to-many and many-to-many cardinality, resolving many-to-many with a link table, and mapping an ER model to relational tables.
- Handle runtime errors with try and except, and read from and write to text files safely in Python
A focused answer to the H2 Computing outcome on exceptions and files. The try, except, else and finally blocks, raising exceptions, and reading and writing text files safely with the with statement.