As a software engineer, it feels very difficult to avoid interacting with data. Whether you are building a simple web application, a large-scale e-commerce system, or a microservices architecture, data is the heart of all these systems.
Many beginners jump straight into learning a framework like Laravel, Express, or Next.js, but get confused when it comes to designing database structures or writing efficient queries. This is where SQL (Structured Query Language) and the RDBMS (Relational Database Management System) system play a crucial role.
In the first article of this database guide series, we will unpack the basic concepts of SQL, understand how an RDBMS works, and immediately put into practice the process of setup a database on your local computer.
1. What Is a Relational Database and Why Does SQL Still Reign?
Before writing the first line of code, let's first understand the theoretical foundation without confusing jargon.
Relational Database (RDBMS)
A relational database is a way of organizing data into the form of tables consisting of rows (records/rows) and columns (fields/columns). Each table typically represents a single real-world entity — for example a
user, product, or transaction entity.The word relational refers to the ability of this system to connect one table with another table through a unique identifier (identifier).
-
Primary Key (PK): A unique column that identifies each row in a table (example:
id_user). -
Foreign Key (FK): Column in a table that refers to Primary Key in another table to form a relationship (example:
user_idin the tableorders).
Why SQL?
SQL is the international standard language for communicating with RDBMS. While the NoSQL wave (like MongoDB or Redis) was briefly popular for niche user cases, SQL has remained the industry standard for more than four decades for several fundamental reasons:
-
Strict Data Integrity: The RDBMS guarantees that incoming data meets certain rules (constraint).
-
ACID Compliance: Guarantees that financial transactions or crucial data are never corrupted mid-stream.
-
Declarative Language: You simply tell the database what data you want, not howdoes the algorithm retrieve it. SQL Engine which will optimize the search process.
2. Simple Architecture: Client vs. Database Server
Many novice developers imagine a database as a "huge Excel file." This analogy is not completely wrong, but it ignores the main architecture of the RDBMS, namely the Client-Server architecture.
+----------+ +----------------+
| Database Client | | Database Server |
| | TCP/IP Connection | |
| - CLI (psql/mysql)| -------------------> | - Query Engine |
| - GUI (DBeaver) | (Ports 5432 / 3306) | - Storage Engine |
| - App (Node/PHP) | <------------------ | - Transaction Manager |
+----------+ +-------------------------+
-
Database Server: A background process (background service/daemon) that manages physical storage on disk, processing memory (RAM), controls user access, and executes query.
-
Database Client: The application where we write queries. The client sends SQL commands via a network connection (usually port 5432 for PostgreSQL or 3306 for MySQL/MariaDB) to the server, then receives the results.
Understanding this separation is very important. When your application slows down in a production environment, the problem could be in two places: network transmission between the application and the database client, or slow execution of the database server.
3. Setting Up the Environment: Installing PostgreSQL and Client GUI
For practical guidance in this series of articles, we will use PostgreSQL. Why PostgreSQL? PostgreSQL is the most powerful, feature-rich (supports JSON, full-text search, even spatial features), and is the de facto standard in the modern software industry.
A. Create First Table (
B. Mengubah Struktur Tabel (
C. Menghapus Tabel atau Database (
A. Memasukkan Data (
B. Memperbarui Data (
C. Menghapus Data (
We will set up PostgreSQL using two methods: the direct way (native) and using Docker (the most recommended method for developers).
Method A: Setup Using Docker (Recommended)
If you already have Docker on your system, installing PostgreSQL is very fast and doesn't burden the local operating system with service running in the background.
Open a terminal or command prompt, then run the following command:
Bash
docker run --name postgres-dev \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=db_learn \
-p 5432:5432 \
-d postgres:16-alpine
Command Explanation:
-
--name postgres-dev: Name our containerpostgres-dev. -
-e POSTGRES_PASSWORD=secret: Sets the access password for the primary user (postgres). -
-e POSTGRES_DB=db_belajar: Automatically creates an initial database nameddb_belajar. -
-p 5432:5432: Maps port 5432 in the container to port 5432 on the local computer. -
-d postgres:16-alpine: Runs lightweight image PostgreSQL version 16 in the background.
To ensure the container is running, type the command:
Bash
docker ps
Method B: Native Setup (No Docker)
If you choose direct installation without Docker:
-
Windows / macOS: Download the official PostgreSQL installer from the site postgresql.org. Run the installation wizard, note the port (default:
5432) and the password you entered for the superuserpostgres. -
Linux (Ubuntu/Debian):
Bashsudo apt update sudo apt install postgresql postgresql-contrib sudo systemctl start postgresql
Installing Database Client GUI: DBeaver
While you can use Terminal or
psql, using a GUI (Graphical User Interface) is helpful when visualizing table relationships. DBeaver is a free, open-source option, and supports almost all database types.-
Download and install DBeaver Community Edition from dbeaver.io.
-
Open DBeaver, click the New Database Connection button (plug icon in the top left corner).
-
Select PostgreSQL.
-
Fill in the connection parameters:
-
Host:
localhost -
Port:
5432 -
Database:
db_learning(orpostgres) -
Username:
postgres -
Password:
secret(or the password you created during native installation)
-
-
Click Test Connection. If DBeaver asks to download the PostgreSQL driver, click Download.
-
Click Finish. Congratulations, you have successfully connected to the database server!
4. Your First DDL Command: Engineering Data Structures
SQL is divided into several main groups of commands. The first group that must be mastered is DDL (Data Definition Language). DDL commands are used to create, modify, or delete database schema structures (such as tables, indexes, or data types).
The three most basic DDL commands are
CREATE, ALTER, and DROP.A. Create First Table (CREATE TABLE)
Scenario: We want to create a blog application. We need the
users table to store user data and the posts table to store articles.Open SQL Editor in DBeaver (or terminal
psql), then write the following query:SQL
-- Create users table
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
full_name VARCHAR(100),
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Command Anatomy:
-
id SERIAL PRIMARY KEY:SERIALin PostgreSQL is an automatic numeric data type (auto-increment).PRIMARY KEYensures each ID is unique and cannot be empty. -
VARCHAR(50): Stores variable text up to a maximum of 50 characters. -
UNIQUE: Guarantees that no two rows can have the valueusernameoremail. -
NOT NULL: Constraint (constraint) that prohibits the column from being filled with empty values (NULL). -
DEFAULT CURRENT_TIMESTAMP: If we do not enter the current time insert, the database will fill this column with the current server time automatically.
Now, let's create a second table connected to the table
users:SQL
-- Create a posts table with relations (Foreign Key)
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(200) NOT NULL,
TEXT content,
status VARCHAR(20) DEFAULT 'draft',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- Defines Foreign Key
CONSTRAINT fk_user_posts
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE CASCADE
);
Understanding Relationships:
The
FOREIGN KEY (user_id) REFERENCES users(id) section creates a relationship rule: the value in the user_id column in the posts must refer to the id value that actually exists in the users.The
ON DELETE CASCADE clause means that if a user is deleted from the users table, all articles belong to that user in the posts akan ikut terhapus otomatis oleh sistem. Ini mencegah hadirnya data yatim-piatu (orphan data).B. Mengubah Struktur Tabel (ALTER TABLE)
Dalam siklus pengembangan aplikasi, kebutuhan fitur sering berubah. Misalkan tim produk meminta kita menambahkan kolom nomor telepon pada tabel
users. Kita tidak perlu menghapus dan membuat ulang tabel; cukup gunakan perintah ALTER:SQL
-- Menambahkan kolom baru
ALTER TABLE users
ADD COLUMN nomor_telepon VARCHAR(20);
-- Mengubah tipe data atau constraint kolom yang ada
ALTER TABLE users
ALTER COLUMN nama_lengkap SET NOT NULL;
C. Menghapus Tabel atau Database (DROP)
Jika sebuah tabel sudah tidak digunakan lagi dan ingin dihapus permanen beserta seluruh isinya:
SQL
-- Menghapus tabel posts
DROP TABLE IF EXISTS posts;
Peringatan dari Senior Engineer: PerintahDROPmenghapus struktur beserta seluruh data di dalamnya tanpa bisa di-undo. Selalu pastikan kamu berada di environment yang benar (development, bukan production) sebelum mengeksekusi perintah ini!
5. Perintah DML Dasar: Manipulasi Data
Setelah struktur tabel terbentuk menggunakan DDL, kelompok perintah berikutnya adalah DML (Data Manipulation Language). DML digunakan untuk mengelola data di dalam tabel tersebut.
A. Memasukkan Data (INSERT INTO)
Mari kita masukkan beberapa baris data ke dalam tabel
users:SQL
-- Memasukkan satu baris data
INSERT INTO users (username, email, nama_lengkap)
VALUES ('budi_dev', '[email protected]', 'Budi Santoso');
-- Memasukkan banyak baris sekaligus (Batch Insert)
INSERT INTO users (username, email, nama_lengkap)
VALUES
('siti_coder', '[email protected]', 'Siti Rahma'),
('joko_backend', '[email protected]', 'Joko Susilo');
Selanjutnya, mari tambahkan artikel ke tabel
posts menggunakan user_id dari pengguna yang baru kita buat (misalnya id 1 untuk Budi):SQL
INSERT INTO posts (user_id, judul, konten, status)
VALUES
(1, 'Panduan Belajar Docker untuk Pemula', 'Docker sangat mempermudah setup...', 'published'),
(1, 'Tips Menguasai SQL Cepat', 'Langkah pertama belajar SQL adalah...', 'draft'),
(2, 'REST API vs GraphQL: Pilih Mana?', 'Dalam arsitektur modern...', 'published');
B. Memperbarui Data (UPDATE)
Bagaimana jika Siti ingin mengganti nama lengkapnya, atau Budi ingin mengubah status artikelnya dari
draft menjadi published?SQL
-- Memperbarui data pengguna
UPDATE users
SET nama_lengkap = 'Siti Rahmawati'
WHERE username = 'siti_coder';
-- Memperbarui status artikel
UPDATE posts
SET status = 'published'
WHERE id = 2;
Aturan Emas Perintah UPDATE & DELETE:JANGAN PERNAH menjalankan perintahUPDATEatauDELETEtanpa klausulWHERE, kecuali kamu memang sengaja ingin mengubah atau menghapus SELURUH baris data di dalam tabel tersebut.
Kesalahan klasik pengembang pemula: MenulisUPDATE users SET nama_lengkap = 'Siti';tanpaWHERE. Akibatnya, seluruh pengguna di aplikasi kamu akan berubah namanya menjadi 'Siti'!
C. Menghapus Data (DELETE)
Untuk menghapus baris data spesifik yang memenuhi kondisi tertentu:
SQL
-- Menghapus artikel yang berstatus draft milik user tertentu
DELETE FROM posts
WHERE status = 'draft' AND user_id = 1;
6. Desain Database & Anti-Pattern yang Wajib Dihindari Pemula
Membuat tabel itu mudah, tetapi merancang struktur yang aman, teratur, dan mudah dikembangkan butuh latihan. Berikut beberapa kesalahan umum (anti-pattern) yang sering dilakukan pengembang di awal karirnya:
+-------------------------------------------------------------------------+
| DESAIN BAD VS GOOD PRACTICE |
+-------------------------------------------------------------------------+
| BAD: Menyimpan banyak data dalam satu kolom dipisah koma |
| Tabel: users | Kolom: hobi -> "membaca, berenang, coding" |
| |
| GOOD: Menggunakan tabel relasi terpisah (Normalization) |
| Tabel: users_hobbies | Kolom: user_id, hobi_name |
+-------------------------------------------------------------------------+
| BAD: Menggunakan nama kolom yang ambigu |
| Tabel: orders | Kolom: date, name, status |
| |
| GOOD: Menggunakan nama yang spesifik & eksplisit |
| Tabel: orders | Kolom: order_date, customer_name, order_status |
+-------------------------------------------------------------------------+
Checklist Desain Skema untuk Pemula:
-
Gunakan Naming Convention yang Konsisten: Gunakan nama tabel jamak atau tunggal secara konsisten (disarankan menggunakan kata benda bahasa Inggris gaya
snake_case, contoh:user_profiles,order_items). -
Jangan Pernah Menyimpan Password Secara Plain-Text: Kolom kata sandi harus berukuran cukup panjang (misal
VARCHAR(255)) untuk menyimpan hasil enkripsi hash (seperti Bcrypt atau Argon2) dari sisi aplikasi. -
Selalu Sertakan Timestamp: Menambahkan kolom
created_atdanupdated_atdi hampir setiap tabel akan sangat membantu proses debugging dan audit data di kemudian hari. -
Pilih Tipe Data yang Tepat: Jangan gunakan
VARCHAR(255)untuk semua hal. Jika kolom hanya berisi nilaiTRUE/FALSE, gunakanBOOLEAN. Jika berisi tanggal, gunakanDATEatauTIMESTAMP. Pemilihan tipe data yang presisi menghemat penggunaan RAM dan ruang penyimpanan disk secara signifikan.
Langkah Selanjutnya
Selamat! Kamu telah menyelesaikan langkah pertama dalam perjalanan menguasai SQL. Kamu sudah memahami konsep arsitektur RDBMS, berhasil memasang server PostgreSQL lokal menggunakan Docker, terhubung melalui GUI Client DBeaver, serta mampu mengeksekusi perintah dasar DDL (
CREATE, ALTER, DROP) dan DML (INSERT, UPDATE, DELETE).Struktur basis data kita sudah siap. Namun, bagaimana cara kita mengambil kembali data yang sudah disimpan dengan berbagai variasi kondisi, filter, dan fungsi analisis?
Pada Artikel 2: SELECT, WHERE, dan Filtering Data, kita akan menyelami teknik mengekstraksi data secara presisi menggunakan berbagai operator logika, pencarian pola teks, hingga penanganan data kosong (
NULL).
Sigit Wasis Subekti
Software Engineer & Tech Educator
Software Engineer and Tech Educator sharing insights on web development and software architecture.