Denormalizatsiya — qachon va nima uchun
Hisobot sahifasi sekin yuklanyapti. EXPLAIN ANALYZE ko'rsatdi — 8 ta jadval JOIN qilinmoqda, 500 ms ketmoqda. Normalizatsiya to'g'ri — lekin bu holda juda ko'p JOIN. Denormalizatsiya — tezlik uchun ataylab takrorlanish kiritish.
Denormalizatsiya nima?
Normalizatsiya qoidalarini ataylab buzish — ma'lumotni bir necha joyda saqlash. Natijada JOIN kamayadi, so'rovlar tezlashadi. Lekin yangilash murakkablashadi.
Qachon denormalizatsiya?
✅ Denormalizatsiya qilish:
- O'qish yozishdan ko'p (read-heavy)
- Hisobot, dashboard, API
- Ko'p JOIN sekinlashtirgan
- Cache o'rnini bosib
❌ Denormalizatsiya qilmaslik:
- Ko'p yangilanuvchi ma'lumot
- Yozish muhim (write-heavy)
- Normalizatsiya yetarli tezlikda
Usul 1 — hisoblangan ustun
-- ❌ Normalizatsiya: har so'rovda hisoblash
SELECT f.ism, COUNT(b.id) AS buyurtmalar_soni
FROM foydalanuvchilar f
LEFT JOIN buyurtmalar b ON f.id = b.foydalanuvchi_id
GROUP BY f.id;
-- ✅ Denormalizatsiya: soni to'g'ridan foydalanuvchida
ALTER TABLE foydalanuvchilar ADD COLUMN buyurtmalar_soni INT DEFAULT 0;
-- Buyurtma qo'shilganda
UPDATE foydalanuvchilar SET buyurtmalar_soni = buyurtmalar_soni + 1
WHERE id = :foydalanuvchi_id;
Endi hisobotda JOIN shart emas:
SELECT ism, buyurtmalar_soni FROM foydalanuvchilar ORDER BY buyurtmalar_soni DESC;
Usul 2 — takrorlangan ma'lumot
-- Buyurtmada kategoriya nomini ham saqlash — JOIN kamaytirish
CREATE TABLE buyurtmalar (
id SERIAL PRIMARY KEY,
mahsulot_id INT REFERENCES mahsulotlar(id),
mahsulot_nomi TEXT, -- ← denormalizatsiya: mahsulotlar jadvalida ham bor
kategoriya_nomi TEXT, -- ← denormalizatsiya
narxi NUMERIC -- ← denormalizatsiya: o'sha vaqtdagi narx
);
Bu holda mahsulot nomi o'zgarse, eski buyurtmalar eski nomni saqlab qoladi — bu aslida to'g'ri (tarixiy ma'lumot).
Usul 3 — Materialized View
Normalizatsiya saqlab, hisobot uchun denormalizatsiya:
CREATE MATERIALIZED VIEW oylik_hisobot AS
SELECT
f.ism, f.email,
COUNT(b.id) AS buyurtmalar,
SUM(b.summa) AS jami
FROM foydalanuvchilar f
LEFT JOIN buyurtmalar b ON f.id = b.foydalanuvchi_id
GROUP BY f.id;
REFRESH MATERIALIZED VIEW oylik_hisobot; -- kecha yangilanadi
Tez-tez uchraydigan xatolar
Denormalizatsiyadan oldin o'lchash:
-- Avval EXPLAIN ANALYZE bilan sekin ekanligini isbotlang
EXPLAIN ANALYZE SELECT ...;
-- Keyin denormalizatsiya
Ko'pincha to'g'ri index yetarli — denormalizatsiya shart emas.
Sinxronizatsiyani unutish:
-- ❌ buyurtmalar_soni yangilanmagan
INSERT INTO buyurtmalar ...;
-- foydalanuvchilar.buyurtmalar_soni eski qoldi!
Denormalizatsiyada trigger yoki dastur kodi ma'lumotni sinxron ushlab turishi kerak.
Xulosa
Normalizatsiya → ma'lumot bir joyda, JOIN ko'p
Denormalizatsiya → ma'lumot takrorlanadi, JOIN kam, tezroq
Usullar:
Hisoblangan ustun — COUNT, SUM ni jadvalda saqlash
Takrorlangan ma'lumot — nom, narx kabi ma'lumotni nusxalash
Materialized View — hisobot uchun alohida kesh jadval
Qoida: avval o'lchang, keyin denormalizatsiya qiling
Keyingi dars
50-dars: ER Diagram — jadvallar va munosabatlarni loyihalash