Veri Mimarisi

Veri Hiyerarşisi & Performans Analizi

Cihaz verileri nasıl organize edilmeli + yeni alanların etkisi

29 Aralık 2025 - v2

1 Veri Hiyerarşisi

Basit Anlatım

Cihaz bilgileri bir ağaç gibi düşünülebilir. En tepede "Mobil mi, Masaüstü mü?" var. Sonra "Hangi işletim sistemi?", en altta "Hangi tarayıcı?" soruları geliyor.

Hiyerarşi Ağacı

📱 device_type (Cihaz Tipi)
├── desktop
│ └── 💻 platform (İşletim Sistemi)
│ ├── macOS
│ │ └── 🌐 browser
│ │ ├── Chrome
│ │ ├── Safari
│ │ └── Firefox
│ ├── Windows
│ │ └── 🌐 browser
│ │ ├── Chrome
│ │ ├── Edge
│ │ └── Firefox
│ └── Linux
├── mobile
│ └── 💻 platform
│ ├── iOS
│ │ └── 🌐 browser
│ │ ├── Safari (WebKit)
│ │ └── Chrome (WebKit)
│ └── Android
│ └── 🌐 browser
│ ├── Chrome
│ └── Samsung Internet
└── tablet
└── (aynı yapı)

ip_address (Ayrı Boyut)

IP adresi hiyerarşide değil, ayrı bir boyut. Aynı cihaz farklı ağlardan bağlanabilir (ev, iş, mobil data).

92.44.171.31 → Türkiye / İstanbul / Vodafone

user_agent (Ham Veri)

Diğer tüm bilgiler user_agent'tan çıkarılır. Ham string olarak saklanır, gerekirse yeniden parse edilebilir.

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...

Timeline İçin Önerilen Gruplama

Abuse detection timeline'da Y ekseni şöyle olmalı:

Şu anki (Sadece Browser)
Chrome
Safari
Önerilen (Device + Browser)
Desktop Chrome
Desktop Safari
Mobile Safari
Mobile Chrome
Neden? Aynı kullanıcı hem telefondan hem bilgisayardan dinleyebilir. Bu normal. Ama aynı anda 2 farklı masaüstü tarayıcıdan dinlemek şüpheli.

2 Yeni Alanların Performans Etkisi

Basit Anlatım

Şu an sadece şarkı başladığında veri kaydediyoruz. Yeni alanlar için şarkı bittiğinde de sunucuya haber vermemiz gerekir. Bu, her şarkı için 1 yerine 2 istek demek.

Alan Ne Zaman Toplanır? API İsteği DB Etkisi Performans
source_type Başlangıçta Mevcut istekte +1 varchar field ✅ Sıfır etki
source_id Başlangıçta Mevcut istekte +1 bigint field ✅ Sıfır etki
ended_at Bitişte +1 yeni istek UPDATE query ⚠️ Orta etki
listened_duration Bitişte ended_at ile birlikte +1 int field ✅ Ek etki yok
was_skipped Bitişte ended_at ile birlikte +1 boolean field ✅ Ek etki yok

Şu Anki Durum

Her şarkı için API isteği: 1
1000 şarkı/gün için: 1,000 istek
DB query/şarkı: 1 INSERT

ended_at Eklendikten Sonra

Her şarkı için API isteği: 2 (start + end)
1000 şarkı/gün için: 2,000 istek
DB query/şarkı: 1 INSERT + 1 UPDATE

Sayısal Etki Hesabı

226
Haftalık dinleme (1 kullanıcı)
+226
Ek "end" isteği
~0.5KB
İstek başına veri

Sonuç: 100 aktif kullanıcı ile haftalık ~22,600 ek istek. Modern sunucu için ihmal edilebilir. Redis/Nginx zaten bu trafiği rahat kaldırır.

Potansiyel Riskler ve Çözümler

İnternet kesilirse "end" isteği gitmez

Çözüm: localStorage'a kaydet, sonra gönder (queue)

Sekme kapatılırsa "end" isteği gitmez

Çözüm: beforeunload + sendBeacon API (fire-and-forget)

UPDATE query yükü

Çözüm: play_id indexed olmalı, UPDATE hızlı olur

Öneri

1.

Önce source_type/source_id ekle - Sıfır performans etkisi, hemen eklenebilir

2.

ended_at için JS altyapısı hazırla - sendBeacon, localStorage queue

3.

Test ortamında dene - Gerçek yük ile performans ölç

4.

Production'a al - Eğer sorun yoksa