Topik ini membuka modul objek basis data dengan view, yaitu query bernama yang disimpan sebagai objek dan dibaca sebagaimana tabel. View tidak menyimpan data, melainkan definisi querynya, sehingga setiap pembacaan menjalankannya ulang atas data terkini, dan manfaatnya menumpuk pada tiga hal, yaitu keringkasan, kesatuan definisi, dan lapisan keamanan.
Blok penyiapan dataset#
# siapkan ulang tabel dan data contoh untuk topik ini
PGOPTIONS='-c client_min_messages=warning' psql -q -U postgres -d perpustakaan <<'SQL'
DROP TABLE IF EXISTS peminjaman, buku, anggota, kategori, laporan_aktif, staf CASCADE;
CREATE TABLE kategori (id SERIAL PRIMARY KEY, nama TEXT NOT NULL UNIQUE);
CREATE TABLE anggota (id SERIAL PRIMARY KEY, nama TEXT NOT NULL, email TEXT UNIQUE, bergabung DATE NOT NULL, aktif BOOLEAN NOT NULL DEFAULT TRUE);
CREATE TABLE buku (id SERIAL PRIMARY KEY, judul TEXT NOT NULL, penulis TEXT NOT NULL, tahun INTEGER NOT NULL, kategori_id INTEGER REFERENCES kategori(id));
CREATE TABLE peminjaman (id SERIAL PRIMARY KEY, anggota_id INTEGER NOT NULL REFERENCES anggota(id), buku_id INTEGER NOT NULL REFERENCES buku(id), tanggal_pinjam DATE NOT NULL, tanggal_kembali DATE);
INSERT INTO kategori (nama) VALUES ('Pemrograman'), ('Sains'), ('Sejarah'), ('Fiksi'), ('Statistika');
INSERT INTO anggota (nama, email, bergabung, aktif) VALUES ('Ali Rahman', '[email protected]', '2024-01-15', TRUE), ('Budi Santoso', '[email protected]', '2024-03-02', TRUE), ('Citra Kirana', '[email protected]', '2024-05-20', FALSE), ('Dewi Lestari', '[email protected]', '2024-08-11', TRUE), ('Eka Pratama', NULL, '2025-01-30', TRUE);
INSERT INTO buku (judul, penulis, tahun, kategori_id) VALUES ('Dasar Basis Data', 'Sari Wulandari', 2021, 1), ('Jaringan Komputer', 'Ahmad Fauzi', 2019, 1), ('Fisika untuk Pemula', 'Rina Marlina', 2020, 2), ('Kimia Organik', 'Rina Marlina', 2022, 2), ('Sejarah Nusantara', 'Bambang Wijaya', 2018, 3), ('Cerita Kota Lama', 'Nur Aisyah', 2023, 4), ('Statistika Terapan', 'Sari Wulandari', 2022, 5), ('Algoritma dan Struktur Data', 'Ahmad Fauzi', 2021, 1);
INSERT INTO peminjaman (anggota_id, buku_id, tanggal_pinjam, tanggal_kembali) VALUES (1, 1, '2025-03-01', '2025-03-15'), (1, 7, '2025-03-05', '2025-03-20'), (2, 3, '2025-03-10', NULL), (3, 5, '2025-02-20', '2025-03-01'), (2, 1, '2025-04-02', NULL), (4, 6, '2025-04-07', NULL), (5, 8, '2025-04-09', '2025-04-25'), (4, 2, '2025-05-01', NULL);
CREATE TABLE staf (id SERIAL PRIMARY KEY, nama TEXT NOT NULL, email TEXT NOT NULL);
INSERT INTO staf (nama, email) VALUES ('Hana Zahira', '[email protected]');
SQLView sebagai query bernama#
CREATE VIEW menyimpan query di bawah satu nama, dan pembacaannya memperlakukannya seperti tabel. Blok berikut menyimpan laporan peminjaman aktif yang meringkas empat tabel, lalu membacanya dengan query yang jauh lebih pendek.
# view laporan peminjaman aktif
psql -U postgres -d perpustakaan <<'SQL'
CREATE VIEW laporan_aktif AS
SELECT p.id, a.nama AS anggota, b.judul, k.nama AS kategori, p.tanggal_pinjam
FROM peminjaman p
JOIN anggota a ON p.anggota_id = a.id
JOIN buku b ON p.buku_id = b.id
JOIN kategori k ON b.kategori_id = k.id
WHERE p.tanggal_kembali IS NULL;
SQL
psql -U postgres -d perpustakaan -c "SELECT anggota, judul, kategori FROM laporan_aktif ORDER BY id;"CREATE VIEW
anggota | judul | kategori
--------------+---------------------+-------------
Budi Santoso | Fisika untuk Pemula | Sains
Budi Santoso | Dasar Basis Data | Pemrograman
Dewi Lestari | Cerita Kota Lama | Fiksi
Dewi Lestari | Jaringan Komputer | Pemrograman
(4 rows)Delapan baris definisi disatikan sekali, dan pembacaannya tinggal satu baris dengan syarat tambahan sesuai kebutuhan. View yang dirujuk berkali-kali menjamin setiap laporan memakai definisi yang sama, kebiasaan yang mencegah empat versi laporan yang saling berbeda tipis.
View sebagai lapisan keamanan#
View membatasi kolom dan baris yang terlihat, dan hak akses diberikan pada view-nya alih-alih tabel dasarnya. Blok berikut membuat view yang menyembunyikan email anggota, lalu menunjukkan bahwa tabel dasarnya tidak pernah disentuh lapisan pembaca.
# view tanpa kolom sensitif
psql -U postgres -d perpustakaan <<'SQL'
CREATE VIEW anggota_publik AS SELECT id, nama, aktif FROM anggota;
CREATE VIEW staf_publik AS SELECT nama FROM staf;
SELECT * FROM anggota_publik ORDER BY id LIMIT 3;
SELECT * FROM staf_publik;
DROP VIEW anggota_publik, staf_publik;
SQLCREATE VIEW
CREATE VIEW
id | nama | aktif
----+--------------+-------
1 | Ali Rahman | t
2 | Budi Santoso | t
3 | Citra Kirana | f
(3 rows)
nama
-------------
Hana Zahira
(1 row)
DROP VIEWKolom email tidak pernah muncul karena view-nya tidak menyebutkannya, dan pada instalasi nyata, role pembaca diberi GRANT SELECT hanya pada view, sehingga tabel dasarnya tidak dapat dibaca langsung. Pola ini juga menyembunyikan baris tertentu melalui WHERE pada view, dan pembatasan yang lebih halus diteruskan dengan keamanan tingkat baris pada modul administrasi.
View yang dapat ditulis#
View sederhana yang memetakan satu tabel tanpa agregasi menerima INSERT, UPDATE, dan DELETE yang diteruskan ke tabel dasarnya secara otomatis. Aturannya semakin longgar pada versi modern, sedangkan view dengan join membutuhkan trigger INSTEAD OF atau aturan tulis eksplisit, dan pembahasan lengkapnya menyusul pada topik trigger.
Kebiasaan yang sehat memperlakukan view yang dapat ditulis sebagai antarmuka yang disengaja, bukan efek samping, karena pembaca yang mengira view hanya untuk baca dapat menulis tanpa sadar pada tabel dasarnya.
Kesalahan umum#
Kesalahan pertama adalah menumpuk view di atas view berlapis-lapis, sehingga perencana tetap dapat menganalisisnya tetapi manusia kehilangan jejak definisi, dan rantai yang lebih dari dua tingkat diratakan. Kesalahan kedua adalah view yang membungkus SELECT * pada tabel dasar, karena penambahan kolom di tabel dasar mengubah hasil view diam-diam, dan daftar kolom eksplisit menangkalnya.
Kesalahan ketiga adalah mengira view mempercepat query, padahal view tanpa materialisasi dijalankan ulang setiap kali dibaca, dan percepatannya menjadi wilayah materialized view pada topik tersendiri. Kesalahan keempat adalah memberi nama view sama dengan tabelnya, yang ditolak server karena keduanya berbagi ruang nama yang sama.
Satu perhatian keamanan menyertai view yang menyembunyikan baris, yaitu perencana dapat memindahkan syarat melintasi batas view demi rencana yang lebih murah, sehingga fungsi yang sengaja dijadikan pagar dapat terpanggil pada waktu yang tak terduga. Opsi security_barrier pada CREATE VIEW menahan penataan ulang itu dengan biaya peluang rencana yang lebih sempit, dan pemilihannya dipikirkan saat view memuat syarat yang benar-benar sensitif. Untuk laporan biasa tanpa pagar fungsi, bentuk bawaannya tetap dipilih.
Ringkasan#
- CREATE VIEW menyimpan query sebagai objek bernama yang dijalankan ulang atas data terkini pada setiap pembacaan.
- View menyatukan definisi laporan yang dipakai berkali-kali dan mencegah versi definisi yang menyimpang.
- Sebagai lapisan keamanan, view membatasi kolom dan baris yang terlihat, dan hak akses diberikan pada view-nya.
- View sederhana menerima tulisan yang diteruskan ke tabel dasar, sedangkan view bergabung butuh trigger INSTEAD OF.
Referensi#
- Views — PostgreSQL Documentation — Referensi CREATE VIEW dan perilaku pembaruan view.
- Rules and Privileges — PostgreSQL Documentation — View sebagai lapisan hak akses pada dokumentasi resmi.
- CREATE VIEW — PostgreSQL Documentation — Bagian tutorial resmi tentang view.