Belajar SQL PostgreSQL - Data Types di PostgreSQL & Constraints Management
Episode 3 of 21

Belajar SQL PostgreSQL - Data Types di PostgreSQL & Constraints Management

Episode ini membahas tipe data utama PostgreSQL: numerik, karakter, tanggal dan waktu, boolean, serta UUID. Selain itu dibahas manajemen constraint seperti NOT NULL, UNIQUE, PRIMARY KEY, FOREIGN KEY dengan referential action, dan CHECK untuk menjaga integritas data.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Selamat datang di episode 3 series Belajar SQL PostgreSQL! Pada episode 2, kita sudah belajar merancang tabel dengan DDL. Sekarang kita akan menyelam lebih dalam ke bahan dasar dari setiap tabel: tipe data dan constraint. Pemahaman keduanya menentukan seberapa aman, cepat, dan benar database kalian nantinya.

Di episode ini, kita akan membahas tipe data utama PostgreSQL satu per satu — numerik, karakter, tanggal dan waktu, boolean, dan UUID — lalu mempelajari cara mengelola constraint dengan benar.

Tipe Data Numerik

PostgreSQL menyediakan keluarga tipe numerik yang cukup lengkap, dan setiap tipe punya kasus penggunaan yang berbeda. Memilih tipe yang tepat adalah keputusan desain yang penting.

Integer, BIGINT, dan Precise Decimal

TipeRentang nilaiKasus penggunaan
SMALLINT-32.768 s/d 32.767Menyimpan angka kecil: quantity
INTEGER / INT-2,1 milyar s/d 2,1 milyarDefault untuk id dan counter
BIGINTRentang ±9,2 triliunData dengan volume raksasa
NUMERIC(p,s)Presisi tepat, bisa disetUang, perhitungan presisi
REALFloating point 4 bytePengukuran yang presisinya tidak kritis
Perbandingan presisi numerik
SELECT 0.1::REAL + 0.2::REAL AS floating_error;
SELECT 0.1::NUMERIC(10,2) + 0.2::NUMERIC(10,2) AS exact_sum;

Warning

Aturan emasnya: jangan pernah menyimpan uang dengan REAL atau DOUBLE PRECISION. Error pembulatan floating point bisa membuat laporan keuangan selisih receh yang kemudian menjadi selisih besar saat dikalikan jutaan transaksi. Untuk uang, selalu gunakan NUMERIC atau BIGINT dalam satuan sen.

SERIAL vs GENERATED ALWAYS AS IDENTITY

Untuk kolom auto-increment, generasi lama memakai SERIAL; standar SQL modern menyarankan GENERATED ALWAYS AS IDENTITY yang lebih eksplisit dan tidak bisa di-override.

Perbandingan SERIAL dan IDENTITY
CREATE TABLE old_style (
    id SERIAL PRIMARY KEY
);
 
CREATE TABLE modern_style (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY
);

Dengan GENERATED ALWAYS, PostgreSQL menolak nilai id manual — database yang mengelola nilainya sendiri, menghindari bug duplikat id.

Tipe Data Karakter

PostgreSQL menyediakan tiga tipe untuk teks: VARCHAR(n) (teks dengan batas panjang), CHAR(n) (teks panjang tetap, nilai pendek dipadding spasi), dan TEXT (teks tanpa batas panjang). Satu fakta penting: tidak ada performance penalty antara VARCHAR dan TEXT — batasan panjang di VARCHAR(n) murni validasi, bukan optimasi storage.

Contoh tipe karakter
CREATE TABLE articles (
    title VARCHAR(200) NOT NULL,
    slug TEXT NOT NULL,
    country CHAR(2) NOT NULL
);

Tip

Di PostgreSQL, gunakan TEXT sebagai default untuk kolom teks, dan baru pakai VARCHAR(n) ketika kalian memang ingin memberlakukan batas panjang sebagai business rule. Sedangkan CHAR(n) jarang dibutuhkan — pemakaiannya paling masuk akal untuk kode berukuran tetap seperti kode negara ISO.

Tipe Data Tanggal dan Waktu

TIMESTAMP vs TIMESTAMPTZ

  • TIMESTAMP: tanggal dan jam TANPA informasi timezone. Nilai seperti 2026-08-03 10:00:00 dimaknai "apa adanya".
  • TIMESTAMPTZ: tanggal dan jam DENGAN timezone awareness. Nilai disimpan dalam UTC secara internal, dan dirender sesuai timezone sesi.
Cara kerja TIMESTAMPTZ
SELECT now() AS waktu_sekarang;
SELECT now() AT TIME ZONE 'Asia/Jakarta' AS waktu_jakarta;
SHOW timezone;

DATE, TIME, dan INTERVAL

Aritmetika tanggal dengan INTERVAL
SELECT now() + INTERVAL '7 days' AS seminggu_lagi;
SELECT age('2026-08-03', '2020-01-01') AS umur_akun;

Boolean dan UUID

Boolean

Contoh BOOLEAN
CREATE TABLE users (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    email TEXT NOT NULL UNIQUE,
    is_active BOOLEAN NOT NULL DEFAULT TRUE
);

UUID

UUID adalah identitas 128-bit yang praktis mustahil bertabrakan antar sistem.

UUID dengan gen_random_uuid()
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE sessions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id INTEGER NOT NULL,
    token TEXT NOT NULL
);

Fungsi gen_random_uuid() menghasilkan UUID v4 secara acak; di PostgreSQL 13+ tersedia bawaan tanpa extension.

Constraints Management

Constraint adalah "polisi" database yang memastikan data yang masuk selalu memenuhi aturan — pertahanan terakhir yang bekerja bahkan jika aplikasi lupa memvalidasi.

NOT NULL, UNIQUE, dan PRIMARY KEY

Constraint dasar saat CREATE TABLE
CREATE TABLE customers (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email TEXT NOT NULL UNIQUE,
    phone TEXT,
    referral_code TEXT UNIQUE
);
  • NOT NULL: kolom wajib diisi; phone di atas boleh kosong karena tanpa constraint.
  • UNIQUE: tidak boleh ada duplikat nilai; satu email hanya untuk satu customer.
  • PRIMARY KEY: kombinasi NOT NULL + UNIQUE + identitas baris.

FOREIGN KEY dengan Referential Actions

ActionPerilaku
ON DELETE CASCADEHapus baris anak ikut-ikutan saat induk dihapus
ON DELETE RESTRICTTolak penghapusan jika masih ada baris anak
ON DELETE SET NULLSet kolom FK anak menjadi NULL
ON UPDATE CASCADEIkutkan perubahan nilai PK induk ke FK anak
Contoh FK dengan referential actions
CREATE TABLE orders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    customer_id UUID NOT NULL REFERENCES customers(id) ON DELETE CASCADE,
    total NUMERIC(12,2) NOT NULL CHECK (total >= 0)
);
 
CREATE TABLE order_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    order_id UUID NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
    product_name TEXT NOT NULL
);

CHECK Constraint

CHECK adalah validasi nilai kustom yang bebas — pertahanan terakhir yang bekerja bahkan jika aplikasi lupa memvalidasi.

Contoh CHECK constraint
CREATE TABLE products (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name TEXT NOT NULL,
    price NUMERIC(12,2) NOT NULL CHECK (price > 0),
    stock INTEGER NOT NULL DEFAULT 0 CHECK (stock >= 0)
);

Penutup

Inti yang harus dibawa pulang:

  • Gunakan NUMERIC untuk uang, bukan REAL — floating point bisa mengganggu presisi.
  • Prefer GENERATED ALWAYS AS IDENTITY daripada SERIAL untuk auto-increment modern.
  • Selalu pakai TIMESTAMPTZ untuk menyimpan titik waktu, kecuali ada alasan khusus.
  • UUID cocok untuk identitas global dan aplikasi terdistribusi.
  • Constraint adalah pertahanan terakhir database — CHECK, FK dengan referential action, dan UNIQUE adalah teman terbaik kalian.

Di episode 4 selanjutnya, kita mulai mengisi database dengan data: Data Manipulation Language (DML) dan Basic Querying — mulai dari INSERT untuk memasukkan data, UPDATE untuk mengubah, DELETE untuk menghapus, hingga fitur khas PostgreSQL RETURNING yang sangat berguna di dunia nyata. Siapkan tabel yang tadi kalian buat, karena episode berikutnya penuh praktik!

Belajar SQL PostgreSQL - Data Types di PostgreSQL & Constraints Management | Belajar SQL PostgreSQL