Hello! Welcome to your third lesson.
In our first two lessons, we established the fundamental "why" of databases. We saw the shortcomings of file systems and then learned how a Database Management System (DBMS) provides a robust solution through the ACID properties, solving critical problems of data integrity, concurrent access, and recovery.
Today, we address the next logical question: How do we communicate with a DBMS? This lesson tackles a core concept that you specifically wanted to understand—the distinction between the languages we use for general programming and the languages we use to query databases.
Your background in C gives you a significant head start, as you're already fluent in one of the two paradigms we'll discuss. By the end of this lesson, you will be able to distinguish between declarative languages (like SQL) and procedural/imperative languages (like C). Understanding this difference is not just theoretical; it's the key to thinking effectively in SQL.
The Core Idea: "What" vs. "How"
At its heart, the difference between these two programming paradigms is simple:
- Imperative / Procedural Programming tells the computer how to accomplish a task. You provide a sequence of explicit, step-by-step commands.
- Declarative Programming tells the computer what you want to achieve. You describe the desired result, and the system figures out how to produce it.
This might seem abstract, so let's start with a video that uses excellent real-world analogies to make this distinction clear.
Imperative vs Declarative Programming
This video from ui.dev, titled 'Imperative vs Declarative Programming,' provides a fantastic, non-technical introduction to the topic. Pay close attention to the restaurant analogy and how it translates to code.
Watch from the beginning to 01:13 to grasp the core analogy. Then, jump to 03:36 and watch until 04:15, where it specifically discusses SQL as a declarative language.
As the video illustrates, asking for a "table for two" is declarative. You state your desired outcome. Giving a step-by-step route to a specific empty table is imperative. You're defining the process.
The Imperative Paradigm: Your Comfort Zone
Given your experience with C, the imperative paradigm is your native tongue. When you write a C program, you are meticulously controlling the execution flow.
Think about a simple task: finding the maximum value in an array of integers. In C, you would write a function that:
- Initializes a variable, let's call it
max_val, to the first element of the array. - Starts a
forloop that iterates from the second element to the end of the array. - Inside the loop, it performs an
ifcheck to compare the current element withmax_val. - If the current element is larger, it updates
max_val. - After the loop finishes, it returns
max_val.
Every single step is explicitly defined by you. You manage the state (the max_val variable, the loop counter) and control the flow (the loop and the conditional).
This "cookbook recipe" approach is the essence of imperative programming. To explore this idea with a fun analogy, please read the following short section.
The Data Engineers Guide to Declarative vs Imperative for ...
The article 'The Data Engineers Guide to Declarative vs Imperative' uses a great analogy of making a peanut butter and jelly sandwich to explain imperative thinking. It highlights how much detail is required when the system (the 'sandwich maker') has no context.
Read the section titled 'Definition of Imperative Programming' and the sub-section 'Making a Peanut Butter and Jelly Sandwich with Imperative Programming'.
The Declarative Paradigm: Speaking to the Database
Now, let's switch gears. SQL is a declarative language. You don't tell the database how to retrieve data; you only describe what data you want.
Let's use a visual to make this concrete. The image below contrasts the procedural, step-by-step approach (similar to how you'd code it in C) with the concise, declarative SQL approach for the same task.

As you can see, the SQL query SELECT name FROM users WHERE age >= 18; simply declares the properties of the data we want: the name column from the users table where the age is 18 or greater. We have no idea if the database is using an index, scanning the whole table, or how it's organizing the retrieval. We don't need to know.
This video clip focuses specifically on how this applies to database queries.
How do Databases Work? | System Design
This clip from the 'How do Databases Work?' video by Interview Pen directly explains why SQL is declarative and contrasts it with a hypothetical imperative query.
Watch the clip from 00:35 to 01:47. Note the difference between the declarative SQL statement and the imperative statement that specifies how to perform the join and scan.
Unveiling the "Magic": How Does Declarative Work?
This is where your interest in low-level systems comes into play. It's natural to ask: if I only tell the database what I want, how does it figure out how to get it? Does it just guess?
The answer is no. This is where a critical component of the DBMS comes in: the Query Optimizer.
The best analogy for a query optimizer is a GPS navigation app like Google Maps.
- You provide a declarative goal: "I want to go to 221B Baker Street."
- The GPS acts as a declarative compiler. It looks at your current state (your location), the desired end state (the address), and a vast amount of pre-programmed information (road maps, traffic data, speed limits).
- It then generates an imperative plan: a step-by-step list of directions ("Turn left in 200 feet," "Merge onto the highway," etc.) to get you there efficiently.
The database's query optimizer does the exact same thing for your SQL query. It takes your declarative SQL, analyzes the database's current state (what tables exist, what indexes are available, how large the tables are), and generates an efficient imperative "execution plan" to retrieve your data.
The following resource explains this relationship perfectly.
The Data Engineers Guide to Declarative vs Imperative for ...
This article, 'The Data Engineers Guide...', explains the crucial relationship between declarative and imperative programming. It argues they are not opposites, but that declarative is an abstraction built on top of imperative.
Read the sections 'What is the Relationship between Declarative and Imperative?' and 'Declarative Programming Requires Declarative Compilers'. This will connect the dots between your declarative SQL query and the imperative steps the database actually executes.
This abstraction is incredibly powerful. It allows you to focus on the logic of your data needs, while the DBMS team at companies like Oracle or Microsoft/PostgreSQL contributors spend decades perfecting query optimizers to handle the performance details.
A Structured Comparison
To solidify your understanding, let's look at a structured breakdown of the key differences. The table below summarizes the concepts we've discussed.

For a more detailed textual breakdown of these points, the following article is an excellent reference.
Declarative vs. Imperative Programming: 4 Key Differences
The article 'Declarative vs. Imperative Programming: 4 Key Differences' from Codefresh provides a clear, structured comparison that will be valuable for your logical learning style.
Read the main section 'Declarative vs. Imperative Programming: 4 Key Differences', focusing on the four numbered points: Syntax, Abstraction Level, State Management, and Control Flow.
Test your understanding!
Imagine you need to get a list of all product names that cost more than $50 from a products table.
- In plain English, briefly describe the imperative steps you might tell a computer to follow.
- Now, in plain English, write the declarative statement of what you want.
Show answer
-
Imperative (How):
- Open the
productstable. - Create an empty list to store the results.
- Go to the first row.
- Check if the value in the 'price' column is greater than 50.
- If it is, take the value from the 'name' column and add it to your list.
- Move to the next row and repeat until you've checked all rows.
- Return the list.
- Open the
-
Declarative (What):
- Give me the names of all products where the price is greater than $50.
Notice how the declarative version is exactly what you'd write in SQL: SELECT name FROM products WHERE price > 50;.
Conclusion
Today we've bridged the gap between the "why" of a DBMS and the "how" of communicating with one. You've learned the fundamental difference between the imperative paradigm you know from C and the declarative paradigm used by SQL.
Key Takeaways:
- Imperative/Procedural programming (like C) specifies the step-by-step instructions on how to perform a task. You manage the control flow and state explicitly.
- Declarative programming (like SQL) describes what result you want to achieve, leaving the "how" to the system.
- This is not magic. A sophisticated component, the Query Optimizer, acts as a translator, converting your declarative request into an efficient, imperative execution plan.
- This abstraction is a core benefit of using a DBMS, allowing you to focus on data logic rather than low-level retrieval mechanics.
Preview of the Next Lesson:
We've now established the foundational concepts of why we use a DBMS and the paradigm we use to talk to it. In the next lesson, we will officially begin our journey into SQL. We'll start by understanding the core structure of a relational database—tables, rows, and columns—and write our very first SELECT statements to retrieve data.