SQL Fundamentals and CRUD Operations

My journey from data loss nightmares to mastering SQL operations


Table of Contents


Introduction: The Week I Lost Everything

I'll never forget the Monday morning I opened my Excel spreadsheet with 127 blog posts, three months of meticulous work, and saw this:

My heart sank. I had no backup. No version control. Just hope that maybe, somehow, I could recover the file.

I tried every recovery tool I could find. Nothing worked. A week of blog drafts, carefully organized categories, scheduled publication dates—all gone. That moment of staring at an error message taught me a brutal lesson: if you care about your data, you need a real database.

That's when I committed to learning SQL properly. Not just creating tables, but understanding CRUD operations—the fundamental ways you interact with data. The "CRUD" operations (Create, Read, Update, Delete) became my new religion, and PostgreSQL became my sanctuary.

Let me share what I learned about managing data the right way, so you never have to experience that sinking feeling of lost work.

Understanding CRUD: The Foundation

CRUD is an acronym that represents the four basic operations you can perform on data:

  • Create: Adding new data (INSERT)

  • Read: Retrieving data (SELECT)

  • Update: Modifying existing data (UPDATE)

  • Delete: Removing data (DELETE)

Every application you've ever used—whether it's social media, email, or banking—relies on these four operations. Master CRUD, and you understand how data flows through systems.

How SQL Queries Flow Through PostgreSQL

Here's what happens when you run a query:

spinner

Understanding this flow helped me write better queries. The planner is smart, but giving it good data structures (proper types, indexes) makes it even faster.

CREATE: Building Better Tables

In Part 1, we created a simple posts table. Now let's build it properly with auto-incrementing IDs, constraints, and defaults.

The SERIAL Data Type: Auto-Incrementing IDs

My first tables had manual ID management. I'd insert id=1, then id=2, etc. This is tedious and error-prone. Enter SERIAL:

Breaking Down the Improvements

Let's understand what each change accomplishes:

id SERIAL PRIMARY KEY

  • SERIAL automatically generates sequential numbers (1, 2, 3...)

  • No more manual ID management!

  • Internally creates a sequence object

title VARCHAR(200) NOT NULL

  • Limited to 200 characters (prevents novels as titles)

  • NOT NULL ensures every post has a title

  • More efficient storage than TEXT for short strings

slug VARCHAR(200) UNIQUE NOT NULL

  • URL-friendly identifier (e.g., "my-first-post")

  • UNIQUE ensures no two posts have the same slug

  • Perfect for clean URLs: /blog/my-first-post

published BOOLEAN DEFAULT false

  • Explicitly tracks draft vs published state

  • Defaults to false (draft) if not specified

  • Better than checking if a publish_date exists

view_count INTEGER DEFAULT 0

  • Tracks page views

  • Starts at 0 automatically

  • Can be incremented on each visit

created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

  • Automatically set to current time on insert

  • No more manual date entry!

  • Includes time, not just date

updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

  • Will be updated via trigger or application code

  • Tracks last modification time

Creating the Authors Table

Now let's add an authors table (we'll connect them in Part 3):

Verification

Always verify your table structure:

INSERT: Adding Data the Right Way

With our improved schema, inserting data becomes much easier.

Basic INSERT with Auto-Incrementing ID

INSERT with RETURNING Clause

One of my favorite PostgreSQL features—see what you just inserted:

This is incredibly useful when you need the generated ID for your application.

INSERT Multiple Rows Efficiently

INSERT with Conflict Handling (UPSERT)

What if you try to insert a duplicate slug? Here's how to handle it:

This is called an "UPSERT" (UPDATE or INSERT). It prevented countless errors in my applications.

Inserting Authors

SELECT: Querying Like a Pro

SELECT is where SQL truly shines. Let's move beyond simple queries.

Basic SELECT Patterns

Filtering with WHERE

Pattern Matching with LIKE

Sorting with ORDER BY

Limiting and Pagination

Checking for NULL Values

Combining Conditions

UPDATE: Modifying Data Safely

UPDATE is powerful but dangerous. One mistake and you could modify all your data.

Basic UPDATE

The Critical Importance of WHERE

⚠️ WARNING: This updates EVERY row!

Always use WHERE unless you truly want to update every row:

Updating Multiple Columns

Increment a Counter

UPDATE with RETURNING

See what you changed:

Conditional UPDATE

UPDATE Based on Calculation

DELETE: Removing Data Responsibly

DELETE is even more dangerous than UPDATE. There's usually no undo.

Basic DELETE

The WHERE Clause is CRITICAL

⚠️ DANGER: This deletes EVERYTHING!

Always use WHERE:

DELETE with RETURNING

See what you deleted:

Soft Deletes (My Preferred Approach)

Instead of actually deleting, mark as deleted:

Soft deletes saved me multiple times when I accidentally "deleted" important data.

Aggregate Functions: Analyzing Your Data

Aggregate functions let you analyze data across multiple rows.

COUNT: How Many?

SUM: Add It Up

AVG: Find the Average

MIN and MAX: Extremes

Combining Aggregates

GROUP BY: Organizing Results

GROUP BY lets you aggregate data by category.

Basic Grouping

GROUP BY with Multiple Aggregates

Filtering Groups with HAVING

HAVING is like WHERE, but for groups:

WHERE vs HAVING

Group by Date

Advanced Grouping Example

Improving Our Blog Schema

Let's create a complete, production-ready schema with everything we've learned:

Understanding Constraints

CHECK Constraints enforce business rules:

If you try to violate these, PostgreSQL will reject the operation:

Understanding Indexes

Indexes make queries fast. We'll dive deep in Part 4, but here's the basics:

Real-World Query Patterns

Here are queries I use constantly in real applications:

Latest Published Posts (Blog Homepage)

Search by Title or Content

Content Analytics Dashboard

Posts Needing Attention (Low Views)

Common Mistakes and How to Avoid Them

Mistake 1: Forgetting WHERE in UPDATE/DELETE

My rule: Always write SELECT first, then convert to UPDATE/DELETE:

Mistake 2: Using = NULL Instead of IS NULL

Mistake 3: Not Using Transactions for Multiple Changes

Mistake 4: Ignoring Data Types

Mistake 5: Not Using LIMIT on Large Tables

What I Learned About SQL

Looking back at my journey from Excel corruption to SQL mastery, here are my key insights:

1. SQL is a Conversation with Your Data

At first, SQL felt like typing commands into a black box. Then I realized: you're having a conversation. "Hey PostgreSQL, SELECT (show me) the title (these fields) FROM posts (from this table) WHERE published = true (that meet this criteria)."

2. Start with SELECT, Always

Before any UPDATE or DELETE, I always write a SELECT query first. Verify I'm targeting the right rows, then modify the query. This habit has saved me countless times.

3. SERIAL Changed Everything

Auto-incrementing IDs freed my mind. No more manually tracking the next ID number. No more duplicate ID errors. Just let the database handle it.

4. Defaults and Constraints Are Your Friends

DEFAULT CURRENT_TIMESTAMP means I never forget to set created_at. NOT NULL prevents incomplete data. CHECK constraints enforce business rules. These aren't restrictions—they're guardrails that prevent mistakes.

5. PostgreSQL Error Messages Are Actually Helpful

Unlike some systems that give cryptic errors, PostgreSQL tells you exactly what went wrong:

Read the error. It's usually telling you exactly how to fix it.

6. RETURNING is Magical

The ability to see what you just inserted/updated/deleted in one query is incredibly powerful. Use it!

Next Steps

Congratulations! You've mastered CRUD operations, the foundation of all database work. You now understand:

✅ Creating tables with proper types, defaults, and constraints ✅ Inserting data efficiently with SERIAL and RETURNING ✅ Querying with WHERE, ORDER BY, LIMIT, and pagination ✅ Updating data safely with proper WHERE clauses ✅ Deleting responsibly (and why soft deletes are better) ✅ Aggregate functions (COUNT, SUM, AVG) ✅ Grouping and analyzing data with GROUP BY ✅ Real-world query patterns

But we still have a major limitation: our tables exist in isolation. We can't:

  • Link posts to their authors

  • Connect posts to categories

  • Track comments on posts

  • Ensure referential integrity

In Part 3: Relationships and Data Integrity, we'll learn:

  • Foreign keys and how they work

  • One-to-many relationships (authors → posts)

  • Many-to-many relationships (posts ↔ categories)

  • JOIN operations to query related data

  • CASCADE deletion and referential integrity

  • Transactions and ACID properties

  • Indexing for performance

The journey continues! 🚀


Practice Exercise: Before moving to Part 3, try this:

  1. Add an author_id column to the posts table

  2. Insert some authors

  3. Update posts to link them to authors

  4. Write a query to find all posts by a specific author

  5. Try to delete an author and see what happens

These exercises will prepare you perfectly for understanding relationships!

Last updated