PostgreSQL in 10 Minutes: Install, Create a Database, and Run Your First Query
Install PostgreSQL on Linux, macOS, or Windows, connect with psql, create your first database, and run real SQL queries. Built for absolute beginners.
I still remember the first time I opened a database tutorial. The page jumped straight into SELECT * FROM users and I sat there thinking, "But where did this database come from?" Everyone assumed I already had one running. I did not. So I closed the tab and searched "how to install PostgreSQL" instead. That small gap — between wanting to learn SQL and actually having a database to practice on — is what this post closes.
A few years later I tried to keep track of my freelance clients in a spreadsheet. At first it was simple: name, phone, project status. Then I wanted to add notes, then payment dates, then the last time I contacted each person. Within a month the sheet had duplicate names, missing phone numbers, and a row that said "Carol??" with no other information. I had a lot of data and no clean way to ask questions of it.
That mess is the exact problem a database solves.
In the next 10 minutes you will install PostgreSQL, open its command-line tool psql, build a small phone book database, and learn how to add, read, update, and delete real records. No Docker, no cloud account, and no assumptions about what you already know.
Why your notebook turns into a mess
Imagine you are keeping a paper phone book for your friends. You write one name per line: Alice, Bob, Carol. Next to each name you add a phone number and an email. So far so good.
Then Bob changes his number. You cross out the old one and write the new one in the margin. Then Carol gets a second email. You squeeze it next to the first. Then you add a friend you met twice but forget whether you already wrote the name. The book starts to look like this:
Alice - 555-0101 - alice@example.com
Bob - 555-0102 crossed out, new: 555-0199 - bob@example.com
Carol - 555-0103 - carol@example.com, carol.work@example.com
Alice? - 555-0101 - ???This is what happens when data grows without rules. A database gives you those rules. It stores data in one trusted place, makes sure names do not repeat by accident, and lets you ask clear questions like "What is Bob's phone number?" or "Who has more than one email?"
How a database organizes the mess
The paper phone book has a structure we already understand, so let us use it as our mental model.
- The whole book is the database. It is the container that holds everything.
- Each section of the book — Friends, Family, Work — is a table. A table holds one kind of thing.
- Each person in a section is a row. A row is one complete record.
- The details you store about each person — name, phone, email — are columns. Every row in a table has the same columns.
So a database is not a mysterious black box. It is an organized phone book with a strict librarian. The librarian is called a database engine, and the engine we are going to use is PostgreSQL.
PostgreSQL stores the book, makes sure the rules are followed, and answers your questions fast. But you do not talk to PostgreSQL directly. You use a command-line tool called psql — think of it as the phone you use to call the librarian.
Install PostgreSQL
PostgreSQL is the engine. psql comes with it, so installing PostgreSQL gives you both.
Already have PostgreSQL?
Open a terminal and run psql --version. If you see a version number like psql (PostgreSQL) 16.x, you are done with this section. Skip to the next one.
Pick your operating system below and follow the steps. If a command finishes without an error, move to the next one.
On Ubuntu and Debian, run:
sudo apt update
sudo apt install postgresql postgresql-contribsudo apt updaterefreshes the list of available packages so your system can find the latest PostgreSQL version.sudo apt install postgresql postgresql-contribinstalls the PostgreSQL server, thepsqlcommand-line tool, and some useful extra utilities.
On Fedora, run:
sudo dnf install postgresql-server postgresql-contrib
sudo postgresql-setup --initdbsudo dnf install postgresql-server postgresql-contribinstalls the server and extra tools.sudo postgresql-setup --initdbcreates the initial data directory PostgreSQL needs before it can run.
After installation, check that psql is available by running psql --version. You should see something like psql (PostgreSQL) 16.x.
Start PostgreSQL and open psql
The phone book is on the shelf, but the librarian is not awake yet. PostgreSQL runs as a background service; we need to start it before psql can connect.
Start the service:
sudo systemctl start postgresqlThis starts the PostgreSQL background process so it can accept connections.
Enable it so it starts automatically on boot:
sudo systemctl enable postgresqlThis registers PostgreSQL as a service that starts automatically whenever your computer boots.
Connect as the default postgres user:
sudo -u postgres psqlThis opens psql as the built-in postgres administrative user, which is created during installation.
Once connected, your prompt will look something like this:
sunilkalikayi@sumeruinfra-Latitude-3420:~$ sudo -u postgres psql psql (16.14 (Ubuntu 16.14-0ubuntu0.24.04.1)) Type "help" for help.
postgres=#
That postgres=# prompt means psql is ready. The word before the = is the database you are currently using. Right now it is the default postgres database.
Here are the four psql commands you need to survive:
| Command | What it does |
|---|---|
\l | List all databases |
\c name | Connect to a database called name |
\dt | List all tables in the current database |
\q | Quit psql |
Try the first one:
\lYou will see a list of databases that already exist. postgres is one of them. Do not worry about the others.
Create your first database and table
Let us make our own database called playground. We will use it for experiments, and we can delete it later without breaking anything.
CREATE DATABASE playground;This creates a new empty database named playground where you can store tables and data.
Switch into it:
\c playgroundThis switches your active connection from the postgres database to playground. The prompt will change to reflect this.
Your prompt should now say:
playground=#
Which database am I using?
Notice the prompt changed from postgres=# to playground=#. The word before the = always tells you which database is currently active.
Now create a table called students. Think of it as a phone book page where each row is one student.
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);Let us break that down in plain words:
CREATE TABLE studentsmakes a new table namedstudents.idis the row identifier.SERIALtells PostgreSQL to automatically assign the next number for each new row.PRIMARY KEYmeans everyidmust be unique. It is how PostgreSQL quickly finds a specific row, like an index in a book.namestores the student's name.VARCHAR(100)means text up to 100 characters.NOT NULLmeans this field cannot be empty.emailstores an email address.TEXTis another text type with no strict length limit.created_atstores the time the row was created.DEFAULT CURRENT_TIMESTAMPtells PostgreSQL to fill it automatically.
Confirm the table exists:
\dtThis lists all tables in the current database. You should see students in the list.
Insert, read, update, and delete data
A table without rows is just an empty spreadsheet. Let us add three students.
INSERT INTO students (name, email) VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com'),
('Carol', 'carol@example.com');This adds three new rows to the students table in one command.
The database should respond with:
INSERT 0 3
That means three rows were inserted.
Read all the rows
Now read them back:
SELECT * FROM students;SELECT * means "give me every column." The FROM clause tells PostgreSQL which table to read from.
You should see something like this:
id | name | email | created_at ----+-------+-------------------+------------------------- 1 | Alice | alice@example.com | 2026-08-18 10:00:00.123 2 | Bob | bob@example.com | 2026-08-18 10:00:01.456 3 | Carol | carol@example.com | 2026-08-18 10:00:02.789 (3 rows)
Your created_at values will be the exact time you ran the command, so they will differ from the example.
Read only specific columns
You do not always need every column. If you only want names, ask for names:
SELECT name FROM students;Filter rows
If you only want Alice's row, use WHERE:
SELECT * FROM students WHERE name = 'Alice';WHERE is the filter clause. It tells PostgreSQL, "Only give me rows that match this condition." You should see just Alice:
id | name | email | created_at ----+-------+-------------------+------------------------- 1 | Alice | alice@example.com | 2026-08-18 10:00:00.123 (1 row)
Update a row
Phone books need corrections. Databases do too.
Suppose Alice changes her email. You do not delete the row and recreate it. You update it:
UPDATE students
SET email = 'alice.new@example.com'
WHERE name = 'Alice';This finds the row where name is 'Alice' and changes only that row's email. Every other row stays untouched.
The response will be:
UPDATE 1
Verify the change:
SELECT * FROM students WHERE name = 'Alice';You should see Alice's updated email:
id | name | email | created_at ----+-------+-----------------------+------------------------- 1 | Alice | alice.new@example.com | 2026-08-18 10:00:00.123 (1 row)
Warning
Never run UPDATE without a WHERE clause on a real table. UPDATE students SET email = 'x' would change every row in the table.
Delete a row
If you want to remove Bob from the table:
DELETE FROM students WHERE name = 'Bob';This removes the row where name is 'Bob'. Only matching rows are deleted.
Verify:
SELECT * FROM students;Bob should be gone. The output should now show only Alice and Carol:
id | name | email | created_at ----+-------+-----------------------+------------------------- 1 | Alice | alice.new@example.com | 2026-08-18 10:00:00.123 3 | Carol | carol@example.com | 2026-08-18 10:00:02.789 (2 rows)
Warning
DELETE without WHERE removes every row. Always double-check your WHERE clause before pressing Enter.
Recap and next steps
While learning, you will create messy tables and want to start over. The safest way to practice is to drop the practice table and recreate it.
DROP TABLE IF EXISTS students;This deletes the students table entirely. The IF EXISTS part prevents an error if the table was already deleted. Now you can run the CREATE TABLE and INSERT commands again and repeat the exercises. The database itself stays alive, so you do not need to reinstall anything.
You now have a local PostgreSQL server, a playground database, and a students table you can create, fill, read, update, and delete. That is the foundation every SQL skill builds on.
The next natural step is to add a second table. Once you have two tables, you can ask questions like "Which students have scores?" and "Which students have no scores?" Those questions are answered with JOINs, and that is exactly what the next post covers.
🎯 What is in my hands now!
- PostgreSQL is the database engine;
psqlis the command-line tool that talks to it. - Install PostgreSQL with your OS package manager, start the service, then connect with
psql. \l,\c,\dt, and\qare the psql commands you will use most.CREATE DATABASEmakes a database;CREATE TABLEdefines the shape of one kind of record.INSERTadds rows,SELECTreads them,UPDATEchanges them, andDELETEremoves them.- Always use a
WHEREclause withUPDATEandDELETE. DROP TABLE IF EXISTSlets you reset your playground without reinstalling PostgreSQL.
“Do not lose your peace of mind for anyone or anything.”
— Gurudev Sri Sri Ravi Shankar Ji.
