Sitemize hoşgeldiniz!  ::  Son eklenen yazı: Git’te “master” mı “main” mi? Bir kelimenin ardındaki hikâye  ::  Toplam 63 yazı  ::  Görüş ve önerileriniz için iletişim sayfasını kullanabilirsiniz.
» Menü
Anasayfa
Hakkımda
İletişim
» Kategoriler
› nostalji (8)
› laravel (7)
› php (5)
› web (3)
› agile (3)
› go (2)
› golang (2)
› api (2)
› redis (2)
› git (2)
› github (2)
› model (1)
» Arşiv
› Ekim 2025 (2)
› Temmuz 2025 (1)
› Nisan 2025 (3)
› Mart 2025 (5)
› Şubat 2025 (1)
› Ocak 2025 (43)
› Haziran 2011 (1)
› Kasım 2009 (1)
› Temmuz 2009 (1)
› Temmuz 2007 (1)
› Ocak 2007 (1)
› Kasım 2006 (1)
› Ekim 2006 (1)
› Ağustos 2006 (1)
Anasayfa » Yazılar » PostgreSQL Mini‑Kılavuz
PostgreSQL Mini‑Kılavuz
Yazan: Atilla Mutlu | Tarih: 14.07.2025 08:40 | Kategori: postgresql

*SQL güvenlik ve performans çıtasını yukarı taşıyan pratik bir yol haritası.


1. Temel Yapılar

1.1. Tablo Oluştur

CREATE TABLE urunler (
    id          SERIAL PRIMARY KEY,
    ad          TEXT            NOT NULL,
    kategori    TEXT            NOT NULL,
    fiyat       NUMERIC(10,2)   CHECK (fiyat >= 0),
    stok        INT             DEFAULT 0 CHECK (stok >= 0),
    aktif       BOOLEAN         DEFAULT TRUE
);

İpucu: PostgreSQL 17’de SERIAL yerine identity sütun kullan:

id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY

Sekans yönetimini otomatikleştirir.

1.2. CRUD Örnekleri

-- INSERT
INSERT INTO urunler (ad, kategori, fiyat, stok)
VALUES ('USB‑C Hub', 'Elektronik', 349.90, 25)
RETURNING id;

-- SELECT
SELECT id,
       ad                AS urun,
       fiyat || ' ₺'     AS fiyat_etiket,
       stok,
       CASE WHEN stok = 0 THEN 'Stok Yok' ELSE 'Var' END AS durum
FROM urunler
WHERE aktif IS TRUE
ORDER BY fiyat DESC
LIMIT 10;

-- UPDATE
UPDATE urunler
SET stok = stok - 1
WHERE id = 42;

-- DELETE (kampanya bitince)
DELETE FROM urunler
WHERE aktif IS FALSE AND stok = 0;

2. İlişkiler & JOIN’ler

-- Basit JOIN: sipariş detayındaki ürün bilgisi
SELECT u.ad, u.kategori, sd.miktar
FROM urunler u
JOIN siparis_detay sd  ON sd.urun_id = u.id
WHERE sd.birim_fiyat > 100;

-- LEFT JOIN + agregasyon: hiç satmayan ürünleri bul
SELECT u.id,
       COALESCE(SUM(sd.miktar), 0) AS toplam_satis
FROM urunler u
LEFT JOIN siparis_detay sd ON sd.urun_id = u.id
GROUP BY u.id
HAVING SUM(sd.miktar) IS NULL;

Performans Tüyosu: JOIN’lenen sütunlara (siparis_detay.urun_id) mutlaka indeks bas. Yabancı anahtarlar için ON DELETE CASCADE ya da DEFERRABLE senaryolarını değerlendir.


3. Güvenlik — “Veri kalesini” sağlamlaştır

Tehdit Karşı Hamle
SQL Injection Parametreli sorgu ($1, pg_prepare, PDO::prepare`).
Aşırı yetki CREATE ROLE readonly LOGIN...; sonra sadece gerekli tablolara GRANT SELECT.
Şifreler Sunucu‑CLI SSL (hostssl), scram-sha-256 auth; uygulama katmanında Argon2/BCrypt hash.
Veri sızıntısı Sütun şifreleme (pgcrypto), satır düzeyi politikalar (Row‑Level Security).
Kaza‑silme WAL + pg_basebackup; v17’de artımlı yedek (delta) desteği.

🔐 Ekstra: Trigger ile “soft delete” (örn. deleted_at) tut, yetkisi olmayan kullanıcılara WHERE deleted_at IS NULL filtreli view göster.


4. Performans — “Uçan” sorgular için reçete

  1. İndeks Stratejisi

    • btree → eşitlik/sırala
    • hash  → saf eşitlik (v17’de hızlandı)
    • GIN/GIST → JSONB, coğrafi, full‑text
  2. EXPLAIN (ANALYZE, BUFFERS) ile plan oku:

    EXPLAIN (ANALYZE, BUFFERS)
    SELECT * FROM urunler WHERE ad ILIKE 'usb%';
  3. Autovacuum Ayarı — büyük tablolarda autovacuum_vacuum_scale_factor = 0.02 gibi agresif değer.
  4. Konfig:

    • shared_buffers = 25% RAM
    • work_mem = (eşzamanlı sorgu × 1–2 MB)
    • maintenance_work_mem = rebuild/vacuum sırasında yüksek tut
  5. PostgreSQL 17 Bonusları

    • Streaming I/O → sekansiyel taramada %20 hız
    • Adaptive Vacuum → yoğun trafikte daha az dur‑kalk
    • JSON_TABLE() → JSON’u satırlara aç, sonra join
  6. Connection Pool → PgBouncer / PgCat.
  7. Partisyonlama → yıllık veya kategori bazlı tablolar; eski partisyonu DETACH edip salt‑okunur sakla.

5. Mikroservis / Modüler Data Layer

  • Schema‑per‑module: CREATE SCHEMA stok;, siparis; vb. Çakışma riskini sıfırlar.
  • Foreign Data Wrapper (postgres_fdw) ile modüller arası sorgu, ya da
  • Logical Replication — modül A’daki urunler tablosunu modül B’ye yayınla; v17’de failover kontrolü geldi.
  • Event Bus: LISTEN/NOTIFY ile hafif publish–subscribe.

6. Öğrenme Rotaları & Alıştırmalar

  1. Challenge — “Kritik stok” fonksiyonu yaz:

    CREATE OR REPLACE FUNCTION urun_kritik_stokta_mi(p_id INT)
    RETURNS BOOLEAN LANGUAGE plpgsql AS $$
    DECLARE
       s INT;
    BEGIN
       SELECT stok INTO s FROM urunler WHERE id = p_id;
       RETURN s < 10;  -- eşik değeri
    END;
    $$;
  2. Index Lab — generate_series ile 1 M satırlık sahte veri doldur; btree vs gin arası hız farkını ölç.
  3. RLS Görevi — tedarikçi bazlı satır politikası: tedarikci_id = current_user.

7. Son Tüyolar

  • Versiyon Güncellemesi — 15→17 in‑place upgrade artık tek tık; downtime kısa.
  • pg_stat_statements → yavaş sorguları sınıflandır; sonra gereken yerde CREATE INDEX / REFRESH MATERIALIZED VIEW.
  • Test ≠ Prod — staging’de farklı work_mem/istatistik hedefi, hatalı plan doğurur.
  • CLI Ninja Move — \watch 1 ile psql çıktısını saniyelik güncelle; canlı monitoring gibi.

Şimdi terminali aç, birkaç EXPLAIN patlat: kaç satır diskten geldi, kaç buffer hit oldu bir bak. Sonra kahveni yudumla; bir sonraki optimizasyon turunda görüşürüz! 🚀

« Geri dön | Yorum gönder | Yukarı ↑
» Hakkımda
A
Atilla Mutlu
Yazılım Geliştirici

Devamını oku »
» Son Yazılar
› Git’te “master” mı “main” mi? Bir kelimenin ardındaki hikâye
› Laravel Model Controller
› PostgreSQL Mini‑Kılavuz
› ReactJS Rehberi
› Spatie Laravel Paketleri
» İstatistik
Ziyaretçi Sayısı
036356
Toplam yazı: 63
PHPpowered SQLiteinside Firefoxile daha iyi CSStables ♥
Bu site en iyi 1024x768 çözünürlükte görüntülenir.
Copyright © 2006-2026
Anasayfa | Hakkımda | İletişim | Yukarı ↑
Bu sayfa 0,016 saniyede oluşturuldu.