Mengenal PostgreSQL
RDBMS
Menyimpan data relasional dengan dukungan transaksi dan constraint yang kuat.
Open Source
Dapat digunakan dan dikembangkan secara terbuka.
Standar SQL
Mendukung banyak fitur SQL standar dan ekstensi modern.
Extensible
Mendukung tipe data, function, operator, dan extension tambahan.
psql, pgAdmin, koneksi, dan database awal
psql
Perintah meta
\c akademik
\dn
\dt
\d siswa
\q
Database awal
COMMENT ON DATABASE akademik IS 'Database pembelajaran';
Database, schema, search_path, dan organisasi objek
Membuat schema
CREATE SCHEMA keuangan;
SET search_path TO sekolah, public;
Nama lengkap objek
SELECT * FROM keuangan.pembayaran;
Schema membantu memisahkan modul dan menghindari benturan nama tabel.
Tipe data PostgreSQL yang kaya
| Tipe | Kegunaan |
|---|---|
| INTEGER / BIGINT | Bilangan bulat |
| NUMERIC(p,s) | Desimal presisi |
| VARCHAR / TEXT | Teks |
| BOOLEAN | TRUE/FALSE |
| DATE | Tanggal |
| TIMESTAMP / TIMESTAMPTZ | Tanggal dan waktu |
| UUID | Identitas universal |
| JSONB | Dokumen JSON terstruktur |
| TEXT[] / INTEGER[] | Array |
| INET | Alamat jaringan |
Membuat struktur yang aman
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
nis VARCHAR(20) NOT NULL UNIQUE,
nama VARCHAR(100) NOT NULL,
nilai NUMERIC(5,2) CHECK (nilai BETWEEN 0 AND 100),
aktif BOOLEAN DEFAULT TRUE,
profil JSONB DEFAULT '{}'::jsonb,
minat TEXT[] DEFAULT ARRAY[]::TEXT[],
created_at TIMESTAMPTZ DEFAULT now()
);
INSERT, SELECT, UPDATE, DELETE, dan RETURNING
VALUES ('2026001','Alya',88)
RETURNING id,nis,nama,nilai;
FROM sekolah.siswa
WHERE aktif IS TRUE
ORDER BY nilai DESC;
SET nilai=90, profil=profil || '{"status":"unggul"}'::jsonb
WHERE id=1
RETURNING *;
WHERE id=1
RETURNING id,nama;
Filter, pencarian, sorting, dan pagination
ILIKE
WHERE nama ILIKE '%alya%';
BETWEEN dan IN
WHERE nilai BETWEEN 75 AND 90
AND kelas_id IN (1,2,3);
LIMIT OFFSET
ORDER BY id
LIMIT 20 OFFSET 40;
GROUP BY, HAVING, FILTER, dan statistik
Agregasi kelas
COUNT(*) jumlah,
AVG(nilai) rata,
MAX(nilai) tertinggi
FROM siswa
GROUP BY kelas_id;
FILTER
COUNT(*) FILTER (WHERE nilai >= 75) AS lulus,
COUNT(*) FILTER (WHERE nilai < 75) AS remedial
FROM siswa;
Menggabungkan tabel
INNER JOIN
FROM siswa s
JOIN kelas k ON k.id=s.kelas_id;
LEFT JOIN
FROM kelas k
LEFT JOIN siswa s ON s.kelas_id=k.id;
LATERAL
FROM siswa s
LEFT JOIN LATERAL (
SELECT nilai FROM nilai
WHERE siswa_id=s.id
ORDER BY created_at DESC LIMIT 1
) n ON TRUE;
Menyimpan dan mengolah data fleksibel
Insert JSONB
SET profil='{"kota":"Pontianak","hobi":["membaca","coding"]}'::jsonb
WHERE id=1;
Mengambil nilai
FROM siswa;
Filter JSONB
WHERE profil @> '{"kota":"Pontianak"}'::jsonb;
Menyimpan daftar nilai dalam satu kolom
Array
SET minat=ARRAY['Sosiologi','Teknologi']
WHERE id=1;
ANY dan unnest
WHERE 'Teknologi'=ANY(minat);
SELECT nama,unnest(minat) AS minat
FROM siswa;
WITH dan recursive query
CTE biasa
SELECT * FROM siswa WHERE nilai >= 75
)
SELECT * FROM lulus ORDER BY nilai DESC;
Recursive CTE
SELECT 1
UNION ALL
SELECT n+1 FROM angka WHERE n<10
)
SELECT * FROM angka;
Ranking, running total, dan perbandingan baris
Ranking
RANK() OVER(ORDER BY nilai DESC) peringkat
FROM siswa;
Partition
AVG(nilai) OVER(PARTITION BY kelas_id) rata_kelas
FROM siswa;
LAG
LAG(jumlah) OVER(ORDER BY tanggal) sebelumnya
FROM penjualan;
INSERT ... ON CONFLICT
VALUES ('2026001','Alya',90)
ON CONFLICT (nis)
DO UPDATE SET
nama=EXCLUDED.nama,
nilai=EXCLUDED.nilai
RETURNING *;
View dan materialized view
View
SELECT id,nama,nilai
FROM siswa
WHERE nilai >= 75;
Materialized View
SELECT kelas_id,AVG(nilai) rata
FROM siswa GROUP BY kelas_id;
REFRESH MATERIALIZED VIEW mv_rata_kelas;
Otomasi logika di database
Function
RETURNS TEXT AS $$
BEGIN
RETURN CASE WHEN n>=75 THEN 'Lulus' ELSE 'Remedial' END;
END;
$$ LANGUAGE plpgsql;
Trigger
BEFORE UPDATE ON siswa
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
B-tree, GIN, GiST, dan BRIN
B-tree
Cocok untuk pencarian, sorting, dan perbandingan umum.
GIN
Cocok untuk JSONB, array, dan full-text search.
GiST
Cocok untuk tipe data khusus seperti geometri dan range.
BRIN
Cocok untuk tabel sangat besar dengan data yang terurut secara alami.
CREATE INDEX idx_siswa_profil ON siswa USING GIN(profil);
EXPLAIN ANALYZE SELECT * FROM siswa WHERE profil @> '{"kota":"Pontianak"}';
BEGIN, COMMIT, ROLLBACK, dan SAVEPOINT
UPDATE rekening SET saldo=saldo-100000 WHERE id=1;
SAVEPOINT setelah_debit;
UPDATE rekening SET saldo=saldo+100000 WHERE id=2;
COMMIT;
-- jika gagal:
ROLLBACK TO SAVEPOINT setelah_debit;
Mengelola akun dan hak akses
Role
CREATE ROLE pembaca;
Privilege
GRANT SELECT ON ALL TABLES IN SCHEMA sekolah TO pembaca;
GRANT pembaca TO guru;
Melindungi database
Custom Format
pg_restore -d akademik_baru akademik.backup
Plain SQL
psql -d akademik_baru -f akademik.sql
VACUUM, ANALYZE, REINDEX, dan monitoring
VACUUM
ANALYZE
Aktivitas
FROM pg_stat_activity;
Latihan dari dasar sampai HOTS
Database Akademik
Buat schema sekolah, tabel siswa, kelas, mapel, dan nilai.
JSONB Profil
Simpan profil tambahan siswa dengan JSONB dan buat query filternya.
Peringkat
Gunakan window function untuk peringkat siswa per kelas.
Audit Trigger
Buat trigger untuk mencatat perubahan data.
Role Akses
Buat role admin, guru, dan pembaca dengan privilege berbeda.
Optimasi Query
Bandingkan EXPLAIN ANALYZE sebelum dan sesudah index.
Generator query PostgreSQL
Kuis PostgreSQL 30 soal
Nilai minimal 75%.