Menu
Playground'da Dene

SQLite vs PostgreSQL: Hangisini Ne Zaman Kullanmalı?

SQLite ile PostgreSQL arasındaki gerçek farklar: mimari, eşzamanlılık, tip sistemi ve hangi proje için hangisinin daha mantıklı olduğu.

Bu sayfada çalıştırılabilir editörler var — düzenle, çalıştır ve sonucu anında gör.

İki Veritabanı, İki Farklı Yapı

SQLite ve PostgreSQL'in ikisi de SQL konuşur, ilişkisel veri saklar ve gerçek uygulamalara güç verebilir. Ama bu noktadan sonra ikisi tamamen farklı dünyalar için tasarlanmış.

  • SQLite bir kütüphanedir. Uygulamanızın process'i içinde yaşar ve diskteki tek bir .db dosyasından okur. Sunucu yok, port yok, kullanıcı ayarı yok.
  • PostgreSQL bir sunucudur. Kendi process'i olarak çalışır, bir ağ portunu dinler ve uygulamanız ona bir istemci olarak bağlanır.

Aralarındaki neredeyse diğer tüm farklar — eşzamanlılık, dağıtım (deployment), tip katılığı, performans — hep bu mimari ayrımdan doğuyor. İlerlerken bunu aklınızın bir köşesinde tutun.

Mimari: Process İçi vs İstemci/Sunucu

SQLite veritabanı açmak, aslında bir dosya açmak demek:

Çalıştırılacak bir servis yok, düzenlenecek bir pg_hba.conf yok, dışarı açılacak bir port da yok. Uygulamanız SQLite kütüphanesini yükler, notes.db dosyasını açar ve sorguları çalıştırmaya başlar. Deployment dediğiniz şey, "dosyayı kopyala"dan ibaret.

Postgres tarafı ise daha çok şöyle görünür:

# Sunucuyu başlat (yönetici olarak, bir defa):
sudo systemctl start postgresql

# Ardından uygulamandan bağlan:
psql -h localhost -U alice -d mydb

Uygulamanız ayrı bir süreçle konuşur — genelde TCP üzerinden, bazen Unix socket ile. Bu ekstra katman size kurulum zamanı ve sorgu başına bir bağlantı turu maliyetine mal olur ama karşılığında ağ erişimi, çok kullanıcılı kimlik doğrulama ve gerçek anlamda eşzamanlı yazma imkânı sunar.

En Kritik Konu: Eşzamanlılık

Karar verirken çoğu zaman terazinin dengesini bu mesele bozar. SQLite yazma işlemlerini sıraya sokar: herhangi bir anda yalnızca tek bir yazıcı veritabanı dosyası üzerinde kilit tutar, diğerleri bekler. Okuma işlemleri paralel yürüyebilir (özellikle WAL modunda), ama yazma işlemleri tek tek ilerler.

Postgres ise MVCC (çok sürümlü eşzamanlılık kontrolü) ve satır seviyesinde kilitleme kullanır. Birden fazla transaction farklı satırlara aynı anda yazabilir ve birbirini bloklamaz.

Pratikte şöyle düşünün:

  • Saniyede 50 okuyucusu olan, ara sıra yazı giren bir blog mu? SQLite gayet yeterli.
  • Yüzlerce kullanıcının aynı anda stok güncellediği bir e-ticaret ödeme akışı mı? Postgres.
  • Mobil uygulamanın yerel cache'i mi? Tartışmasız SQLite.
  • Onlarca arka plan işçisiyle çalışan multi-tenant bir SaaS backend mi? Postgres.

WAL modu (PRAGMA journal_mode = WAL;) SQLite'ın eşzamanlılık tarafını ciddi şekilde rahatlatır — okuyucular yazıcıları bloklamaz — ama "aynı anda tek yazıcı" kuralını değiştirmez.

Tip Sistemleri: Esnek mi, Katı mı?

Postgres katıdır. INTEGER olarak tanımlanmış bir kolona string yazmaya kalkarsanız reddeder, nokta:

-- Postgres
CREATE TABLE t (n INTEGER);
INSERT INTO t (n) VALUES ('not a number');
-- HATA: integer türü için geçersiz giriş sözdizimi

SQLite varsayılan olarak type affinity (tip yakınlığı) kullanır; yani bu bir kural değil, daha çok bir öneridir. Aşağıdaki insert sorgusu sorunsuz çalışır:

String, INTEGER olarak tanımlanmış bir kolonda öylece duruyor. SQLite onu metin olarak saklamış. Bu esneklik bilinçli bir tasarım tercihi — hızlı prototipler için pratik, ama uzun ömürlü şemalarda başınızı ağrıtır.

SQLite'ın yeni sürümleri (3.37+) ise Postgres'e benzer şekilde davranan STRICT tabloları destekliyor:

Yeni bir SQLite projesine başlıyorsanız STRICT kullan. "Sayı kolonumda neden string var ki?" tarzı bir sürü sürprizi tek hamlede ortadan kaldırıyor.

Özellik yelpazesi

Postgres'te neredeyse her şeyden daha fazlası var: veri tipleri (diziler, aralıklar, geometrik tipler, ağ tipleri, özel enum'lar), prosedürel diller (PL/pgSQL, PL/Python), sıralamalı tam metin arama, materialized view'lar, tablo partition'ları, replikasyon, rol bazlı güvenlik ve oldukça zengin bir eklenti ekosistemi (PostGIS, TimescaleDB, pgvector).

SQLite ise temel ihtiyaçları karşılıyor ve kendi ölçeğine uygun birkaç hoş özellik ekliyor: JSON fonksiyonları, FTS5 ile tam metin arama, R-Tree index'leri, window fonksiyonları, CTE'ler, generated column'lar. Atladığı şeyler ise sunucu varlığını gerektiren her şey: kullanıcılar, roller, replikasyon, ağ erişimi.

Kabaca bir zihin haritası:

  • GIS, vektör araması ya da replikasyon mu lazım? Postgres.
  • iOS uygulamasının içine veritabanı gömmek mi gerekiyor? SQLite.
  • İkisi birden mi? Pek çok ekip geliştirme ve testi SQLite üzerinde yapıp deploy'u Postgres'e alıyor — ama bu karışım, syntax farkları yüzünden ileride canını yakabilir (aşağıya bak).

Pratikte karşılaşacağın syntax farkları

Günlük SQL'in büyük kısmı aynı. Farklar genelde şema, tipler ve birkaç yerleşik fonksiyon etrafında toplanıyor:

-- Otomatik artan birincil anahtar
-- SQLite:
CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);
-- Postgres:
CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);
-- veya, modern Postgres:
CREATE TABLE users (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT);

-- Geçerli zaman damgası
-- SQLite:  CURRENT_TIMESTAMP   (metin döndürür)
-- Postgres: NOW()              (timestamp döndürür)

-- Boolean türü
-- SQLite:  gerçek BOOLEAN yok; INTEGER 0/1 kullanın
-- Postgres: TRUE/FALSE ile BOOLEAN

Eğer geliştirme ortamında SQLite, üretim ortamında Postgres kullanıyorsanız, aralarda bir ORM veya migration aracı bulundurmak işine yarar. Aksi halde bu farklılıklar uygulamana sızmaya başlar.

Performans: İşin Doğrusu

"Hangisi daha hızlı?" sorusunun cevabı, ne yaptığına bağlı. Tek bir process'in okuma ve küçük yazma işlemleri yaptığı senaryolarda SQLite'ı geçmek zor — ortada ağ trafiği, protokol parse etme veya istemci bağlantısı yok. Tek istemcili benchmark'larda basit sorgularda SQLite çoğu zaman Postgres'i geride bırakır.

Ama işin içine eşzamanlı yazıcılar, paralel sorgu çalıştırması gereken büyük veri kümeleri ya da Postgres'in olgun planlayıcısından faydalanan karmaşık sorgu planları girdiğinde, ipi göğüsleyen Postgres oluyor. Postgres ayrıca dikey ölçekleniyor (daha büyük makineler, daha fazla çekirdek) — SQLite zaten bu amaçla tasarlanmadı.

Dürüst özet şu: SQLite kendi işinde hızlıdır. Postgres da kendi işinde hızlıdır. Seçimi benchmark başlıklarına değil, iş yükünün şekline göre yap.

Hızlı Karar Rehberi

Şu durumlarda SQLite tercih et:

  • Veri tek bir uygulamanın yanında yaşıyorsa — masaüstü, mobil, gömülü sistem, CLI aracı.
  • Yazma işlemleri tek bir process'ten ya da az sayıda process'ten geliyorsa.
  • Sıfır konfigürasyonla deploy etmek istiyorsanız.
  • Prototip aşamasındaysan ve altyapıyla değil şemayla uğraşmak istiyorsanız.

Şu durumlarda Postgres tercih et:

  • Birden fazla uygulama sunucusu ya da worker veritabanına yazıyorsa.
  • Çok sayıda istemciden ağ üzerinden erişim gerekiyorsa.
  • Gelişmiş özelliklere ihtiyacın varsa: roller, replikasyon, GIS, özel tipler, stored procedure'lar.
  • Veri, üretimdeki bir servisin kalıcı ve merkezi deposu konumundaysa.

Sık görülen bir yol haritası: küçük bir projeye SQLite ile başla, trafik şekli gerektirdiğinde Postgres'e geç. Geçiş bedavaya gelmiyor ama bilinen bir operasyon — ve projelerin çoğu bu noktaya hiç gelmiyor.

Sırada: SQLite Ne Zaman Doğru Seçim?

Yukarıdaki karşılaştırma sana ödünleşimleri gösterdi. Bir sonraki sayfada SQLite'ın olumlu tarafına daha derin bakacağız — yani SQLite'ın yalnızca idare eder değil, gerçekten daha iyi bir araç olduğu iş yüklerine ve onu artık aştığını gösteren uyarı işaretlerine.

Sıkça Sorulan Sorular

SQLite ile PostgreSQL arasındaki temel fark nedir?

SQLite, uygulamanızın kendi process'i içinde tek bir dosyayı okuyup yazan gömülü bir kütüphanedir. PostgreSQL ise ağ üzerinden bağlandığınız ayrı bir sunucudur. İşte bu mimari fark, geri kalan her şeyi belirliyor: eşzamanlılık, dağıtım, tipler ve araç ekosistemi hep buradan türüyor.

SQLite, PostgreSQL'den daha mı hızlı?

Tek process'ten yapılan okumalarda ve küçük yazma işlemlerinde çoğu zaman evet — SQLite'ta ne ağ gidiş-dönüşü ne de istemci/sunucu protokol yükü var. Ama birden fazla istemciden gelen eşzamanlı yazma söz konusu olduğunda satır seviyesinde kilitleme ve MVCC sayesinde Postgres öne geçiyor. Yani 'hangisi hızlı' sorusunun cevabı motorda değil, iş yükünde.

SQLite production'da kullanılır mı?

Doğru tipte iş yükü için kesinlikle evet. SQLite; web siteleri, masaüstü uygulamaları ve gömülü cihazlarda production ortamında gayet iyi çalışıyor. Asıl kırılma noktası eşzamanlı yazıcılar: aynı anda yazmak isteyen çok sayıda process varsa bunu Postgres doğal yoldan halleder, SQLite ise yazmaları sıraya sokar. WAL modu işi rahatlatır ama bu sınırı tamamen ortadan kaldırmaz.

SQLite'tan PostgreSQL'e nasıl geçilir?

Şema ve veriyi sqlite3 mydb.db .dump ile dışa aktarın, sonra SQL'i biraz elden geçirin: AUTOINCREMENT yerine SERIAL ya da GENERATED AS IDENTITY gelir, tip isimleri değişir, SQLite'ın gevşek tiplemesi gibi bazı tuhaflıkların temizlenmesi gerekir. pgloader gibi araçlar bu işin büyük kısmını otomatikleştiriyor. SQLite'ın esnek tiplemesine bel bağlamış her şeyi yeniden yazmaya hazırlıklı olun.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA