Apa Itu Sebenarnya?
PostgreSQL dan Azure SQL adalah dua sistem manajemen basis data relasional yang secara luas diadopsi di industri modern, namun keduanya memiliki filosofi, arsitektur, dan model bisnis yang sangat berbeda. PostgreSQL adalah sistem basis data open-source yang pertama kali dirilis pada tahun 1996, berakar dari proyek POSTGRES di University of California, Berkeley. Selama lebih dari dua dekade, PostgreSQL telah berkembang menjadi salah satu RDBMS open-source paling canggih di dunia, dengan dukungan penuh terhadap SQL standar, tipe data lanjutan seperti JSONB dan array, serta ekosistem ekstensi yang kaya termasuk PostGIS untuk data geospasial dan pgvector untuk pencarian vektor. Di sisi lain, Azure SQL adalah layanan basis data terkelola (managed database service) dari Microsoft Azure yang dibangun di atas mesin Microsoft SQL Server. Azure SQL hadir dalam tiga varian utama: Azure SQL Database (single database), Azure SQL Managed Instance (kompatibilitas penuh dengan SQL Server on-premises), dan Azure SQL Edge (untuk perangkat IoT). Pentingnya memahami perbedaan keduanya tidak bisa diremehkan, karena keputusan pemilihan basis data berdampak langsung pada arsitektur aplikasi, anggaran operasional jangka panjang, kemampuan scaling, serta produktivitas tim pengembang.
Secara head-to-head, PostgreSQL unggul dalam fleksibilitas dan kebebasan—ia dapat diinstal di mana saja, di-modifikasi, dan dijalankan tanpa biaya lisensi. Azure SQL unggul dalam kenyamanan operasional—Microsoft menangani patching, high availability, backup, dan tuning secara otomatis. Dari segi fitur, PostgreSQL mendukung extensible type system, custom aggregates, dan procedural languages (PL/pgSQL, PL/Python, PL/Perl), sementara Azure SQL menawarkan integrasi mendalam dengan ekosistem Microsoft seperti Active Directory, Power BI, dan Azure Synapse Analytics. Dari perspektif harga, PostgreSQL gratis secara lisensi namun memerlukan investasi signifikan dalam DevOps dan infrastruktur jika di-host sendiri; alternatifnya, layanan managed PostgreSQL tersedia di AWS RDS, Azure Database for PostgreSQL, atau Google Cloud SQL dengan harga mulai dari sekitar $12/bulan untuk instance terkecil. Azure SQL Database memulai harga dari sekitar $5/bulan untuk tier Basic, namun biaya dapat melonjak drastis ketika kebutuhan compute dan storage meningkat, terutama pada tier Business Critical yang bisa mencapai ribuan dolar per bulan.
Cara Kerjanya di Balik Layar
Konsep inti PostgreSQL berakar pada arsitektur process-per-connection, di mana setiap koneksi klien mendapatkan proses backend tersendiri yang disebut postgres process. Multi-version concurrency control (MVCC) adalah tulang punggung PostgreSQL—setiap transaksi melihat snapshot konsisten dari data tanpa mengunci pembaca, sehingga reader tidak pernah memblokir writer dan sebaliknya. Write-Ahead Logging (WAL) memastikan durabilitas data: setiap modifikasi ditulis ke log sebelum perubahan diterapkan ke data file, sehingga dalam kejadian crash, recovery dapat dilakukan dengan replaying WAL. PostgreSQL juga menggunakan konsep tablespace untuk pengaturan penyimpanan fisik, dan partitioning declarative sejak versi 10 untuk memecah tabel besar menjadi partisi yang lebih mudah dikelola. Autovacuum daemon berjalan di latar belakang untuk menghapus tuple yang sudah tidak terlihat (dead tuples) akibat MVCC dan menganalisis statistik untuk query planner.
Azure SQL beroperasi pada paradigma yang sangat berbeda sebagai layanan PaaS. Di balik layar, setiap Azure SQL Database berjalan dalam isolasi yang disebut database shard, di mana beberapa database dari berbagai pelanggan dapat berbagi infrastruktur fisik yang sama (multi-tenant) pada tier General Purpose, atau berjalan di hardware dedicated pada tier Business Critical. Komponen utama mencakup SQL Engine yang sama dengan SQL Server on-premises, namun ditambahkan dengan lapisan Service Fabric yang mengelola lifecycle, failover, dan health monitoring. Azure SQL menggunakan arsitektur compute-storage separation pada tier Hyperscale—compute nodes bersifat stateless dan dapat di-scale secara independen dari storage yang disimpan di Azure Blob Storage dengan multiple replicas. High availability dijamin oleh Always On Availability Groups secara transparan; pelanggan tidak perlu mengkonfigurasi replication atau failover secara manual. Intelligent Database Advisor dan Automatic Tuning memonitor workload secara berkontanu dan dapat secara otomatis membuat atau menghapus indeks berdasarkan pola query yang diamati.
Komponen utama dalam ekosistem PostgreSQL meliputi postmaster (process utama yang menerima koneksi), autovacuum launcher, bgwriter (background writer yang menulis dirty pages ke disk), WAL writer, checkpointer, dan stats collector. Di Azure SQL, komponen yang terlihat oleh pengguna adalah database itu sendiri, logical server (gateway untuk koneksi dan kebijakan firewall), elastic pool (untuk sharing resource antar database), dan geo-replication link untuk disaster recovery lintas region.
Praktik di Dunia Nyata
Skenario 1: Membuat tabel dan memasukkan data dasar
Pertama, mari kita lihat bagaimana operasi CRUD dasar dilakukan di kedua platform. Di PostgreSQL, kita membuat tabel dengan tipe data yang kaya termasuk JSONB untuk data semi-terstruktur:
-- PostgreSQL
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(200) NOT NULL,
attributes JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
INSERT INTO products (name, attributes)
VALUES ('Laptop Pro', '{"cpu": "i9", "ram": 32, "ssd": 1024}');
SELECT name, attributes->>'cpu' AS cpu_model
FROM products
WHERE attributes @> '{"ram": 32}'::jsonb;
name | cpu_model
-----------+-----------
Laptop Pro| i9
(1 row)
Di Azure SQL, pendekatan serupa menggunakan tipe data NVARCHAR untuk JSON dan fungsi JSON bawaan sejak SQL Server 2016:
-- Azure SQL
CREATE TABLE products (
id INT IDENTITY(1,1) PRIMARY KEY,
name NVARCHAR(200) NOT NULL,
attributes NVARCHAR(MAX),
created_at DATETIME2 DEFAULT SYSUTCDATETIME()
);
INSERT INTO products (name, attributes)
VALUES ('Laptop Pro', N'{"cpu": "i9", "ram": 32, "ssd": 1024}');
SELECT name, JSON_VALUE(attributes, '$.cpu') AS cpu_model
FROM products
WHERE JSON_VALUE(attributes, '$.ram') = '32';
name | cpu_model
-----------+-----------
Laptop Pro | i9
(1 row affected)
Perbedaan mencolok: PostgreSQL menggunakan operator @> untuk JSON containment query yang memanfaatkan GIN index secara efisien, sementara Azure SQL mengandalkan JSON_VALUE yang merupakan extract function—untuk performa optimal, Azure SQL memerlukan computed column dengan index.
Skenario 2: Full-text search
PostgreSQL memiliki fts bawaan yang powerful, sedangkan Azure SQL juga mendukung FTS tetapi dengan konfigurasi yang berbeda:
-- PostgreSQL: Full-text search dengan tsvector
ALTER TABLE products ADD COLUMN search_vector tsvector
GENERATED ALWAYS AS (to_tsvector('english', name)) STORED;
CREATE INDEX idx_fts ON products USING GIN(search_vector);
SELECT name
FROM products
WHERE search_vector @@ to_tsquery('english', 'laptop');
-- Azure SQL: Full-text search
CREATE FULLTEXT CATALOG ft_catalog AS DEFAULT;
CREATE FULLTEXT INDEX ON products(name) KEY INDEX PK_products;
SELECT name
FROM products
WHERE CONTAINS(name, 'laptop');
Skenario 3: Monitoring performa query
-- PostgreSQL: Menggunakan pg_stat_statements
SELECT query, calls, total_exec_time, mean_exec_time, rows
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 5;
query | calls | total_exec_time | mean_exec_time | rows
--------------------------------------------+-------+-----------------+----------------+------
SELECT * FROM products WHERE attributes @> | 142 | 2345.67 | 16.52 | 284
SELECT name FROM products WHERE search_vec | 891 | 891.23 | 1.00 | 8910
(2 rows)
-- Azure SQL: Menggunakan Query Store
SELECT TOP 5
qs.query_id,
qt.query_sql_text,
rs.avg_duration,
rs.count_executions
FROM sys.query_store_query q
JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
JOIN sys.query_store_plan p ON q.query_id = p.query_id
JOIN sys.query_store_runtime_stats rs ON p.plan_id = rs.plan_id
ORDER BY rs.avg_duration DESC;
Skenario 4: Konfigurasi koneksi dari aplikasi
# PostgreSQL (psycopg2)
import psycopg2
conn = psycopg2.connect(
host="pg-server.postgres.database.azure.com",
dbname="mydb",
user="admin@pg-server",
password="secret",
sslmode="require"
)
# Azure SQL (pyodbc)
import pyodbc
conn = pyodbc.connect(
"Driver={ODBC Driver 18 for SQL Server};"
"Server=tcp:sql-server.database.windows.net,1433;"
"Database=mydb;"
"Uid=admin@sql-server;"
"Pwd=secret;"
"Encrypt=yes;"
"TrustServerCertificate=no;"
"Connection Timeout=30;"
)
Skenario 5: Backup dan restore
# PostgreSQL: Manual backup dengan pg_dump
pg_dump -h pg-server -U admin -d mydb -F c -f mydb_backup.dump
# Restore
pg_restore -h pg-server -U admin -d mydb_restored mydb_backup.dump
Di Azure SQL, backup dilakukan secara otomatis setiap beberapa menit dengan retention default 7 hari (bisa diperpanjang hingga 35 hari). Restore dapat dilakukan melalui portal atau T-SQL:
-- Azure SQL: Point-in-time restore
CREATE DATABASE mydb_restored
AS COPY OF mydb (SERVICE_OBJECTIVE = 'S3');
Masalah Umum dan Cara Mengatasinya
Masalah paling umum pada PostgreSQL dalam konteks production adalah koneksi exhaustion. Setiap koneksi memakan proses OS terpisah, dan default max_connections adalah 100—terlalu rendah untuk aplikasi high-traffic namun terlalu tinggi jika setiap koneksi idle menghabiskan ~10MB memori. Solusi terbaik adalah menggunakan connection pooler seperti PgBouncer di mode transaction-level pooling, yang memungkinkan ribuan klien berbagi puluhan koneksi backend. Konfigurasi PgBouncer yang optimal biasanya menetapkan pool_mode = transaction, max_client_conn = 10000, dan default_pool_size = 20 per database. Masalah kedua yang sering terjadi adalah autovacuum yang tidak cukup agresif pada tabel dengan write intensity tinggi, menyebabkan bloat. Solusinya adalah menyesuaikan parameter autovacuum_vacuum_scale_factor ke nilai lebih kecil (misalnya 0.05 daripada default 0.2) pada tabel yang sering di-update, dan memonitor pg_stat_user_tables.n_dead_tup secara berkala.
Pada Azure SQL, masalah yang paling sering ditemui adalah DTU exhaustion. Setiap database memiliki batas DTU (Database Transaction Unit) yang menggabungkan compute, I/O, dan log write menjadi satu metrik. Ketika workload mendekati atau melebihi batas DTU, query akan mengalami throttling dan timeout. Solusi jangka pendek adalah meningkatkan service tier, namun solusi jangka panjang yang lebih efisien secara biaya adalah mengidentifikasi query yang mengonsumsi DTU berlebih melalui sys.dm_db_resource_stats dan mengoptimasikannya—misal