Sql & Veritabanı İle Uygulamalar İçin Veri İstemci Önbelleği Nasıl Yapılır?

Sql & Veritabanı İle Uygulamalar İçin Veri İstemci Önbelleği Nasıl Yapılır?
Sql & Veritabanı İle Uygulamalar İçin Veri İstemci Önbelleği Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Uygulamanızda veri istemci önbelleği mekanizmasını kurmadan önce, temel bileşenleri hazırlamanız gerekir. Bu yapı için modern bir backend (Node.js, PHP veya Python gibi), bir veritabanı yönetim sistemi (PostgreSQL veya MySQL) ve istemci tarafında modern bir JavaScript framework'ü kullanmanız önerilir.

  • Veritabanı: SQL tabanlı bir RDBMS (Relational Database Management System).
  • İstemci: Modern tarayıcı desteği (LocalStorage, IndexedDB).
  • API Katmanı: JSON tabanlı veri alışverişi yapan REST veya GraphQL uç noktaları.
  • Sürüm Kontrolü: Veri tutarlılığı için zaman damgaları (timestamps) veya ETag başlıkları.

Adım 1: Veritabanı Tarafında Versiyon Kontrolü

İstemci tarafında önbellek kullanırken en büyük sorun "bayat veri" (stale data) problemidir. Veritabanındaki veri değiştiğinde istemcinin bunu anlaması gerekir. Bunun için her tabloya bir updated_at sütunu eklemek en güvenli yöntemdir.

-- SQL tablosuna güncelleme zaman damgası ekleme
ALTER TABLE kullanicilar ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

Bu sütun, istemcinin sunucuya "Veri en son ne zaman değişti?" diye sormasını sağlar. Eğer sunucudaki updated_at değeri istemcideki ile aynıysa, veriyi tekrar çekmeye gerek kalmaz.

Adım 2: İstemci Tarafında Veri Saklama Mantığı

Tarayıcıda verileri saklamak için localStorage basit veriler için uygundur, ancak daha büyük veri setleri için IndexedDB kullanmalısınız. Aşağıdaki örnekte, bir API'den gelen verinin nasıl kaydedileceğini ve kontrol edileceğini görebilirsiniz.

// Basit bir önbellek kontrol fonksiyonu
async function getVeri(url) {
    const cacheKey = 'app_data_cache';
    const cached = localStorage.getItem(cacheKey);
    
    if (cached) {
        const data = JSON.parse(cached);
        // Verinin süresi dolmuş mu kontrolü (örneğin 1 saat)
        if (Date.now() - data.timestamp < 3600000) {
            return data.payload;
        }
    }

    const response = await fetch(url);
    const payload = await response.json();
    localStorage.setItem(cacheKey, JSON.stringify({ payload, timestamp: Date.now() }));
    return payload;
}

Bu kod, veriyi önce yerel depolamada arar. Eğer veri yoksa veya süresi dolmuşsa, sunucudan çeker ve günceller.

Adım 3: ETag ve HTTP Önbellekleme Başlıkları

HTTP protokolü, önbellekleme için yerleşik mekanizmalara sahiptir. Sunucunuzda ETag (Entity Tag) kullanarak, verinin değişip değişmediğini sunucuya sormadan anlayabilirsiniz. Sunucu, verinin bir hash değerini oluşturur ve istemciye gönderir.

// Sunucu tarafında (Node.js/Express örneği)
app.get('/api/kullanicilar', (req, res) => {
    const etag = veritabanindanHashHesapla();
    res.set('ETag', etag);
    if (req.headers['if-none-match'] === etag) {
        return res.status(304).end(); // Veri değişmemiş, 304 Not Modified
    }
    res.json(veriler);
});

Bu yöntem, bant genişliğini korur ve sunucu işlem yükünü ciddi oranda düşürür. İstemci 304 yanıtını aldığında, eski veriyi kullanmaya devam eder.

Adım 4: IndexedDB ile Büyük Veri Setlerini Yönetme

LocalStorage 5MB ile sınırlıdır. Büyük SQL sonuç setlerini yönetmek için IndexedDB kullanmak, istemci tarafında bir "mini veritabanı" oluşturmanızı sağlar. Bu, offline-first uygulamalar için zorunludur.

// IndexedDB başlatma
const request = indexedDB.open('VeriTabani', 1);
request.onupgradeneeded = (e) => {
    const db = e.target.result;
    db.createObjectStore('kullanicilar', { keyPath: 'id' });
};

// Veriyi kaydetme
function kaydet(data) {
    const transaction = db.transaction(['kullanicilar'], 'readwrite');
    const store = transaction.objectStore('kullanicilar');
    data.forEach(item => store.put(item));
}

IndexedDB, asenkron yapısı sayesinde tarayıcıyı dondurmadan büyük miktarda veriyi işleyebilir.

Önbellekleme Yöntemlerinin Karşılaştırılması

Yöntem Kapasite Hız Kullanım Alanı
LocalStorage ~5MB Yüksek Küçük ayarlar, kullanıcı tercihleri
IndexedDB Sınırsız (disk alanı) Orta Büyük veri listeleri, offline veriler
HTTP ETag N/A Çok Yüksek API yanıtlarının doğrulanması

Adım 5: Güvenlik ve Veri Bütünlüğü

İstemci tarafında veri saklarken, verinin manipüle edilmediğinden emin olmalısınız. Özellikle hassas verileri (şifre, kişisel bilgiler) asla localStorage üzerinde saklamayın. SQL Injection riskine karşı sunucu tarafında her zaman parametreli sorgular kullanın.

Kritik Uyarı: İstemci tarafında saklanan veriler kullanıcı tarafından görüntülenebilir ve değiştirilebilir. Hassas verileri asla tarayıcı önbelleğinde tutmayın; bu veriler için her zaman sunucu tarafında doğrulama yapın.
// Güvenli veri çekme örneği (Parametreli sorgu mantığı)
const query = "SELECT * FROM urunler WHERE kategori = ?";
// Sunucu tarafında bu sorguyu çalıştırırken mutlaka kütüphanenizin 
// sağladığı 'prepared statement' (hazırlanmış ifade) yapısını kullanın.

Sıkça Sorulan Sorular

İstemci önbelleği veritabanı üzerindeki yükü ne kadar azaltır?

Doğru yapılandırılmış bir önbellekleme stratejisi, tekrarlayan sorguları %80'e kadar azaltabilir. Bu, veritabanı CPU ve I/O kaynaklarınızın daha verimli kullanılmasını sağlar.

LocalStorage ile IndexedDB arasındaki temel fark nedir?

LocalStorage senkron çalışır ve küçüktür; IndexedDB asenkron çalışır ve büyük, karmaşık veri yapılarını destekler.

Veri güncelliğini nasıl garanti ederim?

Zaman damgaları (timestamps) veya ETag başlıklarını kullanarak sunucu ile istemci arasındaki veri sürümünü senkronize edebilirsiniz.

Önbellek temizleme stratejisi nasıl olmalı?

Uygulamanızda "Cache-Control" başlıklarını kullanarak veya belirli bir süre (TTL - Time To Live) sonunda veriyi geçersiz kılarak temizleme yapabilirsiniz.

Mobil cihazlarda önbellek kullanımı sorun yaratır mı?

Mobil cihazlarda depolama alanı kısıtlı olabilir, bu yüzden önbellek boyutunu optimize etmeli ve gereksiz verileri düzenli olarak silmelisiniz.

Yasal Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce, veritabanı güvenliği, veri gizliliği (KVKK/GDPR) ve hata yönetimi konularında profesyonel güvenlik testlerinden geçirilmeleri zorunludur.

İleri Düzey Önbellek Stratejileri: "Stale-While-Revalidate" Yaklaşımı

Uygulamanızda kullanıcı deneyimini en üst düzeye çıkarmak için "Stale-While-Revalidate" (Eski veriyi göster, arka planda güncelle) stratejisini kullanmak, özellikle yavaş ağ bağlantılarında büyük bir fark yaratır. Bu yöntem, kullanıcıya önbellekteki veriyi anında sunarken, aynı anda arka planda veritabanından güncel veriyi çekerek önbelleği tazeler.

Bu yaklaşımı uygulamak için Service Worker yapısını ve IndexedDB'yi birleştiren bir iş akışı kurgulamalısınız. Aşağıdaki örnek, bir veri isteği geldiğinde önbelleğin nasıl kontrol edileceğini ve güncelleneceğini özetler:

async function getCachedDataWithRevalidation(url) {
  const cache = await caches.open('api-cache-v1');
  const cachedResponse = await cache.match(url);
  
  // Arka planda güncelleme işlemini başlat
  const fetchPromise = fetch(url).then(async (networkResponse) => {
    cache.put(url, networkResponse.clone());
    return networkResponse;
  });

  // Önbellekte veri varsa onu dön, yoksa ağdan gelen veriyi bekle
  return cachedResponse || fetchPromise;
}

Önbellek Performansını İzleme ve Hata Ayıklama

İstemci tarafında önbellekleme yaparken, verinin ne kadarının önbellekten geldiğini (Cache Hit) veya ağa gitmek zorunda kaldığını (Cache Miss) ölçmek, uygulamanızın verimliliğini analiz etmenizi sağlar. Tarayıcıların geliştirici araçları (DevTools) bu süreçte en büyük yardımcınızdır.

Performans Ölçüm Metrikleri

  • Cache Hit Ratio: Başarılı önbellek isteklerinin toplam isteklere oranı.
  • Latency Improvement: Önbellekten gelen verinin ağdan gelen veriye göre sağladığı milisaniye cinsinden hız kazancı.
  • Storage Quota Usage: IndexedDB veya LocalStorage üzerinde kullanılan toplam alanın, tarayıcı limitlerine olan yakınlığı.

Hata ayıklama sürecinde, özellikle IndexedDB kullanıyorsanız, veritabanı şeması değişikliklerinde (migration) oluşabilecek hatalara karşı hazırlıklı olmalısınız. Aşağıdaki kod bloğu, veritabanı versiyon güncellemelerinde eski verilerin temizlenmesi veya dönüştürülmesi için kullanılır:

const request = indexedDB.open("AppDatabase", 2);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  if (event.oldVersion < 2) {
    // Eski verileri taşı veya yeni store oluştur
    if (!db.objectStoreNames.contains('user_data')) {
      db.createObjectStore('user_data', { keyPath: 'id' });
    }
  }
};

Bu tür bir yapılandırma, uygulamanızın kararlılığını artırırken, veritabanı üzerindeki gereksiz sorgu yükünü minimize eder. Özellikle yüksek trafikli SQL tabanlı sistemlerde, istemci tarafında doğru yönetilen bir önbellek katmanı, sunucu maliyetlerinizi %40'a varan oranlarda düşürebilir.

Sonuç

Sql & veritabanı ile uygulamalar için veri istemci önbelleği uygulamak, uygulamanızın hızını ve ölçeklenebilirliğini doğrudan artırır. Bu rehberde öğrendiğiniz ETag kullanımı, IndexedDB yönetimi ve zaman damgası kontrolleri, modern yazılım mimarisinin temel taşlarıdır. Bir sonraki adım olarak, uygulamanızda "Service Worker" kullanarak ağ isteklerini daha gelişmiş bir şekilde yönetmeyi ve offline çalışma yeteneklerini geliştirmeyi deneyebilirsiniz.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Yaşam kalitesini artıran hızlı ve etkili yöntemler üzerine içerik geliştiriyorum. Detaylara önem veren, çözüm odaklı rehberlerin öncüsüyüm.

Yorumlar (0)

Yorum Yaz