Sejauh ini kita bekerja sebagai superuser postgres — pengguna yang boleh melakukan apa saja terhadap server. Untuk belajar itu praktis, tetapi sebagai kebiasaan sehari-hari kebiasaan itu berbahaya: satu perintah DROP TABLE yang salah sasaran tidak menyisakan pengaman apa pun. Chapter penutup section ini menyusun lingkungan pengembangan yang sehat: role khusus untuk kerja harian, database latihan milik role itu, konvensi penamaan objek, serta kebiasaan-kebiasaan kecil yang membuat pekerjaan bisa diulang dengan hasil sama.

Prinsip: Pisahkan Kerja dari Administrasi #

Mengapa repot-repot membuat role baru kalau postgres sudah bisa segalanya? Alasannya sama dengan kenapa kita tidak bekerja sebagai root di Linux: superuser tidak punya rem. Kesalahan kecil — menjalankan skrip di database yang salah, UPDATE tanpa WHERE, DROP yang keliru sasaran — dieksekusi tanpa pertanyaan, dan sering berlaku untuk seluruh cluster, bukan satu database saja.

Role biasa hanya bisa merusak objek yang dimilikinya. Dengan memberi setiap proyek atau keperluan belajar role dan database sendiri, ledakan kecil tetap terjadi — itu bagian dari belajar — tetapi radiusnya terbatas di satu database. Prinsip least privilege ini pula yang akan kita temui lagi pada Section User Management dan Keamanan ketika mengatur hak akses produksi.

Membuat Role dan Database Latihan #

Dua objek yang kita butuhkan: role budi yang bisa login, dan database latihan yang dimilikinya. Perintah pembuatannya termasuk kategori administrasi cluster, jadi dijalankan dari database maintenance postgres:

-- Bersihkan sisa percobaan sebelumnya supaya file bisa dijalankan ulang
DROP DATABASE IF EXISTS latihan;
DROP ROLE IF EXISTS budi;

-- Role khusus untuk kerja harian, bukan superuser
CREATE ROLE budi LOGIN PASSWORD 'YOUR_PASSWORD';

-- Database latihan yang dimiliki oleh budi
CREATE DATABASE latihan OWNER budi;

-- Berpindah ke database yang baru dibuat
\connect latihan

SELECT current_user, current_database();

Output yang Dihasilkan:

text
DROP DATABASE
DROP ROLE
CREATE ROLE
CREATE DATABASE
You are now connected to database "latihan" as user "postgres".
 current_user | current_database 
--------------+------------------
 postgres     | latihan
(1 row)

Mari kita bedah file tersebut baris per baris:

  1. DROP DATABASE IF EXISTS latihan; dan DROP ROLE IF EXISTS budi;: membersihkan sisa percobaan sebelum file ini dijalankan lagi. Tag DROP DATABASE dan DROP ROLE tetap tampil meskipun objeknya belum ada — bagian IF EXISTS hanya mengubah perilaku dari error menjadi skipping — dan inilah pola yang membuat file setup bisa dijalankan berulang tanpa error. Urutannya sengaja database dulu, role kemudian, karena role tidak bisa dihapus selama masih memiliki database.
  2. CREATE ROLE budi LOGIN PASSWORD 'YOUR_PASSWORD';: membuat role bernama budi. Kata kunci LOGIN yang membuatnya bisa dipakai untuk koneksi — tanpa LOGIN, sebuah role hanya wadah grup hak akses. Ganti YOUR_PASSWORD dengan kata sandi Anda sendiri.
  3. CREATE DATABASE latihan OWNER budi;: membuat database sekaligus menyerahkan kepemilikannya. Sebagai pemilik, budi berhak membuat tabel dan objek lain di dalamnya tanpa pemberian hak tambahan.
  4. \connect latihan: meta-command psql berpindah koneksi ke database baru itu. Query penutup membuktikan hasilnya: user masih postgres, tetapi database sudah berganti.

Bekerja sebagai User Biasa #

Kini sisi sebaliknya: masuk sebagai budi dan bekerja di latihan seperti kerja harian. File berikut berpindah koneksi dengan menyebut user, membuat tabel tugas, mengisinya, lalu memeriksa dua hal: isi tabel dan search path aktif:

-- Masuk ke database latihan sebagai user biasa
\connect latihan budi

CREATE TABLE tugas (
    id      integer PRIMARY KEY,
    judul   text NOT NULL,
    selesai boolean NOT NULL DEFAULT false
);

INSERT INTO tugas (id, judul) VALUES
    (1, 'Mengenal meta-command psql'),
    (2, 'Membuat database latihan');

SELECT id, judul, selesai
FROM tugas
ORDER BY id;

-- Urutan schema yang dicari saat objek ditulis tanpa awalan schema
SHOW search_path;

Output yang Dihasilkan:

text
You are now connected to database "latihan" as user "budi".
CREATE TABLE
INSERT 0 2
 id |           judul            | selesai 
----+----------------------------+---------
  1 | Mengenal meta-command psql | f
  2 | Membuat database latihan   | f
(2 rows)

   search_path   
-----------------
 "$user", public
(1 row)

Hal pertama yang perlu dicermati: \connect latihan budi membuka koneksi baru dengan identitas budi, dan baris You are now connected ... as user "budi" pada output membuktikannya. Di server dengan autentikasi kata sandi, psql akan menanyakan kata sandi budi pada titik ini — di lingkungan pengujian materi ini yang memakai trust, pergantian berlangsung mulus. Selanjutnya CREATE TABLE dan INSERT berhasil tanpa pemberian hak apa pun karena budi pemilik database ini — bandingkan dengan cara kerja GRANT di section user management nanti.

Kolom selesai menampilkan f — cara PostgreSQL menuliskan nilai false — dan nilainya berasal dari DEFAULT false karena perintah INSERT tidak mengisinya. Tabel kecil semacam ini nyaman dipakai sebagai scratch pad harian: catat tugas belajar, tandai selesai dengan UPDATE.

search_path dan Penamaan Objek #

Hasil SHOW search_path; memperlihatkan "$user", public — dua schema yang dicari server ketika kita menulis nama objek tanpa awalan schema. Kata tugas pada query kita di atas berhasil ditemukan karena tabel itu berada di schema public, komponen kedua dari search path. Komponen pertama, "$user", adalah nama role yang sedang aktif: ketika role budi punya schema bernama budi, objek di sana akan dipakai lebih dulu.

Urutan ini menjelaskan satu kejutan klasik PostgreSQL: dua user bisa menulis SELECT * FROM pelanggan dan mendapat tabel yang berbeda, karena masing-masing menemukan tabel pertama di schema miliknya sendiri. Menyebut schema secara eksplisit — public.pelanggan — menghilangkan ambiguitas itu.

Sambil menata objek, gunakan konvensi penamaan yang konsisten sejak awal:

AspekKonvensiContoh
Tabelsnake_case, tunggal atau jamak asal konsistenpelanggan, pesanan_item
Kolomsnake_case, deskriptif, tanpa awalan tipetanggal_daftar
Rolenama orang atau aplikasi tanpa spasibudi, aplikasi_toko
Kata reservedhindari, atau kutip terus-menerusorder jangan; pesanan boleh

Baris terakhir patut digarisbawahi: nama tanpa kutip di PostgreSQL otomatis dilipat ke huruf kecil. Menamai tabel "Pelanggan" dengan kutip dan huruf besar membuat kita wajib mengutipnya dengan huruf persis sama selamanya — kesalahan kecil yang menyulitkan bertahun-tahun.

Merapikan Lingkungan Latihan #

Setiap lingkungan latihan kadang perlu dikembalikan ke nol — mengulang chapter dari awal, atau sekadar membereskan akumulasi percobaan. Perintah pembersihannya kebalikan dari pembuatannya, dijalankan dari database maintenance:

sql rapikan.sql
-- Hapus kembali objek latihan yang dibuat chapter ini
DROP DATABASE latihan;
DROP ROLE budi;

Output yang Dihasilkan:

text
DROP DATABASE
DROP ROLE

Menghapus database sekaligus menghapus seluruh isinya — tabel tugas ikut lenyap tanpa perlu dibahas satu per satu — dan setelah databasenya hilang, role budi bisa dihapus. Kombinasi siapkan-akun.sql lalu struktur-latihan.sql lalu rapikan.sql membentuk siklus yang bisa dijalankan berulang kali dengan hasil identik, pola yang sama dengan bagaimana file-file contoh course ini menjaga idempotensinya.

Kebiasaan Kerja yang Aman #

Menutup section ini, rekap kebiasaan yang layak dibawa sepanjang course dan karier:

  • Satu role dan satu database untuk satu keperluan; superuser hanya untuk pekerjaan administrasi sungguhan.
  • Jalankan skrip SQL dengan psql -v ON_ERROR_STOP=1 -f file.sql supaya gagal di tengah tidak meninggalkan keadaan setengah jadi.
  • Simpan parameter koneksi yang sering dipakai di connection service file, dan kata sandi di .pgpass berpermission 0600 — bukan di dalam skrip atau connection string.
  • Tulis file setup yang bisa dijalankan ulang (DROP ... IF EXISTS di awal) supaya lingkungan latihan selalu bisa dibangun ulang dari nol.
  • Sebut schema secara eksplisil (public.nama_tabel) ketika satu database dipakai banyak schema.

Dengan server yang terpasang, alat yang dikuasai, dan lingkungan kerja yang tertata, kita siap menulis SQL sungguhan. Section berikutnya, Dasar SQL, dimulai dari perintah yang paling sering kita tulis seumur hidup berdatabase: SELECT.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

rapikan.sql

Unduh berkas
sql
-- Hapus kembali objek latihan yang dibuat chapter ini
DROP DATABASE latihan;
DROP ROLE budi;

siapkan-akun.sql

Unduh berkas
sql
-- Bersihkan sisa percobaan sebelumnya supaya file bisa dijalankan ulang
DROP DATABASE IF EXISTS latihan;
DROP ROLE IF EXISTS budi;

-- Role khusus untuk kerja harian, bukan superuser
CREATE ROLE budi LOGIN PASSWORD 'YOUR_PASSWORD';

-- Database latihan yang dimiliki oleh budi
CREATE DATABASE latihan OWNER budi;

-- Berpindah ke database yang baru dibuat
\connect latihan

SELECT current_user, current_database();

struktur-latihan.sql

Unduh berkas
sql
-- Masuk ke database latihan sebagai user biasa
\connect latihan budi

CREATE TABLE tugas (
    id      integer PRIMARY KEY,
    judul   text NOT NULL,
    selesai boolean NOT NULL DEFAULT false
);

INSERT INTO tugas (id, judul) VALUES
    (1, 'Mengenal meta-command psql'),
    (2, 'Membuat database latihan');

SELECT id, judul, selesai
FROM tugas
ORDER BY id;

-- Urutan schema yang dicari saat objek ditulis tanpa awalan schema
SHOW search_path;