Bir Hata ile Başladı
Bir Hata ile Başladı
VMMS – bir voucher yönetim sistemi inşa ederken, her şey yerel ortamda mükemmel çalışıyordu.
MySQL. Temiz sorgular. Hızlı sonuçlar.
Sonra, MariaDB çalışan bir sunucuya dağıttım.
Grafiklerin yarısı bozuldu.
Problem
Problem
Veri tabanı boyunca şöyle tarih sorguları yazmıştım:
// Bu MariaDB'de bozuluyor
DB::table('voucher_transactions')
->selectRaw()
->groupByRaw()
->get();
MONTH() ve MONTHNAME() MySQL fonksiyonlarıdır. MySQL’de iyi çalışırken, MariaDB’de farklı davranış sergileyebilirler — özellikle GROUP BY ile birlikte kullanıldıklarında.
Sonuç olarak? Ayların yanlış sırada görüntülenmesi. Tekrar eden girdiler. Kaybolan veriler.
Neden Bu Oluyor?
Neden Bu Oluyor?
MySQL ve MariaDB yıllar içinde farklılaştı. Birçok sözdizimini paylaşsalar da, bazı fonksiyonları farklı şekilde işlerler — özellikle tarih gruplama ve sıralama konusunda.
Güvenli kural: Uygulamanızın hem MySQL hem de MariaDB’nde çalışmasını istiyorsanız, veritabanına özgü tarih fonksiyonlarına güvenmeyin.
Çözüm — Veriyi Al ve Carbon Kullan
Çözüm — Veriyi Al ve Carbon Kullan
Tarih hesaplamalarını SQL’de yapmak yerine, ham verileri çekip her şeyi PHP’de Carbon kullanarak işlemeyi tercih ettim:
// DB-bağımsız yaklaşım
$rows = VoucherTransaction::where(, $userId)
->whereYear(, $year)
->whereNull()
->get([, ]);
$byMonth = [];
foreach ($rows as $row) {
$m = (int) $row->created_at->format();
$status = strtolower($row->status);
$byMonth[$m] = $byMonth[$m] ?? [=> 0, => 0];
if ($status === ) $byMonth[$m][]++;
if ($status === ) $byMonth[$m][]++;
}
ksort($byMonth);
Sonra ay adını almak için MONTHNAME() yerine Carbon kullandım:
$monthName = Carbon::create($year, $m, 1)->format();
// "Ocak", "Şubat", vb. döner.
// MySQL ve MariaDB'de aynı şekilde çalışır
Yılda Tüm Ay Grafiklerini Oluşturma
Yılda Tüm Ay Grafiklerini Oluşturma
Tüm 12 ayı — boş olanlar dahil — gösterecek grafikler için, range(1, 12) kullanıyorum ve veri olmayan aylar için sıfır dolduruyorum:
return collect(range(1, 12))->map(function ($m) use ($byMonth, $year) {
$d = $byMonth[$m] ?? [=> 0, => 0];
return [
=> Carbon::create($year, $m, 1)->format(),
=> $d[],
=> $d[],
];
});
Bu, grafiklerde her ayın her zaman görünmesini garanti eder — veri olmasa bile. Temiz ve öngörülebilir.
Performans Hakkında Ne Olacak?
Performans Hakkında Ne Olacak?
Sizce — tüm satırları çekmek ve PHP’de işlemek, SQL’de yapmaktan daha yavaş mı?
Çoğu uygulama için — evet, SQL agregasyonu daha hızlıdır.
Ancak pratikte bu kullanım durumu için:
- Veriler önce kullanıcı ve yıla göre filtrelenir
- Sonuç seti küçük (yılda kullanıcının 365 satırdan fazlası yok)
- PHP işleme göz ardı edilebilir
Bir milyonlarca satırla çalışıyorsanız, bu yaklaşımın yeniden ele alınması gerekir. Ama tipik iş uygulamaları için yeterince hızlı ve taşınabilirlik bu sürece değer.
VMMS’de Kullandığım Diğer Carbon İpuçları
VMMS’de Kullandığım Diğer Carbon İpuçları
Tarihler arasında zaman olmadan karşılaştırma:
// Zaman karşılaştırma sorunlarını önlemek için SQL'de DATE() kullanın
->whereRaw(, [$now->toDateString()])
->whereRaw(, [$now->copy()->addDays(7)->toDateString()])
Gün sayısını hesaplama:
$deadline = Carbon::parse($t->deadline)->startOfDay();
$daysLeft = (int) $now->copy()->startOfDay()->diffInDays($deadline, false);
Burada false parametresi, diffInDays‘in geçmiş tarihler için negatif sayılar döndürmesini sağlar — bu da, geciken tespit açısından yararlıdır.
İşleme süresini hesaplama:
$minutes = Carbon::parse($row->process_initiate)
->diffInMinutes(Carbon::parse($row->process_accomplished));
Ders
Ders
Yerel MySQL davranışının üretim ile eşleşeceğini varsaymayın. Uygulamanız MariaDB, PostgreSQL veya başka bir veritabanında çalışabilir — tarih mantığınızı PHP’de Carbon ile tutun ve yalnızca standart SQL kullandığınızdan emin olun.
Bu, birçok hata ayıklama zamanından tasarruf eden küçük bir alışkanlıktır.
VMMS Hakkında
VMMS Hakkında
Bu ve diğer birçok ders, hükümet ofisleri, şirketler ve eğitim kurumları için tam bir voucher yönetim sistemi olan VMMS’i inşa etmekten geldi.
🔴 Canlı demo: https://vmms-app-production.up.railway.app/login
Gumroad’da mevcut:
👉 https://getvmms.gumroad.com/l/zeroqz
Sorularınızı yanıtlamaktan memnuniyet duyarım!
Kaynak: Orijinal Makale


