Dua minggu setelah membuat tabel, wajar kalau ingatan kita kabur: apa saja kolomnya, kolom mana yang wajib diisi, apa nilainya default? Untunglah PostgreSQL tidak pernah lupa — setiap definisi tabel yang kita buat tercatat rapi di dalam server, dan ada tiga pintu untuk membacanya kembali: meta-command psql seperti \d, view standar information_schema, dan system catalog pg_catalog. Pada chapter ini kita memakai ketiganya di atas satu tabel yang sama dan membandingkan kapan masing-masing pintu paling tepat dipakai.

Menyiapkan Tabel untuk Diamati #

Tabel latihan kita adalah pelanggan dari chapter sebelumnya — cukup kaya untuk memperlihatkan semua informasi yang menarik (primary key, NOT NULL, UNIQUE, dan DEFAULT), tetapi tetap ringkas:

sql buat-tabel.sql
CREATE TABLE pelanggan (
    id     integer PRIMARY KEY,
    nama   text NOT NULL,
    email  text UNIQUE,
    kota   text DEFAULT 'Jakarta'
);

INSERT INTO pelanggan (id, nama, email)
VALUES (1, 'Budi', '[email protected]');

Output yang Dihasilkan:

text
CREATE TABLE
INSERT 0 1

Meta-Command psql: \dt dan \d #

Cara tercepat memeriksa struktur adalah meta-command — perintah yang diawali backslash dan diproses oleh psql sendiri, bukan dikirim ke server sebagai SQL. \dt mendaftar semua tabel dalam search_path, sedangkan \d nama_tabel membedah satu tabel sampai ke constraint-nya:

\dt

\d pelanggan

Output yang Dihasilkan:

text
           List of relations
 Schema |   Name    | Type  |  Owner   
--------+-----------+-------+----------
 public | pelanggan | table | postgres
(1 row)

                 Table "public.pelanggan"
 Column |  Type   | Collation | Nullable |     Default     
--------+---------+-----------+----------+-----------------
 id     | integer |           | not null | 
 nama   | text    |           | not null | 
 email  | text    |           |          | 
 kota   | text    |           |          | 'Jakarta'::text
Indexes:
    "pelanggan_pkey" PRIMARY KEY, btree (id)
    "pelanggan_email_key" UNIQUE CONSTRAINT, btree (email)

Mari kita baca hasilnya bagian demi bagian:

  1. \dt menghasilkan daftar relasi: schema (public), nama tabel (pelanggan), jenis objek (table), dan pemiliknya (postgres — pengguna yang menjalankan CREATE TABLE).
  2. \d pelanggan menghasilkan tabel kolom: nama kolom, tipe, collation (aturan urutan teks — kosong di sini), status NULL (not null atau kosong), dan nilai default. Baris kota memperlihatkan 'Jakarta'::text — default yang kita definisikan, lengkap dengan cast ke tipe text yang ditambahkan server.
  3. Bagian Indexes: di bawahnya mendaftar index yang tercipta otomatis oleh constraint: pelanggan_pkey untuk primary key dan pelanggan_email_key untuk UNIQUE. Kedua index ini dibuat server tanpa kita minta.

Bentuk \d+ menambahkan kolom-kolom teknis — cara penyimpanan fisik tiap kolom (Storage), target statistik, dan deskripsi — yang mulai berguna saat kita menyelami performa nanti:

\d+ pelanggan

Output yang Dihasilkan:

text
                                            Table "public.pelanggan"
 Column |  Type   | Collation | Nullable |     Default     | Storage  | Compression | Stats target | Description 
--------+---------+-----------+----------+-----------------+----------+-------------+--------------+-------------
 id     | integer |           | not null |                 | plain    |             |              | 
 nama   | text    |           | not null |                 | extended |             |              | 
 email  | text    |           |          |                 | extended |             |              | 
 kota   | text    |           |          | 'Jakarta'::text | extended |             |              | 
Indexes:
    "pelanggan_pkey" PRIMARY KEY, btree (id)
    "pelanggan_email_key" UNIQUE CONSTRAINT, btree (email)
Access method: heap

Output \d+ memperlihatkan informasi tambahan seperti plain dan extended pada kolom Storage (strategi kompresi dan penyimpanan tiap tipe data) — detail yang kita abaikan dulu dan bahas kembali di Section Query Optimization. Yang penting sekarang: pola \d dan \d+ selalu siap sebagai jendela cepat ke struktur mana pun.

information_schema: Cara Standar SQL #

information_schema adalah kumpulan view yang didefinisikan standar SQL untuk memetakan struktur database. Karena bentuknya query SQL biasa, hasilnya bisa dibaca dari psql, dari aplikasi, bahkan (dengan nama view yang sama) dari database lain seperti MySQL — itulah nilai utamanya. View information_schema.columns memuat satu baris per kolom dari semua tabel:

SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'pelanggan'
ORDER BY ordinal_position;

Output yang Dihasilkan:

text
 column_name | data_type | is_nullable | column_default  
-------------+-----------+-------------+-----------------
 id          | integer   | NO          | 
 nama        | text      | NO          | 
 email       | text      | YES         | 
 kota        | text      | YES         | 'Jakarta'::text
(4 rows)

Empat hal penting dari query tersebut: saringan table_schema dan table_name mempersempit hasil ke tabel yang kita tuju; kolom ordinal_position adalah nomor urut kolom sesuai definisi — dan ORDER BY ordinal_position menjamin baris tampil persis dalam urutan itu (tanpa ORDER BY, urutan baris hasil query tidak dijamin); is_nullable bernilai NO atau YES; dan column_default menampilkan nilai default kota dalam bentuk aslinya. Nilai untuk primary key id terlihat beda dari \d: information_schema tidak punya kolom khusus “primary key” — informasi itu hidup di view information_schema.table_constraints yang kita kenal nanti.

pg_catalog: Sumber Aslinya #

Kedua pintu sebelumnya membaca dari satu sumber yang sama: system catalog — tabel-tabel internal bernama pg_* tempat PostgreSQL sungguhan menyimpan seluruh metadata-nya. Ketika psql menjalankan \d, psql menjalankan query ke catalog inilah di belakang layar. Satu contoh kecil memperlihatkan rasanya:

SELECT attname AS nama_kolom,
       format_type(atttypid, atttypmod) AS tipe_kolom
FROM pg_attribute
WHERE attrelid = 'pelanggan'::regclass
  AND attnum > 0
  AND NOT attisdropped
ORDER BY attnum;

Output yang Dihasilkan:

text
 nama_kolom | tipe_kolom 
------------+------------
 id         | integer
 nama       | text
 email      | text
 kota       | text
(4 rows)

Catalog pg_attribute menyimpan satu baris per kolom per tabel, termasuk kolom sistem tersembunyi yang kita saring dengan attnum > 0. Nilai 'pelanggan'::regclass mengubah nama tabel menjadi penunjuk internal (OID — nomor objek internal server), dan function format_type() menerjemahkan kode tipe numerik menjadi nama tipe yang kita kenal seperti integer dan text. Catalog kaya informasi dan cepat, tetapi namanya khas PostgreSQL dan isinya bisa berubah antar versi besar — untuk kode yang perlu portabel, information_schema tetap pilihan lebih aman.

Mana yang Dipakai Kapan? #

Ketiga pintu tersebut saling melengkapi, bukan bersaing:

KebutuhanPilihan tepatAlasan
Cek cepat sambil bekerja di terminal\d, \dt, \d+Paling ringkas, tanpa menulis query
Kode aplikasi yang perlu memeriksa strukturinformation_schemaSQL standar yang sama di banyak database
Informasi internal yang tidak ada di standarpg_catalogSatu-satunya sumber data lengkap

Satu hal yang tidak berubah di ketiganya: struktur tabel yang terbaca adalah struktur yang sedang berlaku saat ini. Begitu kita mengubah definisi tabel, semua pembacaan berikutnya menampilkan bentuk barunya — dan mengubah struktur itulah topik chapter berikutnya, Mengubah Struktur Tabel.

Referensi #

Berkas Sumber

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

buat-tabel.sql

Unduh berkas
sql
CREATE TABLE pelanggan (
    id     integer PRIMARY KEY,
    nama   text NOT NULL,
    email  text UNIQUE,
    kota   text DEFAULT 'Jakarta'
);

INSERT INTO pelanggan (id, nama, email)
VALUES (1, 'Budi', '[email protected]');

informasi-kolom.sql

Unduh berkas
sql
SELECT column_name, data_type, is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'pelanggan'
ORDER BY ordinal_position;

katalog-sistem.sql

Unduh berkas
sql
SELECT attname AS nama_kolom,
       format_type(atttypid, atttypmod) AS tipe_kolom
FROM pg_attribute
WHERE attrelid = 'pelanggan'::regclass
  AND attnum > 0
  AND NOT attisdropped
ORDER BY attnum;