Gereksinimler ve Ön Hazırlık
Veri sürümü kontrolü uygulamak için modern bir RDBMS (İlişkisel Veritabanı Yönetim Sistemi) kullanmanız gerekmektedir. Örneklerimizde PostgreSQL 17+ ve standart SQL sözdizimi kullanılacaktır. Çalışma ortamınızda aşağıdaki yapıların kurulu olduğundan emin olun:
- PostgreSQL veya MySQL 8.4+ veritabanı sunucusu.
- Veritabanı işlemlerini yönetmek için bir GUI aracı (DBeaver veya pgAdmin).
- Uygulama katmanında veritabanı bağlantısı için güvenli bir ORM veya PDO/SQL sürücüsü.
Yöntem 1: Audit Log Tablosu ile Manuel Sürümleme
En yaygın yöntem, her ana tablonun bir yedeğini tutan "log" tabloları oluşturmaktır. Bu yöntem, verinin her değişimini bir "snapshot" (anlık görüntü) olarak saklar. Aşağıdaki örnekte, bir ürün tablosunun geçmişini nasıl tutacağımızı görelim.
-- Ana tablo
CREATE TABLE urunler (
id SERIAL PRIMARY KEY,
isim VARCHAR(255),
fiyat DECIMAL(10,2),
guncellenme_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Geçmiş tablosu
CREATE TABLE urunler_gecmis (
gecmis_id SERIAL PRIMARY KEY,
urun_id INT,
isim VARCHAR(255),
fiyat DECIMAL(10,2),
degisim_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
islem_tipi VARCHAR(10) -- INSERT, UPDATE, DELETE
);
Bu yapıda, ana tabloda bir güncelleme yapıldığında, tetikleyici (trigger) kullanarak veriyi geçmiş tablosuna kopyalarız. Bu, verinin tam bir izini sürmenize olanak tanır.
Yöntem 2: SQL Tetikleyicileri (Triggers) ile Otomasyon
Manuel süreçler hata payı içerir. Veritabanı düzeyinde tetikleyiciler kullanarak, uygulama kodunuzdan bağımsız bir sürümleme sistemi kurabilirsiniz. Bu, veritabanı güvenliğini artırır.
CREATE OR REPLACE FUNCTION urun_gecmis_kaydet()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO urunler_gecmis (urun_id, isim, fiyat, islem_tipi)
VALUES (OLD.id, OLD.isim, OLD.fiyat, TG_OP);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER urun_guncelleme_trg
AFTER UPDATE ON urunler
FOR EACH ROW EXECUTE FUNCTION urun_gecmis_kaydet();
Bu kod bloğu, urunler tablosunda her güncelleme yapıldığında, eski veriyi otomatik olarak urunler_gecmis tablosuna aktarır. TG_OP değişkeni, işlemin türünü otomatik olarak belirler.
Yöntem 3: Temporal Tables (Zamansal Tablolar) Kullanımı
PostgreSQL 17 ve sonrası gibi gelişmiş veritabanları, "System-Period Temporal Tables" özelliğini destekler. Bu özellik, verinin geçerlilik süresini (başlangıç ve bitiş zamanı) otomatik yönetir. Bu, sürümleme için en modern ve temiz yoldur.
CREATE TABLE kullanicilar (
id SERIAL PRIMARY KEY,
ad VARCHAR(100),
sys_period TSTZRANGE NOT NULL DEFAULT tstzrange(current_timestamp, null)
);
-- Geçmiş veriyi sorgulamak için:
SELECT * FROM kullanicilar FOR SYSTEM_TIME AS OF '2025-01-01 00:00:00';
Bu yöntem, veritabanının kendi içinde zaman damgalarını yönetmesini sağlar. Geliştirici olarak siz sadece sorgu zamanını belirtirsiniz; veritabanı o tarihteki veriyi size getirir.
Sürümleme Yöntemlerinin Karşılaştırması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Audit Log | Basit ve taşınabilir | Tablo boyutu çok hızlı artar |
| Tetikleyiciler | Otomatik ve güvenli | Karmaşık hata ayıklama |
| Temporal Tables | Standart ve performanslı | Veritabanı motoru desteği şart |
Kritik Güvenlik Uyarısı: Veritabanı tetikleyicileri ve log tabloları, veritabanı kullanıcısının yetkileriyle sınırlıdır. Uygulamanızda SQL Injection açıklarına karşı mutlaka "Prepared Statements" (Hazırlanmış İfadeler) kullanın. Doğrudan kullanıcı girdisini sorguya eklemeyin.
Veri Sürümü Kontrolünde Sıkça Yapılan Hatalar
Veri sürümü kontrolü yaparken en büyük hata, tüm sütunları loglamaya çalışmaktır. Bu, veritabanı performansını ciddi oranda düşürür. Sadece kritik sütunları (fiyat, durum, yetki vb.) loglamak, disk kullanımını optimize eder.
Diğer bir yaygın hata ise, log tablolarına indeks eklememektir. Geçmiş veriyi sorgularken urun_id ve degisim_tarihi sütunlarına mutlaka indeks ekleyin. Aksi takdirde, veritabanı büyüdükçe raporlama sorgularınız dakikalar sürebilir.
Sıkça Sorulan Sorular
Log tabloları veritabanını çok yavaşlatır mı?
Doğru indeksleme ve bölümleme (partitioning) teknikleri kullanıldığında, log tabloları ana işlemlerin performansını etkilemez. Log tablosunu ayrı bir disk bölümünde tutmak da etkili bir stratejidir.
Silinen verileri nasıl geri getirebilirim?
Eğer "Soft Delete" (Yumuşak Silme) mantığı kullanıyorsanız, bir silindi_mi sütunu ekleyerek veriyi fiziksel olarak silmezsiniz. Sürümleme tabloları, silinen verinin son halini tuttuğu için bu verileri kolayca geri yükleyebilirsiniz.
Hangi yöntemi seçmeliyim?
Küçük ölçekli uygulamalar için Audit Log yeterlidir. Ancak yüksek trafikli ve finansal veriler içeren sistemlerde mutlaka veritabanı seviyesinde Temporal Tables veya tetikleyici destekli loglama kullanılmalıdır.
Log tablolarını nasıl temizlemeliyim?
Veri saklama politikalarına (GDPR/KVKK) uygun olarak, belirli bir süreden (örneğin 1 yıl) eski logları arşivleyip ana veritabanından silen bir "cron job" veya veritabanı zamanlanmış görevi oluşturmalısınız.
Sürümleme verisi şifrelenmeli mi?
Eğer loglanan veriler kişisel veri (PII) içeriyorsa, veritabanı düzeyinde şifreleme (TDE - Transparent Data Encryption) kullanmanız önerilir.
İleri Düzey Strateji: Sürümleme Verileri İçin Arşivleme ve Partitioning
Veri sürümü kontrolü uygulandığında, log tablolarınızın boyutu ana tablonuzdan çok daha hızlı büyüyecektir. Bu durum, özellikle yüksek trafikli sistemlerde disk doluluğu ve sorgu performans düşüşlerine neden olur. Bu sorunu aşmak için Table Partitioning (Tablo Bölümleme) stratejisini uygulamak en profesyonel yaklaşımdır.
Partitioning, veriyi fiziksel olarak farklı dosya gruplarına böler. Örneğin, log verilerini aylık veya yıllık bazda bölümlere ayırarak, eski verilerin sorgu performansını etkilemesini engelleyebilirsiniz.
-- SQL Server üzerinde tarih bazlı partition örneği
CREATE PARTITION FUNCTION LogTarihFonksiyonu (DATETIME)
AS RANGE RIGHT FOR VALUES ('2023-01-01', '2024-01-01', '2025-01-01');
CREATE PARTITION SCHEME LogTarihSemasi
AS PARTITION LogTarihFonksiyonu
TO (DosyaGrubu2023, DosyaGrubu2024, DosyaGrubu2025, DosyaGrubuGelecek);
Sürümleme Sistemlerinde Hata Ayıklama (Debugging)
Sürümleme mekanizmanızın düzgün çalıştığından emin olmak için "Data Integrity Check" (Veri Bütünlüğü Kontrolü) süreçleri kurgulamanız gerekir. Bazen tetikleyiciler (triggers) beklenmedik bir hata nedeniyle çalışmayabilir veya bir uygulama hatası nedeniyle sürüm kaydı oluşmayabilir. Bu durumu tespit etmek için periyodik kontrol prosedürleri yazmalısınız.
Tutarsızlık Tespiti İçin Kontrol Sorgusu
Ana tablodaki son güncelleme tarihi ile log tablosundaki en son kaydı karşılaştırarak, tetikleyicinin atladığı kayıtları tespit edebilirsiniz:
-- Ana tablo ile log tablosu arasındaki tutarsızlıkları bulan sorgu
SELECT
a.ID,
a.GuncellenmeTarihi AS AnaTabloTarihi,
MAX(l.IslemTarihi) AS LogTabloTarihi
FROM Kullanicilar a
LEFT JOIN KullaniciLog l ON a.ID = l.KullaniciID
GROUP BY a.ID, a.GuncellenmeTarihi
HAVING a.GuncellenmeTarihi > MAX(l.IslemTarihi) OR MAX(l.IslemTarihi) IS NULL;
Hata Ayıklama İpuçları:
- Try-Catch Blokları: Tetikleyicilerinizin içerisine hata yakalama mekanizmaları ekleyin. Hata oluştuğunda bu hatayı bir "ErrorLog" tablosuna yazdırın.
- İşlem (Transaction) Yönetimi: Sürümleme işleminin ana işlemle (transaction) birlikte geri alınabilir (rollback) olduğundan emin olun. Eğer log yazılamıyorsa, ana verinin de güncellenmemesi veri bütünlüğü için kritiktir.
- Kullanıcı Bağlamı: Hangi kullanıcının değişikliği yaptığını takip etmek için
SESSION_CONTEXTveyaCONTEXT_INFOkullanarak uygulama katmanından veritabanına kullanıcı ID'sini aktarın.
Bu yöntemler, sisteminizin sadece veri saklamasını değil, aynı zamanda bu verilerin doğruluğunu da garanti altına almasını sağlar. Özellikle finansal veya kritik iş süreçlerinde, bu tür bir "fail-safe" (hata korumalı) yapı kurmak, olası veri kayıplarının önüne geçecektir.
Sonuç
SQL & Veritabanı ile uygulama sürümleme kontrolü, sisteminizin güvenilirliğini artıran en önemli mühendislik pratiklerinden biridir. Bu rehberde öğrendiğiniz tetikleyici mantığı ve zamansal tablolar, profesyonel projelerde veri bütünlüğünü korumanızı sağlayacaktır. Bir sonraki adım olarak, veritabanı bölümleme (Partitioning) konusunu araştırarak log tablolarınızın performansını nasıl ölçeklendireceğinizi öğrenebilirsiniz.
Yasal Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce mutlaka bir veritabanı uzmanı ile test edilmeli ve güvenlik taramalarından geçirilmelidir. Veri kaybı riskine karşı düzenli yedekleme yapılması zorunludur.


Yorumlar (0)
Yorum Yaz