Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›SQL›Normalization — 1NF, 2NF, 3NF

Database Design

Normalization — 1NF, 2NF, 3NF

Normalization is a systematic approach to organizing data in a relational database to minimize redundancy and prevent data anomalies. By decomposing tables into smaller, related structures, it ensures that every piece of information is stored in exactly one place. You apply these rules during the schema design phase to maintain high data integrity and efficient performance.

The Foundation: First Normal Form (1NF)

The First Normal Form acts as the bedrock of relational database design, focusing on the atomicity of data values. To achieve 1NF, a table must store only single, indivisible values in every column, and each record must be uniquely identifiable. When columns contain lists or sets of data, you invite complex parsing requirements that force your queries to perform expensive string manipulation or repeated scanning. By ensuring that each field holds only one data point, you allow the database engine to treat each piece of information as a first-class citizen during filtering and aggregation. Atomicity removes the ambiguity of searching within a delimited string, shifting the burden from application logic back to the database engine where it belongs. This requirement forces you to rethink table structures that might otherwise appear convenient but ultimately hinder scale, ensuring that your primary keys can reliably locate a singular, well-defined row in any scenario.

-- Correcting a non-atomic table (1NF violation)
-- Instead of storing 'Phone1, Phone2', use a related child table.
CREATE TABLE Employees (
    employee_id INT PRIMARY KEY,
    full_name VARCHAR(100)
);

CREATE TABLE EmployeePhones (
    phone_id INT PRIMARY KEY,
    employee_id INT,
    phone_number VARCHAR(15),
    FOREIGN KEY (employee_id) REFERENCES Employees(employee_id)
);

Targeting Partial Dependencies: Second Normal Form (2NF)

Moving into Second Normal Form requires that your database already satisfies the 1NF criteria and addresses the issue of partial dependencies. A partial dependency occurs when a non-prime attribute in a table relies on only a portion of a composite primary key rather than the entire key. This design flaw leads to update anomalies where data must be replicated across multiple rows, creating the risk of inconsistent information if one record is modified while others are ignored. By decomposing tables to ensure that every non-key column is functionally dependent on the entire primary key, you effectively isolate independent attributes into their own specific entities. This process of elimination is crucial because it aligns the structure of the data with the reality of the business entities being represented, significantly reducing storage waste and simplifying the logic required to maintain data consistency across the entire ecosystem of your relational schema.

-- Example of 2NF: Splitting StudentCourses to remove partial dependencies
-- Course title is dependent only on CourseID, not the whole PK (Student, Course).
CREATE TABLE Courses (
    course_id INT PRIMARY KEY,
    course_name VARCHAR(100)
);

CREATE TABLE Enrollments (
    student_id INT,
    course_id INT,
    grade CHAR(1),
    PRIMARY KEY (student_id, course_id),
    FOREIGN KEY (course_id) REFERENCES Courses(course_id)
);

Eliminating Transitive Dependencies: Third Normal Form (3NF)

The Third Normal Form builds upon the 2NF foundation by requiring that there be no transitive dependencies within your tables. A transitive dependency happens when a non-prime attribute depends on another non-prime attribute, rather than depending directly on the primary key. For example, if a table contains a postal code that determines a city, the city is indirectly linked to the primary key through the postal code. This causes problems because updating a city name would require scanning every single record containing that postal code, which is prone to error and highly inefficient. By extracting these attributes into a separate lookup table, you ensure that every fact in a table is a fact about the primary key alone. This strict separation forces you to model dependencies explicitly, leading to a leaner, more modular database architecture that is much easier to extend as your business requirements inevitably grow and evolve over time.

-- 3NF: Separating Address data from User data to remove transitive dependencies
-- City depends on ZipCode, which is not the PK.
CREATE TABLE ZipCodes (
    zip_code VARCHAR(10) PRIMARY KEY,
    city VARCHAR(50)
);

CREATE TABLE Users (
    user_id INT PRIMARY KEY,
    name VARCHAR(100),
    zip_code VARCHAR(10),
    FOREIGN KEY (zip_code) REFERENCES ZipCodes(zip_code)
);

Logical Decoupling via Foreign Keys

At the heart of all normalization is the concept of logical decoupling, achieved primarily through the robust use of foreign key constraints. By breaking down massive, monolithic tables into smaller, normalized entities, you create a network of relationships that describe the true nature of your business data. Foreign keys are not merely safety checks; they are the connective tissue that preserves the integrity of your schema across multiple physical tables. When you isolate an attribute, you are effectively stating that this information can exist independently of other attributes, and the foreign key allows you to reconstruct that relationship whenever necessary using join operations. This strategy prevents the accidental deletion of orphaned data and ensures that the relations between your entities remain consistent. Understanding how to model these connections logically allows you to reason about how your data flows throughout the system, ensuring that changes in one entity propagate predictably and correctly across the entire database.

-- Using foreign keys to maintain referential integrity
CREATE TABLE Departments (
    dept_id INT PRIMARY KEY,
    dept_name VARCHAR(50)
);

ALTER TABLE Employees ADD COLUMN dept_id INT;
ALTER TABLE Employees ADD CONSTRAINT fk_dept 
FOREIGN KEY (dept_id) REFERENCES Departments(dept_id);

Pragmatic Normalization and Performance Trade-offs

While normalization provides a rigorous framework for data integrity, there are scenarios where pure 3NF design might lead to performance bottlenecks due to excessive joins. In read-heavy systems, you may find that joining five or six tables to retrieve a simple set of information becomes computationally expensive. Consequently, understanding normalization is not just about strictly following rules, but knowing when to deviate from them for specific business needs. This technique, often called denormalization, involves intentionally reintroducing redundancy to optimize query speed. However, this is a dangerous path if taken without deep awareness of the risks involved, such as update anomalies and data drift. When you choose to denormalize, you must implement rigorous triggers or application-level logic to ensure that your data remains synchronized. Mastery lies in the ability to balance the pure, mathematical elegance of a normalized schema with the practical requirements of your production system's performance and accessibility needs.

-- A deliberate denormalization for read-heavy performance
-- We cache the DepartmentName in the Employees table to avoid a JOIN.
CREATE TABLE Employees_Fast (
    employee_id INT PRIMARY KEY,
    name VARCHAR(100),
    dept_id INT,
    cached_dept_name VARCHAR(50) -- Redundant, but faster to read!
);

Key points

  • 1NF requires that all columns contain atomic, indivisible values to simplify data querying.
  • 2NF eliminates partial dependencies by ensuring all non-key columns rely on the entire primary key.
  • 3NF removes transitive dependencies to ensure that every column depends only on the primary key.
  • Normalization minimizes data redundancy, which significantly reduces the risk of storage anomalies.
  • Data integrity is strengthened by using foreign keys to enforce relationships between normalized tables.
  • Atomic data design prevents the need for complex string parsing during data retrieval operations.
  • Transitive dependency removal ensures that attribute changes only need to occur in one location.
  • Denormalization is a strategic performance optimization that trades storage for faster read access.

Common mistakes

  • Mistake: Thinking 1NF just means having a primary key. Why it's wrong: 1NF specifically requires atomicity (no multi-valued attributes) and a unique identifier. Fix: Ensure every column contains only atomic values and there is a defined primary key.
  • Mistake: Confusing 2NF with 3NF. Why it's wrong: 2NF deals with partial dependencies on a composite primary key, while 3NF deals with transitive dependencies of non-key attributes. Fix: Check if any non-key column depends on only part of the composite key (fails 2NF) or on another non-key column (fails 3NF).
  • Mistake: Assuming a table is in 3NF just because it has no duplicate rows. Why it's wrong: 3NF is about functional dependencies; you can have no duplicate rows but still have a non-key column determining another non-key column. Fix: Verify that every non-key column is functionally dependent only on the primary key.
  • Mistake: Trying to normalize every table to the highest possible form immediately. Why it's wrong: Over-normalization can lead to excessive joins and poor read performance in data warehousing environments. Fix: Normalize to the point where data redundancy is controlled, then assess performance needs.
  • Mistake: Thinking that if all attributes depend on the primary key, it is automatically 3NF. Why it's wrong: This ignores transitive dependencies where a non-key attribute depends on another non-key attribute, which is a violation of 3NF. Fix: Ensure no non-key attribute is determined by anything other than the primary key.

Interview questions

What is the primary objective of database normalization in SQL?

The primary objective of database normalization in SQL is to organize data within a relational database to minimize redundancy and eliminate undesirable characteristics like insertion, update, and deletion anomalies. By decomposing large, cluttered tables into smaller, logically related ones, we ensure that every piece of data is stored in exactly one place. This significantly improves data integrity, reduces the storage footprint, and ensures that modifications to the database remain consistent and reliable across the entire schema.

Can you explain the requirements for a table to be in First Normal Form (1NF)?

A table is in First Normal Form if it meets three specific criteria: it must contain only atomic, indivisible values in every column; each column must contain values of the same data type; and every row must be unique, typically enforced by a primary key. For example, in SQL, instead of storing a comma-separated list of phone numbers in one column, you should create a separate row for each phone number. This structure allows the SQL engine to efficiently query, filter, and aggregate specific data points without complex string parsing.

What is the difference between 1NF and 2NF, and how do we achieve the latter?

The transition from 1NF to 2NF requires the table to be in 1NF and to have no partial functional dependencies. This means that every non-key column must be fully functionally dependent on the entire primary key, not just a part of it. This usually applies to tables with composite primary keys. If a table has a composite key of (OrderID, ProductID), any attribute related only to the ProductID, such as ProductPrice, must be moved to a separate Products table to satisfy 2NF requirements and avoid unnecessary redundancy.

How does 3NF build upon 2NF, and what is its specific focus?

To reach 3NF, a table must first be in 2NF, and it must contain no transitive dependencies. This means that non-key columns should not depend on other non-key columns. For instance, if you have a table with 'StudentID', 'ZipCode', and 'City', the 'City' depends on the 'ZipCode', not directly on the 'StudentID'. To achieve 3NF, you would split this into two tables: one mapping students to zip codes, and another mapping zip codes to cities. This ensures that changing a city name only happens in one place, preventing anomalies.

Compare the approach of denormalization versus strict adherence to 3NF in high-read SQL environments.

Strict adherence to 3NF is ideal for transactional systems (OLTP) because it ensures data integrity and prevents update anomalies by eliminating redundancy. However, in high-read analytical environments (OLAP), frequent joins across many normalized tables can degrade performance significantly. In such cases, developers may choose to denormalize—intentionally reintroducing redundancy—to reduce the number of joins needed for complex reports. While denormalization improves read speed, it requires robust application logic or triggers to maintain data consistency, effectively trading off simplicity for query performance.

If you are given a legacy SQL table with redundant data and complex dependencies, what is your systematic process to normalize it?

I would start by identifying the candidate keys to ensure uniqueness, which establishes 1NF compliance by atomizing values. Next, I would examine the attributes to see if they rely on the whole primary key or just a part, moving partial dependencies into new tables to satisfy 2NF. Finally, I would identify transitive dependencies where non-key attributes determine other non-key attributes, moving those into distinct entities to achieve 3NF. Throughout the process, I would use 'JOIN' operations to verify that the original data can still be reconstructed without loss, ensuring the schema remains both efficient and logically sound.

All SQL interview questions →

Check yourself

1. A table contains an 'OrderItems' column that stores a comma-separated list of product IDs. Which Normal Form is violated and why?

  • A.1NF, because values must be atomic.
  • B.2NF, because of partial dependency.
  • C.3NF, because of transitive dependency.
  • D.BCNF, because of candidate key overlap.
Show answer

A. 1NF, because values must be atomic.
1NF requires that all attributes contain atomic (indivisible) values; storing multiple IDs in one cell violates this. The other options are incorrect because those forms deal with dependencies between columns rather than the atomicity of data within a column.

2. A table uses (StudentID, CourseID) as a primary key. The attribute 'InstructorOffice' is stored here, but it only depends on 'CourseID'. Which Normal Form is violated?

  • A.1NF
  • B.2NF
  • C.3NF
  • D.It is in 3NF
Show answer

B. 2NF
This violates 2NF because 'InstructorOffice' has a partial dependency on the composite key (it depends on only part of the key). 1NF is satisfied as values are atomic; 3NF is not reached because 2NF is failed; it is not in 3NF because it fails 2NF.

3. Consider a table: {OrderID, CustomerID, CustomerZipCode}. If CustomerZipCode is determined by CustomerID, which form does this violate?

  • A.1NF
  • B.2NF
  • C.3NF
  • D.This table is in 3NF
Show answer

C. 3NF
This is a transitive dependency (OrderID -> CustomerID -> ZipCode). Since ZipCode is a non-key attribute depending on another non-key attribute (CustomerID), it fails 3NF. It satisfies 1NF (atomic) and 2NF (full key dependency).

4. When moving from 2NF to 3NF, what is the primary goal regarding column relationships?

  • A.Removing all multi-valued attributes.
  • B.Ensuring every column depends only on the primary key.
  • C.Eliminating transitive dependencies between non-key attributes.
  • D.Combining all related tables into a single wide table.
Show answer

C. Eliminating transitive dependencies between non-key attributes.
3NF specifically addresses the removal of transitive dependencies. The first option is the goal of 1NF; the second is the goal of 2NF; the fourth is the opposite of normalization, which increases redundancy.

5. Which of the following scenarios best represents a table that is in 2NF but NOT in 3NF?

  • A.A table where a column depends on only part of a composite key.
  • B.A table where an attribute is not atomic.
  • C.A table where a non-key column depends on another non-key column.
  • D.A table with no primary key defined.
Show answer

C. A table where a non-key column depends on another non-key column.
If a non-key column depends on another non-key column, it has a transitive dependency, violating 3NF, but if all non-key columns depend on the full primary key, it remains in 2NF. The other options describe violations of 1NF or 2NF.

Take the full SQL quiz →

← PreviousConstraints — PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULLNext →Indexes and Query Performance

SQL

32 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app