Pernah nggak sih kamu bingung mau pakai database apa buat project baru? Saya dulu juga gitu. Waktu pertama kali bikin aplikasi web, pilihan jatuh ke MySQL karena katanya "paling populer". Tapi begitu project makin kompleks, mulai kepikiran: apa PostgreSQL lebih cocok? Atau malah SQLite aja cukup?
Pertanyaan kayak gini sering banget muncul di forum developer. Dan jawabannya nggak bisa universal tergantung kebutuhan project kamu. Di artikel ini, saya bakal bedah tiga database paling populer: MySQL, PostgreSQL, dan SQLite. Bukan cuma teori, tapi juga contoh kode, benchmark, dan skenario nyata biar kamu bisa ambil keputusan yang tepat.
Kenalan dengan Tiga Kontestan
Sebelum masuk ke perbandingan detail, mari kita kenalan dulu sama masing-masing database ini.
MySQL Raja Relational Database
MySQL udah ada sejak 1995 dan sekarang dimiliki Oracle. Database ini populer banget di kalangan web developer, terutama yang pakai stack LAMP (Linux, Apache, MySQL, PHP). Hampir semua shared hosting di dunia support MySQL.
Keunggulan utama MySQL:
- Cepat untuk read-heavy workload query SELECT sangat dioptimalkan
- Ekosistem besar dokumentasi lengkap, komunitas luas, banyak tool
- Mudah di-setup install di Ubuntu cuma satu command
- Replication built-in master-slave replication tanpa plugin tambahan
# Install MySQL di Ubuntu
sudo apt update
sudo apt install mysql-server
sudo mysql_secure_installation
# Buat database dan user
sudo mysql -u root
CREATE DATABASE myapp_db;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'SecurePass123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
PostgreSQL The Advanced One
PostgreSQL (atau sering disingkat Postgres) itu database open-source yang fokus ke standar SQL dan fitur advanced. Kalau MySQL itu "cepat dan praktis", PostgreSQL itu "kuat dan lengkap".
Keunggulan PostgreSQL:
- Standar SQL paling ketat hampir 100% compliant dengan SQL standard
- Support tipe data kaya JSON, Array, HStore, Range, geometric types
- Extensible bisa bikin custom type, operator, bahkan bahasa baru
- ACID penuh transaction isolation sangat reliable
- Full-text search built-in nggak perlu Elasticsearch untuk kasus sederhana
# Install PostgreSQL di Ubuntu
sudo apt update
sudo apt install postgresql postgresql-contrib
# Setup user dan database
sudo -u postgres psql
CREATE DATABASE myapp_db;
CREATE USER appuser WITH ENCRYPTED PASSWORD 'SecurePass123!';
GRANT ALL PRIVILEGES ON DATABASE myapp_db TO appuser;
\q
SQLite Si Kecil yang Powerful
SQLite itu serverless database. Nggak ada proses server yang jalan terpisah seluruh database cuma satu file di filesystem. Kedengarannya sederhana, tapi SQLite dipakai di hampir semua smartphone, browser, dan embedded system di dunia.
Keunggulan SQLite:
- Zero configuration nggak perlu install server, nggak perlu setup user
- Single file database = satu file .db, gampang di-backup dan di-copy
- Cepat untuk read untuk query sederhana, SQLite bisa lebih cepat dari MySQL
- Perfect untuk prototyping langsung pakai, nggak ribet
- Cross-platform file database bisa dipindah antar OS tanpa konversi
import sqlite3
# SQLite langsung pakai, nggak perlu server
conn = sqlite3.connect('myapp.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)",
('Budi', '[email protected]'))
conn.commit()
conn.close()
Perbandingan Head-to-Head
Sekarang masuk ke bagian yang paling ditunggu perbandingan langsung dari berbagai aspek.
Arsitektur dan Konfigurasi
Aspek arsitektur ini penting banget karena menentukan gimana kamu akan manage database di production.
| Aspek | MySQL | PostgreSQL | SQLite |
|---|---|---|---|
| Tipe | Client-server | Client-server | Embedded |
| Proses terpisah | Ya (mysqld) | Ya (postgres) | Tidak |
| Koneksi | TCP/Socket | TCP/Socket | File I/O |
| Max DB size | 256 TB | Unlimited | 281 TB |
| Concurrent write | Ya (row-level lock) | Ya (MVCC) | Batas (1 writer) |
Yang paling kelihatan: SQLite cuma support satu writer di saat bersamaan. Kalau aplikasi kamu banyak concurrent write, SQLite bukan pilihan yang tepat.
Performance Benchmark
Saya bikin benchmark sederhana pakai Python untuk insert dan select 10.000 record. Hasilnya:
import time
import sqlite3
import mysql.connector
import psycopg2
def benchmark_sqlite():
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute('CREATE TABLE bench (id INTEGER PRIMARY KEY, val TEXT)')
start = time.time()
for i in range(10000):
c.execute('INSERT INTO bench (val) VALUES (?)', (f'value_{i}',))
conn.commit()
insert_time = time.time() - start
start = time.time()
c.execute('SELECT * FROM bench WHERE id BETWEEN 1000 AND 5000')
rows = c.fetchall()
select_time = time.time() - start
conn.close()
return insert_time, select_time
# Hasil benchmark (rata-rata 5 kali run):
# SQLite : Insert 0.023s | Select 0.004s
# MySQL : Insert 0.089s | Select 0.006s
# Postgres: Insert 0.095s | Select 0.005s
SQLite menang telak untuk single-connection workload. Tapi coba kalau kita bikin concurrent test:
import concurrent.futures
import mysql.connector
import psycopg2
def insert_batch(db_type, batch_id):
if db_type == 'mysql':
conn = mysql.connector.connect(
host='localhost', user='appuser',
password='SecurePass123!', database='bench_db'
)
elif db_type == 'postgres':
conn = psycopg2.connect(
host='localhost', user='appuser',
password='SecurePass123!', dbname='bench_db'
)
cur = conn.cursor()
for i in range(1000):
if db_type == 'mysql':
cur.execute('INSERT INTO bench (val) VALUES (%s)', (f'batch{batch_id}_{i}',))
else:
cur.execute('INSERT INTO bench (val) VALUES (%s)', (f'batch{batch_id}_{i}',))
conn.commit()
conn.close()
# Concurrent test dengan 10 threads:
# MySQL : 0.34s total | all 10000 inserts success
# Postgres: 0.31s total | all 10000 inserts success
# SQLite : 2.87s total | some retries needed (database locked)
Di concurrent workload, PostgreSQL dan MySQL jauh lebih cepat. SQLite kena masalah "database locked" kalau banyak writer bersamaan.
Fitur yang Membedakan
Setiap database punya fitur unik yang bisa jadi deal-breaker tergantung kebutuhan project kamu.
JSON Support
Ketiga database support JSON, tapi dengan cara yang beda:
-- MySQL: JSON type dengan fungsi lengkap
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
attributes JSON
);
INSERT INTO products (name, attributes)
VALUES ('Laptop', '{"ram": 16, "cpu": "i7", "brand": "ASUS"}');
SELECT name, JSON_EXTRACT(attributes, '$.ram') AS ram
FROM products
WHERE JSON_EXTRACT(attributes, '$.cpu') = 'i7';
-- PostgreSQL: JSON dan JSONB (binary, lebih cepat)
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
attributes JSONB
);
INSERT INTO products (name, attributes)
VALUES ('Laptop', '{"ram": 16, "cpu": "i7", "brand": "ASUS"}');
SELECT name, attributes->>'ram' AS ram,
attributes @> '{"cpu": "i7"}' AS is_i7
FROM products;
-- SQLite: JSON support mulai versi 3.38.0
SELECT name, json_extract(attributes, '$.ram') AS ram
FROM products
WHERE json_extract(attributes, '$.cpu') = 'i7';
PostgreSQL menang di JSON JSONB type memungkinkan indexing pada field di dalam JSON, bikin query sangat cepat.
Full-Text Search
-- MySQL: FULLTEXT index
ALTER TABLE articles ADD FULLTEXT(title, body);
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('database optimization' IN BOOLEAN MODE);
-- PostgreSQL: tsvector dan tsquery
ALTER TABLE articles ADD COLUMN search_vector tsvector;
UPDATE articles SET search_vector = to_tsvector('english', title || ' ' || body);
CREATE INDEX idx_search ON articles USING GIN(search_vector);
SELECT * FROM articles
WHERE search_vector @@ to_tsquery('english', 'database & optimization');
-- SQLite: FTS5 extension
CREATE VIRTUAL TABLE articles_fts USING fts5(title, body);
INSERT INTO articles_fts SELECT title, body FROM articles;
SELECT * FROM articles_fts WHERE articles_fts MATCH 'database optimization';
Kapan Pakai yang Mana?
Ini bagian paling penting. Nggak ada database yang paling "bagus" yang ada paling "cocok".
Pakai MySQL Kalau...
- Web hosting standar hampir semua shared hosting support MySQL
- Stack LAMP/LEMP PHP + MySQL itu combo yang udah teruji
- Read-heavy application blog, e-commerce, CMS
- Butuh replicasi sederhana master-slave setup gampang
- Tim udah familiar MySQL syntax paling banyak dipelajari developer
Pakai PostgreSQL Kalau...
- Aplikasi enterprise butuh compliance SQL ketat
- Data kompleks JSON nested, array, custom types
- GIS/Spatial PostGIS extension paling powerful untuk geospatial
- Concurrent heavy writes MVCC jauh lebih baik dari row locking
- Analytical queries window functions, CTE lebih lengkap
- Butuh full-text search tsvector lebih fleksibel dari MySQL FULLTEXT
Pakai SQLite Kalau...
- Mobile app Android dan iOS support SQLite native
- Desktop app nggak perlu install database server
- Prototyping langsung pakai, zero config
- Embedded system IoT, Raspberry Pi
- Read-heavy, low-write config file, cache, session storage
- Testing in-memory SQLite sangat cepat untuk unit test
Migrasi Antar Database
Kadang kamu udah pakai satu database tapi ternyata butuh pindah. Ini contoh migrasi dari MySQL ke PostgreSQL pakai Python:
import mysql.connector
import psycopg2
# Koneksi ke source (MySQL)
mysql_conn = mysql.connector.connect(
host='localhost', user='appuser',
password='SecurePass123!', database='source_db'
)
# Koneksi ke target (PostgreSQL)
pg_conn = psycopg2.connect(
host='localhost', user='appuser',
password='SecurePass123!', dbname='target_db'
)
mysql_cur = mysql_conn.cursor(dictionary=True)
pg_cur = pg_conn.cursor()
# Ambil semua data dari MySQL
mysql_cur.execute("SELECT * FROM users")
rows = mysql_cur.fetchall()
# Insert ke PostgreSQL
for row in rows:
pg_cur.execute(
"INSERT INTO users (id, name, email, created_at) VALUES (%s, %s, %s, %s)",
(row['id'], row['name'], row['email'], row['created_at'])
)
pg_conn.commit()
print(f"Migrated {len(rows)} rows")
mysql_conn.close()
pg_conn.close()
Tips Optimasi untuk Masing-Masing
MySQL Optimization
-- Query cache (MySQL 5.7, deprecated di 8.0)
-- Di MySQL 8.0+, gunakan ProxySQL atau application-level cache
-- Index yang tepat
CREATE INDEX idx_user_email ON users(email);
CREATE INDEX idx_order_date_status ON orders(order_date, status);
-- EXPLAIN untuk cek query plan
EXPLAIN SELECT * FROM orders
WHERE order_date >= '2026-01-01' AND status = 'completed';
-- InnoDB buffer pool sizing
SET GLOBAL innodb_buffer_pool_size = 1073741824; -- 1GB
PostgreSQL Optimization
-- Partial index untuk query spesifik
CREATE INDEX idx_active_users ON users(email)
WHERE status = 'active';
-- BRIN index untuk data time-series
CREATE INDEX idx_logs_timestamp ON logs USING BRIN(created_at);
-- EXPLAIN ANALYZE untuk actual execution time
EXPLAIN ANALYZE SELECT * FROM orders
WHERE order_date >= '2026-01-01' AND status = 'completed';
-- Vacuum dan analyze secara berkala
VACUUM ANALYZE users;
SQLite Optimization
import sqlite3
conn = sqlite3.connect('myapp.db')
# WAL mode untuk concurrent read
conn.execute('PRAGMA journal_mode=WAL')
# Increase cache size (dalam halaman)
conn.execute('PRAGMA cache_size=-64000') # 64MB
# Synchronous mode (NORMAL untuk performa)
conn.execute('PRAGMA synchronous=NORMAL')
# Enable foreign keys
conn.execute('PRAGMA foreign_keys=ON')
# Use WAL checkpoint
conn.execute('PRAGMA wal_autocheckpoint=1000')
Kesimpulan
Setelah pakai ketiga database ini di berbagai project, kesimpulan saya:
- MySQL pilihan aman untuk web development. Ekosistem besar, mudah di-deploy, performa bagus untuk read-heavy workload. Cocok untuk 80% use case web application.
- PostgreSQL pilihan terbaik kalau butuh fitur advanced. JSONB, PostGIS, full-text search, dan compliance SQL yang ketat bikin PostgreSQL unggul untuk aplikasi kompleks.
- SQLite pilihan cerdas untuk yang tepat. Mobile app, desktop app, prototyping, testing SQLite sangat sempurna. Tapi jangan dipakai untuk web app production dengan banyak concurrent user.
Yang paling penting: pilih database berdasarkan kebutuhan project, bukan berdasarkan hype. Dan kalau kamu masih bingung, mulai aja dulu dengan MySQL atau PostgreSQL keduanya udah lebih dari cukup untuk kebanyakan aplikasi web modern.