A college stores student, major, course, instructor, and grade information in one table.
The registrar wants a database that:
Your team has been asked to redesign the data in third normal form (3NF).
| student_id | student_name | major | courses | |
|---|---|---|---|---|
| S101 | Ana Rivera | ana@college.edu | M01, Data Science | C101, Databases, Dr. Kim, A; C202, Statistics, Dr. Patel, B+ |
| S102 | Jamal Lee | jamal@college.edu | M02, Computer Science | C101, Databases, Dr. Kim, B |
| S103 | Mei Chen | mei@college.edu | M01, Data Science | C202, Statistics, Dr. Patel, A; C303, Programming, Dr. Gomez, A- |
Normalization
3NF Table
Create Database
Appendix
First Normal Form requires that a database includes a primary key and excludes repeating columns.
The courses is problematic. Create repeating rows. Additionally, each cell should contain one, piece of information.
| student_id | student_name | major_id | major_name | course_id | course_name | instructor | grade | |
|---|---|---|---|---|---|---|---|---|
| S101 | Ana Rivera | ana@college.edu | M01 | Data Science | C101 | Databases | Dr. Kim | A |
| S101 | Ana Rivera | ana@college.edu | M01 | Data Science | C202 | Statistics | Dr. Patel | B+ |
| S102 | Jamal Lee | jamal@college.edu | M02 | Computer Science | C101 | Databases | Dr. Kim | B |
| S103 | Mei Chen | mei@college.edu | M01 | Data Science | C202 | Statistics | Dr. Patel | A |
| S103 | Mei Chen | mei@college.edu | M01 | Data Science | C303 | Programming | Dr. Gomez | A- |
This table satisfies First Normal Form (1NF) because:
student_id and course_id can uniquely identify each enrollment.Student and course information is still repeated. This redundancy will be addressed when the table is converted to Second Normal Form (2NF).
Second Normal Form does not allow non-key attributes to be partially dependent on composite primary keys. Additionally, the table must be in 1NF.
Problems: - course_name only depends on course_id, not student_id - major_name and major_id only depends on student_id (more on that later) - instructor only depends on course_id, not student_id
To convert the table to Second Normal Form (2NF), remove attributes that depend on only part of the composite key (student_id, course_id).
Primary key: student_id
| student_id | student_name | major_id | major_name | |
|---|---|---|---|---|
| S101 | Ana Rivera | ana@college.edu | M01 | Data Science |
| S102 | Jamal Lee | jamal@college.edu | M02 | Computer Science |
| S103 | Mei Chen | mei@college.edu | M01 | Data Science |
Primary key: course_id
| course_id | course_name | instructor |
|---|---|---|
| C101 | Databases | Dr. Kim |
| C202 | Statistics | Dr. Patel |
| C303 | Programming | Dr. Gomez |
Composite primary key: (student_id, course_id)
| student_id | course_id | grade |
|---|---|---|
| S101 | C101 | A |
| S101 | C202 | B+ |
| S102 | C101 | B |
| S103 | C202 | A |
| S103 | C303 | A- |
The Enrollments table is a junction table connecting students and courses.
This design satisfies 2NF because:
student_id.course_id.grade depends on the complete composite key (student_id, course_id).The Students table is not yet in 3NF because major_name depends on major_id. This creates a transitive dependency:
student_id → major_id → major_name
A table is in Third Normal Form when it is in 2NF and non-key attributes do not depend on other non-key attributes.
The Students table in 2NF is not yet in 3NF because major_name depends on major_id. This creates a transitive dependency:
Primary key: student_id
Foreign key: major_id
| student_id | student_name | major_id | |
|---|---|---|---|
| S101 | Ana Rivera | ana@college.edu | M01 |
| S102 | Jamal Lee | jamal@college.edu | M02 |
| S103 | Mei Chen | mei@college.edu | M01 |
Primary key: major_id
| major_id | major_name |
|---|---|
| M01 | Data Science |
| M02 | Computer Science |
Primary key: course_id
| course_id | course_name | instructor_id |
|---|---|---|
| C101 | Databases | Dr. Kim |
| C202 | Statistics | Dr. Patel |
| C303 | Programming | Dr. Gomez |
Composite primary key: (student_id, course_id)
Foreign keys: student_id and course_id
| student_id | course_id | grade |
|---|---|---|
| S101 | C101 | A |
| S101 | C202 | B+ |
| S102 | C101 | B |
| S103 | C202 | A |
| S103 | C303 | A- |
This design satisfies 3NF because:
Majors table.Enrollments table represents the many-to-many relationship between students and courses.Normalization
3NF Table
Create Database
Appendix
The original table is unnormalized because major contains multiple values and courses contains repeating groups.
The data can be converted to 3NF using the following five tables.
| major_id | major_name |
|---|---|
| M01 | Data Science |
| M02 | Computer Science |
Primary key: major_id
| student_id | student_name | major_id | |
|---|---|---|---|
| S101 | Ana Rivera | ana@college.edu | M01 |
| S102 | Jamal Lee | jamal@college.edu | M02 |
| S103 | Mei Chen | mei@college.edu | M01 |
Primary key: student_id
Foreign key: major_id references majors.major_id
| course_id | course_name | instructor_id |
|---|---|---|
| C101 | Databases | Dr. Kim |
| C202 | Statistics | Dr. Patel |
| C303 | Programming | Dr. Gomez |
Primary key: course_id
| student_id | course_id | grade |
|---|---|---|
| S101 | C101 | A |
| S101 | C202 | B+ |
| S102 | C101 | B |
| S103 | C202 | A |
| S103 | C303 | A- |
Composite primary key: student_id, course_id
Foreign keys:
student_id references students.student_idcourse_id references courses.course_id| Table | Primary key | Foreign key(s) |
|---|---|---|
majors |
major_id |
— |
students |
student_id |
major_id |
courses |
course_id |
— |
enrollments |
student_id, course_id |
student_id, course_id |
Normalization
3NF Table
Create Database
Appendix
In DB Browser for SQLite:
college_3nf.db.PRAGMA foreign_keys = ON;.CREATE TABLE statements.Use this pattern for each entity table:
Use this pattern for a foreign key:
Complete the enrollment table:
After creating all five tables:
Example syntax:
PRAGMA foreign_keys = ON;
CREATE TABLE majors (
major_id TEXT PRIMARY KEY,
major_name TEXT NOT NULL UNIQUE
);
CREATE TABLE students (
student_id TEXT PRIMARY KEY,
student_name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
major_id TEXT NOT NULL,
FOREIGN KEY (major_id) REFERENCES majors(major_id)
);
CREATE TABLE courses (
course_id TEXT PRIMARY KEY,
course_name TEXT NOT NULL,
instructor TEXT NOT NULL
);
CREATE TABLE enrollments (
student_id TEXT NOT NULL,
course_id TEXT NOT NULL,
grade TEXT,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES students(student_id)
ON DELETE CASCADE,
FOREIGN KEY (course_id) REFERENCES courses(course_id)
ON DELETE CASCADE
);INSERT INTO majors VALUES
('M01', 'Data Science'),
('M02', 'Computer Science');
INSERT INTO students VALUES
('S101', 'Ana Rivera', 'ana@college.edu', 'M01'),
('S102', 'Jamal Lee', 'jamal@college.edu', 'M02'),
('S103', 'Mei Chen', 'mei@college.edu', 'M01');
INSERT INTO courses VALUES
('C101', 'Databases', 'Dr. Kim'),
('C202', 'Statistics', 'Dr. Patel'),
('C303', 'Programming', 'Dr. Gomez');
INSERT INTO enrollments VALUES
('S101', 'C101', 'A'),
('S101', 'C202', 'B+'),
('S102', 'C101', 'B'),
('S103', 'C202', 'A'),
('S103', 'C303', 'A-');Normalization
3NF Table
Create Database
Appendix
| Keyword or term | Definition |
|---|---|
PRAGMA foreign_keys = ON |
Turns on foreign-key enforcement for the current SQLite connection. |
CREATE TABLE |
Creates a new table and defines its columns and constraints. |
TEXT |
Stores text values such as names, identifiers, and grades. (Data Type) |
PRAGMA changes a SQLite setting. The other items define the structure of the database.
| Keyword or clause | Definition |
|---|---|
PRIMARY KEY |
Uniquely identifies each row in a table. |
NOT NULL |
Requires the column to contain a value. |
UNIQUE |
Prevents duplicate values in a column or group of columns. |
FOREIGN KEY |
Identifies a column whose values must match a key in another table. |
REFERENCES |
Names the parent table and parent column for a foreign key. |
ON DELETE CASCADE |
Automatically deletes related child rows when a parent row is deleted. |
This composite key prevents a student from enrolling in the same course twice.
| Keyword or clause | Definition |
|---|---|
INSERT INTO |
Adds one or more rows to a table. |
VALUES |
Introduces the values for the new rows. |
NULL |
Represents a missing or unknown value when the column permits it. |
The value order must match the order of the named columns.
| Keyword or clause | Definition |
|---|---|
SELECT |
Chooses the columns returned by a query. |
FROM |
Identifies the first table used by the query. |
AS |
Assigns a temporary alias to a table or column. |
JOIN |
Combines matching rows from related tables. |
ON |
States the condition used to match rows in a join. |
ORDER BY |
Sorts the result using one or more columns. |
The aliases s and m shorten qualified column names.