Bayangkan satu database untuk Toko Maju Jaya yang tumbuh sampai berisi tabel pelanggan, produk, pesanan, pengiriman, sampai laporan keuangan — ratusan nama yang menumpuk di satu ruangan. Schema adalah jawaban PostgreSQL untuk keramaian itu: laci-laci logis di dalam satu database yang mengelompokkan tabel-tabel yang berkerabat. Pada chapter ini kita membuat schema, menaruh tabel di dalamnya dengan nama terkualifikasi, mengenal schema public yang selalu ada, dan melihat bagaimana search_path menentukan schema mana yang dipakai saat nama tabel ditulis tanpa awalan.

Schema: Namespace di Dalam Database #

Kedengarannya mirip, tetapi database dan schema adalah dua lapis yang berbeda:

AspekDatabaseSchema
PosisiWadah terbesar; terpisah penuh antar satu sama lainNamespace di dalam satu database
Contoh isiSchema, tabel, indexTabel, view, function, tipe data
Pindah kerjaHarus membuka koneksi baruCukup awalan nama atau search_path
Cocok untukMemisahkan proyek atau aplikasi berbedaMengelompokkan bagian-bagian satu aplikasi

Satu analogi sederhana: database adalah gedung, schema adalah ruangan-ruangan di dalamnya, dan tabel adalah meja di tiap ruangan. Dua ruangan boleh punya meja bernama sama persis karena nomor ruangannya berbeda — dan begitulah schema mencegah bentrok nama tabel.

Membuat Schema dan Tabel di Dalamnya #

Perintah CREATE SCHEMA membuat laci baru. Setelah itu, setiap tabel yang ditaruh di dalamnya ditulis dengan nama terkualifikasi: nama_schema.nama_tabel. File berikut membuat schema penjualan lalu mengisi tabel pelanggan di dalamnya:

sql buat-schema.sql
CREATE SCHEMA penjualan;

CREATE TABLE penjualan.pelanggan (
    id   integer PRIMARY KEY,
    nama text NOT NULL,
    kota text
);

INSERT INTO penjualan.pelanggan (id, nama, kota)
VALUES
    (1, 'Budi', 'Jakarta'),
    (2, 'Siti', 'Bandung');

SELECT id, nama, kota
FROM penjualan.pelanggan
ORDER BY id;

Output yang Dihasilkan:

text
CREATE SCHEMA
CREATE TABLE
INSERT 0 2
 id | nama |  kota   
----+------+---------
  1 | Budi | Jakarta
  2 | Siti | Bandung
(2 rows)

Mari kita bedah file di atas:

  1. CREATE SCHEMA penjualan;: membuat schema baru bernama penjualan di database tempat sesi kita terhubung. Nama schema mengikuti aturan identifier yang sama dengan nama tabel.
  2. CREATE TABLE penjualan.pelanggan (...): titik memisahkan nama schema dari nama tabel, jadi tabel ini tercipta di dalam laci penjualan, bukan di ruang umum. Struktur kolomnya sama seperti CREATE TABLE biasa.
  3. INSERT INTO penjualan.pelanggan ... dan SELECT ... FROM penjualan.pelanggan: seluruh perintah yang menyentuh tabel itu kini harus menyebut awalan penjualan. — data dua pelanggan masuk dan terbaca kembali seperti biasa.

Lebih dari Satu Schema #

Kekuatan schema baru terasa ketika ada beberapa sekaligus. File berikut menambah schema inventaris untuk data stok gudang, lalu bertanya ke information_schema — kumpulan view standar yang memetakan struktur database — tabel mana hidup di schema mana:

CREATE SCHEMA inventaris;

CREATE TABLE inventaris.produk (
    id    integer PRIMARY KEY,
    nama  text NOT NULL,
    stok  integer NOT NULL
);

INSERT INTO inventaris.produk (id, nama, stok)
VALUES (1, 'Buku Tulis', 120);

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema IN ('public', 'penjualan', 'inventaris')
ORDER BY table_schema, table_name;

Output yang Dihasilkan:

text
CREATE SCHEMA
CREATE TABLE
INSERT 0 1
 table_schema | table_name 
--------------+------------
 inventaris   | produk
 penjualan    | pelanggan
(2 rows)

Kolom table_schema pada hasil memperlihatkan pembagiannya: pelanggan berada di schema penjualan, produk berada di schema inventaris, dan schema public — yang sengaja kita ikutkan dalam saringan — kosong dari tabel. Kita akan bahas public sekarang, dan membaca information_schema lebih tuntas di chapter Melihat Struktur Tabel.

Schema public dan search_path #

Setiap database baru PostgreSQL otomatis membawa satu schema bernama public. Selama ini tabel-tabel kita tanpa sadar tercipta di sana, karena public adalah alamat bawaan untuk semua nama yang ditulis tanpa awalan schema. Daftar alamat itu disebut search_path, dan isinya bisa kita lihat langsung:

sql search-path.sql
SHOW search_path;

CREATE TABLE pelanggan (
    kode    integer PRIMARY KEY,
    catatan text
);

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema IN ('public', 'penjualan')
ORDER BY table_schema, table_name;

Output yang Dihasilkan:

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

CREATE TABLE
 table_schema | table_name 
--------------+------------
 penjualan    | pelanggan
 public       | pelanggan
(2 rows)

Tiga hal terjadi di file tersebut: SHOW search_path menampilkan isi daftar alamat bawaan ("$user", public — schema bernama sama dengan nama pengguna, lalu public); CREATE TABLE pelanggan tanpa awalan menjatuhkan tabel baru itu ke schema pertama yang tersedia dari daftar, yaitu public; dan hasil akhirnya memperlihatkan dua tabel bernama pelanggan hidup berdampingan — satu di public, satu di penjualan — tanpa saling mengganggu.

Menghapus Schema #

Schema dihapus dengan DROP SCHEMA. Syaratnya sama seperti DROP TABLE yang akan kita bahas nanti: schema harus kosong, atau kita menyatakan secara eksplisit bahwa isinya ikut dibuang dengan opsi CASCADE:

DROP SCHEMA inventaris CASCADE;

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema IN ('public', 'penjualan', 'inventaris')
ORDER BY table_schema, table_name;

Output yang Dihasilkan:

text
DROP SCHEMA
 table_schema | table_name 
--------------+------------
 penjualan    | pelanggan
 public       | pelanggan
(2 rows)

DROP SCHEMA inventaris CASCADE menghapus schema inventaris beserta tabel produk di dalamnya — hasil verifikasi terakhir hanya menyisakan dua tabel pelanggan di public dan penjualan. Tanpa CASCADE, server akan menolak dengan error karena schema masih berisi objek.

Schema membuat satu database tetap rapi meski isinya banyak. Namun ada satu keterbatasan yang sering mengejutkan pendatang dari MySQL: kita tidak bisa “berpindah database” dengan satu perintah USE di tengah sesi. Cara kerja perpindahan antar database di PostgreSQL — dan mengapa koneksinya harus diganti — menjadi topik chapter Memilih Database.

Referensi #

Berkas Sumber

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

buat-schema.sql

Unduh berkas
sql
CREATE SCHEMA penjualan;

CREATE TABLE penjualan.pelanggan (
    id   integer PRIMARY KEY,
    nama text NOT NULL,
    kota text
);

INSERT INTO penjualan.pelanggan (id, nama, kota)
VALUES
    (1, 'Budi', 'Jakarta'),
    (2, 'Siti', 'Bandung');

SELECT id, nama, kota
FROM penjualan.pelanggan
ORDER BY id;

hapus-schema.sql

Unduh berkas
sql
DROP SCHEMA inventaris CASCADE;

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema IN ('public', 'penjualan', 'inventaris')
ORDER BY table_schema, table_name;

schema-tambahan.sql

Unduh berkas
sql
CREATE SCHEMA inventaris;

CREATE TABLE inventaris.produk (
    id    integer PRIMARY KEY,
    nama  text NOT NULL,
    stok  integer NOT NULL
);

INSERT INTO inventaris.produk (id, nama, stok)
VALUES (1, 'Buku Tulis', 120);

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema IN ('public', 'penjualan', 'inventaris')
ORDER BY table_schema, table_name;

search-path.sql

Unduh berkas
sql
SHOW search_path;

CREATE TABLE pelanggan (
    kode    integer PRIMARY KEY,
    catatan text
);

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema IN ('public', 'penjualan')
ORDER BY table_schema, table_name;