Files
api-btekno/UPSERT_BEHAVIOR.md

4.4 KiB
Raw Permalink Blame History

Penjelasan Behavior Upsert di Hourly Summary

Jawaban Singkat

Data DIGANTI (REPLACE), bukan ditambah.

Detail Penjelasan

Query Upsert yang Digunakan

INSERT INTO hourly_summary 
    (summary_date, summary_hour, location_code, gate_code, category, total_count, total_amount)
VALUES (?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
    total_count = VALUES(total_count),
    total_amount = VALUES(total_amount)

Primary Key

PRIMARY KEY (summary_date, summary_hour, location_code, gate_code, category)

Behavior: ON DUPLICATE KEY UPDATE

Jika row BELUM ADA:

  • INSERT → Tambah row baru

Jika row SUDAH ADA:

  • UPDATE → Ganti total_count dan total_amount dengan nilai baru
  • BUKAN tambah ke nilai lama

Contoh Skenario

Skenario 1: Cron Pertama Kali (Row Belum Ada)

Jam 2:00, cron jalan untuk update jam 1:00:

1. Query entry_events untuk jam 1:00:
   - location_code: kerkof_01
   - gate_code: gate01
   - category: motor
   - COUNT: 10 events
   - total_amount: 10 × 2000 = 20000

2. INSERT ke hourly_summary:
   ✅ Row baru dibuat:
   summary_date: 2025-12-17
   summary_hour: 1
   location_code: kerkof_01
   gate_code: gate01
   category: motor
   total_count: 10
   total_amount: 20000

Skenario 2: Cron Kedua Kali (Row Sudah Ada)

Jam 2:30, ada event baru masuk (terlambat):

  • Event jam 1:00 masuk di jam 2:30 (terlambat)

Jam 3:00, cron jalan lagi untuk update jam 1:00:

1. Query entry_events untuk jam 1:00 (SEKARANG):
   - location_code: kerkof_01
   - gate_code: gate01
   - category: motor
   - COUNT: 11 events (termasuk yang terlambat)
   - total_amount: 11 × 2000 = 22000

2. ON DUPLICATE KEY UPDATE:
   ✅ Row LAMA diganti:
   - total_count: 10 → 11 (DIGANTI, bukan 10 + 11 = 21)
   - total_amount: 20000 → 22000 (DIGANTI, bukan 20000 + 22000 = 42000)

Mengapa Diganti, Bukan Ditambah?

1. Akurasi Data

  • Summary harus selalu mencerminkan data aktual di entry_events
  • Jika ditambah, data akan double-count jika cron jalan berulang

2. Idempotent

  • Cron bisa jalan berulang tanpa merusak data
  • Hasil selalu sama, tidak peduli berapa kali dijalankan

3. Event Terlambat

  • Jika ada event yang masuk terlambat, akan otomatis terhitung saat rekap ulang
  • Tidak perlu manual correction

Contoh Timeline Lengkap

Hari: 2025-12-17

Jam 1:00 - 1:59:

Event masuk ke entry_events:
- 1:05 → motor (kerkof_01, gate01)
- 1:15 → motor (kerkof_01, gate01)
- 1:30 → motor (kerkof_01, gate01)
Total: 3 events

Jam 2:00 - Cron jalan:

1. Query entry_events untuk jam 1:00:
   → COUNT: 3 events
   → total_amount: 3 × 2000 = 6000

2. INSERT ke hourly_summary:
   ✅ Row baru: total_count = 3, total_amount = 6000

Jam 2:30 - Event terlambat masuk:

Event masuk ke entry_events (terlambat):
- 2:30 → motor (kerkof_01, gate01) dengan event_time = 1:45
Total sekarang: 4 events untuk jam 1:00

Jam 3:00 - Cron jalan lagi (opsional, jika rekap ulang):

1. Query entry_events untuk jam 1:00 (SEKARANG):
   → COUNT: 4 events (termasuk yang terlambat)
   → total_amount: 4 × 2000 = 8000

2. ON DUPLICATE KEY UPDATE:
   ✅ Row LAMA diganti:
   - total_count: 3 → 4 (DIGANTI)
   - total_amount: 6000 → 8000 (DIGANTI)

Verifikasi di Database

Cek Data Sebelum Cron:

SELECT * FROM hourly_summary 
WHERE summary_date = '2025-12-17' 
AND summary_hour = 1
AND location_code = 'kerkof_01'
AND gate_code = 'gate01'
AND category = 'motor';

-- Hasil:
-- total_count: 3
-- total_amount: 6000

Jalankan Cron:

php bin/hourly_summary.php today 1

Cek Data Setelah Cron:

SELECT * FROM hourly_summary 
WHERE summary_date = '2025-12-17' 
AND summary_hour = 1
AND location_code = 'kerkof_01'
AND gate_code = 'gate01'
AND category = 'motor';

-- Hasil (jika ada event baru):
-- total_count: 4 (DIGANTI dari 3, bukan 3 + 4 = 7)
-- total_amount: 8000 (DIGANTI dari 6000, bukan 6000 + 8000 = 14000)

Kesimpulan

Aspek Behavior
Jika row belum ada INSERT (tambah baru)
Jika row sudah ada UPDATE (ganti nilai)
Apakah ditambah? TIDAK, diganti
Apakah diganti? YA, diganti dengan nilai baru
Nilai lama Tidak dipertahankan, diganti dengan hasil rekap ulang

Intinya: Data selalu di-rekap ulang dari entry_events, bukan ditambah ke nilai lama. Ini memastikan akurasi dan konsistensi data summary.