Skip to content
    SeaCode
    Learning tracksCode ArenaWorkshops & EventsInstructors
    Log inSign up
    SQLSQL

    First questions to the data

    • What are SQL and databases?
    • SELECT: choosing columns
    • WHERE: filtering rows
    • ORDER BY and LIMIT: sort and take the top

    Summarizing and grouping

    • Aggregates: COUNT, SUM, AVG
    • GROUP BY and HAVING
    • CASE, COALESCE and text functions

    Joining tables

    • Keys and relationships
    • INNER JOIN
    • LEFT JOIN: leave nobody out
    • Three-table joins and self joins
    • Subqueries and CTEs

    Building tables and changing data

    • CREATE TABLE and constraints
    • INSERT, UPDATE and DELETE
    • Transactions: all or nothing
    • SQL injection: the most dangerous mistake

    Professional level

    • Indexes: why is my query slow?
    • Window functions: rankings and totals without losing rows
    • Designing tables: normalization
    • Project: analytics for a learning platform
    SQL

    Professional level · Lesson 19 of 20

    Designing tables: normalization

    Why one big table goes wrong, and 1NF, 2NF and 3NF without the jargon.

    10 minutes2 games

    This table keeps everything in one place. It looks convenient, but run the query and see the problem:

    SQL
    SELECT student, city, course FROM enrollments_flat WHERE student = 'Nour';
    
    -- Which city does Nour live in?
    SELECT DISTINCT city FROM enrollments_flat WHERE student = 'Nour';

    Nour's city is stored twice, once wrongly (Gizah). Repeated facts drift apart over time. There are three classic problems:

    • Update anomaly: if Nour moves, every row of hers must change; miss one and the data contradicts itself.
    • Insert anomaly: you can't add a new course until someone enrolls in it.
    • Delete anomaly: delete the last React enrollment and the course's price is lost with it.
    FormThe rule, simply

    1NF

    one value per cell, no repeating columns like course1, course2

    2NF

    every column depends on the whole key, not part of it

    3NF

    no column depends on another non-key column (the city belongs to the student, not the enrollment)

    One sentence sums them up: store each fact once, in the table it describes.

    The fix is the design we've used all along: students holds the city, courses holds the price, and enrollments holds only what belongs to the enrollment itself (progress and the date).

    Important

    Denormalization (deliberate repetition) is sometimes right: reporting tables, a counter like total_students on courses to avoid recounting, or the course price at purchase time on invoices (because it can change later). What matters is that it's a conscious choice with one source of truth.

    Exercise

    In enrollments_flat: find students whose city is recorded in more than one way. Show student and the number of different cities as cities.

    Expected result:
    student | cities
    Nour | 2
    SQL
    SELECT student
    FROM enrollments_flat
    

    Quick question

    In the flat table, what does course_price really depend on?

    Interview question

    Explain normalization. When would you denormalize?

    Learn more from

    • Wikipedia: Database normalizationen.wikipedia.org
    • Wikipedia: Third normal formen.wikipedia.org
    • PostgreSQL docs: Foreign keyspostgresql.org

    Played 0 of 2 games

    Sign in to save your progress and earn XP.

    PreviousWindow functions: rankings and totals without losing rowsNextProject: analytics for a learning platform
    SeaCode

    Learn to code for real, online or at our branch in front of Cairo University, Giza.

    Learn

    • All courses
    • Interactive tutorials
    • Interview practice problems
    • Mock interview
    • Learning tracks
    • Code Arena
    • Workshops & Events
    • Knowledge library
    • Team projects

    Your account

    • Log in
    • Sign up
    • Learning plan
    • Certificates
    • Site map

    Contact us

    • WhatsApp
    • 010 9094 1104
    • In front of Cairo University, Giza

    © 2026 SeaCode. All rights reserved.