Mundarija (22)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Normalizatsiya nima
- 2.2. Normal shakllar (1NF, 2NF, 3NF)
- 2.3. Kalitlar (birlamchi, tashqi)
- 2.4. Cheklovlar (NOT NULL, UNIQUE, FK)
- 2.5. Bog'lanish turlari (1-1, 1-ko'p, ko'p-ko'p)
- 2.6. Denormalizatsiya (qachan)
- 2.7. Dizayn jarayoni
- 2.8. Yaxshi dizayn belgilari
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — Normalizatsiya (takrorni yo'qotish)
- Misol 2 — Cheklovlar (himoya)
- Misol 3 — Ko'p-ko'p bog'lanish (oraliq jadval)
- Misol 4 — Amaliy: to'liq sxema loyihalash
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
23.12-dars: Baza dizayni tamoyillari
23-QISM — BAZALAR VA ORM · 12-dars (yakuniy)
1. Kirish va motivatsiya
23-qism davomida SQL (23.1–23.5), ORM (23.6–23.9), kesh 23.10-bob, NoSQL 23.11-bob'ni ko'rdik. Endi eng muhim savol: jadvallarni qanday loyihalash kerak? Yomon dizayn — ma'lumot takrori (bir narsa ko'p joyda), nomuvofiqlik (bir joyda yangilandi, boshqasida yo'q), kengaytirish qiyinligi. Yaxshi dizayn — har fakt bir joyda, bog'lanishlar aniq, o'sishga tayyor.
Baza dizayni — ma'lumotni jadvallar (yoki hujjatlar) va bog'lanishlarga to'g'ri taqsimlash. Asosiy tamoyillar: normalizatsiya (takrorni yo'qotish — har fakt bir marta), kalitlar (birlamchi — noyob shaxs, tashqi — bog'lanish), cheklovlar (NOT NULL, UNIQUE, FK — baza to'g'riligini himoya qiladi), bog'lanish turlari (bir-bir, bir-ko'p, ko'p-ko'p). Bu 23.1–23.2 (jadval, JOIN) ustida quriladi.
Real vaziyat. Bir loyiha buyurtmalarni bir jadvalda saqlardi — har qatorda mijoz nomi, manzili, telefoni takrorlanardi. Mijoz manzilini o'zgartirsa, yuzlab qatorni yangilash kerak edi (ba'zisi unutildi — nomuvofiqlik). Normalizatsiya qilindi: mijoz alohida jadval, buyurtma unga havola (FK). Mijoz bir joyda — bir marta yangilanadi. Ma'lumot toza va ishonchli bo'ldi.
Bu darsda — 23-qism yakuni — baza dizayni tamoyillarini o'rganamiz.
Bu darsda:
- Normalizatsiya nima
- Kalitlar (birlamchi, tashqi)
- Cheklovlar (NOT NULL, UNIQUE, FK)
- Bog'lanish turlari (1-1, 1-ko'p, ko'p-ko'p)
- Denormalizatsiya (qachan)
- Dizayn jarayoni
- 23-qism yakuni
- Amaliy: sxema loyihalash
ℹ Misollarda sqlite3 (o'rnatilgan) bilan sinaladi.
2. Nazariya — chuqur tushuntirish
2.1. Normalizatsiya nima
Normalizatsiya — ma'lumot takrorini yo'qotish:
Yomon (takror):
buyurtma(id, mahsulot, mijoz_nom, mijoz_manzil, mijoz_tel)
→ mijoz ma'lumoti har buyurtmada takror
Yaxshi (normallashtirilgan):
mijoz(id, nom, manzil, tel)
buyurtma(id, mahsulot, mijoz_id → mijoz)
→ mijoz bir marta, buyurtma havola qiladiNormalizatsiya — ma'lumotni shunday tashkil qilishki, har fakt bir marta saqlansin (takror yo'q). Takror yomon: joy isrofi, nomuvofiqlik (bir joyda yangilandi, boshqasida yo'q). Yechim: takrorlanadigan ma'lumotni alohida jadvalga chiqar, havola (FK) bilan bog'la. "Har fakt bir joyda, bir marta".
2.2. Normal shakllar (1NF, 2NF, 3NF)
Normalizatsiya bosqichlari:
| Shakl | Qoida |
|---|---|
| 1NF | Har katak — bitta qiymat (massiv emas) |
| 2NF | 1NF + har ustun to'liq kalitga bog'liq |
| 3NF | 2NF + ustun faqat kalitga (boshqa ustunga emas) |
Normal shakllar — normalizatsiya darajalari: 1NF (har katak bitta qiymat — takrorlanadigan guruh yo'q), 2NF (har ustun butun birlamchi kalitga bog'liq), 3NF (ustun faqat kalitga bog'liq, boshqa ustunga emas). Amaliyotda 3NF yetarli (ko'p loyiha). Maqsad: takror va anomaliya (yangilash muammosi) yo'q.
2.3. Kalitlar (birlamchi, tashqi)
Kalitlar — jadvallarni bog'laydi:
CREATE TABLE muallif (
id INTEGER PRIMARY KEY, -- birlamchi kalit (noyob)
nom TEXT NOT NULL
);
CREATE TABLE kurs (
id INTEGER PRIMARY KEY, -- birlamchi kalit
nom TEXT NOT NULL,
muallif_id INTEGER REFERENCES muallif(id) -- tashqi kalit
); Birlamchi kalit (primary key) — har satrni noyob aniqlaydi (odatda id, avtomatik). Tashqi kalit (foreign key) — boshqa jadval birlamchi kalitiga havola (bog'lanish). muallif_id — qaysi muallif (23.2 JOIN shu bilan). Kalit — dizayn asosi: birlamchi (shaxs), tashqi (bog'lanish).
2.4. Cheklovlar (NOT NULL, UNIQUE, FK)
Cheklovlar — baza to'g'riligini himoya qiladi:
email TEXT UNIQUE NOT NULL -- bo'sh emas, takrorlanmas
narx INTEGER CHECK (narx >= 0) -- shart
muallif_id REFERENCES muallif(id) -- mavjud muallifCheklovlar — baza darajasida qoidalar: NOT NULL (bo'sh bo'lmasin), UNIQUE (takrorlanmasin — email), CHECK (shart — narx ≥ 0), FK (havola mavjud bo'lsin — yo'q muallifga bog'lab bo'lmaydi). Bu ma'lumot to'g'riligini (integrity) kafolatlaydi — dastur xatosi ham bazani buzolmaydi. "Baza o'zi himoyalanadi".
2.5. Bog'lanish turlari (1-1, 1-ko'p, ko'p-ko'p)
Uch bog'lanish turi:
| Tur | Misol | Amalga oshirish |
|---|---|---|
| Bir-bir | foydalanuvchi ↔ profil | FK (bir tomonda) |
| Bir-ko'p | muallif → kurslar | FK (ko'p tomonda) |
| Ko'p-ko'p | kurs ↔ teglar | Oraliq jadval |
Bog'lanish turlari: bir-bir (foydalanuvchi-profil — FK bir tomonda), bir-ko'p (muallif-kurslar — FK "ko'p" tomonda, eng keng tarqalgan), ko'p-ko'p (kurs-teglar — bir kurs ko'p teg, bir teg ko'p kurs — oraliq jadval kurs_teg(kurs_id, teg_id) kerak). Ko'p-ko'p to'g'ridan-to'g'ri bo'lmaydi — oraliq jadval (junction).
2.6. Denormalizatsiya (qachan)
Ba'zan takror ataylab qo'shiladi:
Normalizatsiya: har fakt bir joyda (o'qish — JOIN kerak)
Denormalizatsiya: takror qo'sh (o'qish tez, JOIN'siz)
→ masalan: kurs jadvalida "muallif_nomi" (havola + nusxa)
→ tez o'qish, lekin yangilash qiyin (ikki joyda)Denormalizatsiya — unumdorlik uchun ataylab takror qo'shish (normalizatsiyaning teskarisi). Sabab: JOIN sekin 23.2-bob — takror bilan JOIN'siz o'qish tez. Narx: yangilash qiyin (takrorni sinxron ushlash). Qoida: avval normalizatsiya, keyin (o'lchab) kerak bo'lsa denormalizatsiya. NoSQL 23.11-bob ko'pincha denormallashtirilgan (ichma-ich).
2.7. Dizayn jarayoni
Sxema loyihalash qadamlari:
1. Entitylarni aniqla (foydalanuvchi, kurs, buyurtma)
2. Har entity — jadval (id + maydonlar)
3. Bog'lanishlarni top (1-ko'p, ko'p-ko'p)
4. Kalitlar (birlamchi, tashqi)
5. Cheklovlar (NOT NULL, UNIQUE, CHECK)
6. Normalizatsiya (takrorni yo'qot)
7. Indekslar (23.3 — tez-tez so'raladigan)Dizayn jarayoni: entity (obyekt — foydalanuvchi, kurs) → jadval → bog'lanish (1-ko'p, ko'p-ko'p) → kalit (birlamchi, tashqi) → cheklov (NOT NULL, UNIQUE) → normalizatsiya (takror yo'q) → indeks 23.3-bob. Avval qog'ozda (yoki diagramma — ER), keyin SQL. Dizayn — kod yozishdan oldin (o'zgartirish qimmat).
2.8. Yaxshi dizayn belgilari
| Belgi | Tavsif |
|---|---|
| Har fakt bir joyda | Takror yo'q (normalizatsiya) |
| Bog'lanish aniq | FK bilan |
| Baza o'zi himoyalanadi | Cheklovlar |
| Kengaytirish oson | Yangi jadval/ustun |
| So'rov samarali | Indeks, to'g'ri tuzilma |
Yaxshi dizayn: har fakt bir joyda (takror yo'q), bog'lanishlar aniq (FK), baza o'zi himoyalanadi (cheklov), kengaytirish oson (yangi jadval qo'shish — eskini buzmasdan), so'rov samarali (indeks). Yomon dizaynni keyinchalik tuzatish juda qiyin (ma'lumot ko'chirish, kod o'zgarish). "Dizaynga vaqt sarfla — keyin tejaladi".
3. Tez ma'lumotnoma
-- birlamchi + tashqi kalit:
CREATE TABLE muallif (id INTEGER PRIMARY KEY, nom TEXT NOT NULL);
CREATE TABLE kurs (
id INTEGER PRIMARY KEY,
nom TEXT NOT NULL,
narx INTEGER CHECK (narx >= 0),
muallif_id INTEGER REFERENCES muallif(id) -- bir-ko'p
);
-- ko'p-ko'p (oraliq jadval):
CREATE TABLE kurs_teg (
kurs_id INTEGER REFERENCES kurs(id),
teg_id INTEGER REFERENCES teg(id),
PRIMARY KEY (kurs_id, teg_id)
);
-- UNIQUE:
email TEXT UNIQUE NOT NULLDizayn tamoyillari
Normalizatsiya: har fakt bir marta · Kalit: birlamchi (shaxs), tashqi (bog'lanish)
Cheklov: NOT NULL/UNIQUE/CHECK/FK (himoya) · Bog'lanish: 1-1, 1-ko'p, ko'p-ko'p
Denormalizatsiya: o'lchab, kerak bo'lsa · Indeks: tez-tez so'raladigan4. Batafsil misollar
Misollarda sqlite3 (o'rnatilgan) bilan sinaladi.
PRAGMA foreign_keys=ON— SQLite'da FK cheklovini yoqadi.
Misol 1 — Normalizatsiya (takrorni yo'qotish)
"""normalizatsiya: takrorli (mijoz har buyurtmada) vs normallashtirilgan (mijoz alohida + FK)."""
import sqlite3
def main() -> None:
c = sqlite3.connect(":memory:")
print("=== 1. Yomon: takrorli dizayn ===")
c.execute("CREATE TABLE buyurtma_yomon (id INTEGER PRIMARY KEY, mahsulot TEXT, mijoz_nom TEXT, mijoz_tel TEXT)")
c.execute("INSERT INTO buyurtma_yomon(mahsulot,mijoz_nom,mijoz_tel) VALUES('Python','Ali','111'),('Go','Ali','111')")
r = c.execute("SELECT mahsulot, mijoz_nom FROM buyurtma_yomon").fetchall()
print(f" {r}")
print(" ⚠️ Ali ma'lumoti har qatorda takror (tel o'zgarsa — ikki joyda)")
print("\n=== 2. Yaxshi: normallashtirilgan ===")
c.execute("CREATE TABLE mijoz (id INTEGER PRIMARY KEY, nom TEXT NOT NULL, tel TEXT)")
c.execute("CREATE TABLE buyurtma (id INTEGER PRIMARY KEY, mahsulot TEXT, mijoz_id INTEGER REFERENCES mijoz(id))")
c.execute("INSERT INTO mijoz(nom,tel) VALUES('Ali','111')")
c.execute("INSERT INTO buyurtma(mahsulot,mijoz_id) VALUES('Python',1),('Go',1)")
print(" mijoz bir marta, buyurtma havola qiladi (FK)")
print("\n=== 3. JOIN bilan birlashtirish ===")
r = c.execute("""SELECT b.mahsulot, m.nom, m.tel FROM buyurtma b
JOIN mijoz m ON b.mijoz_id = m.id ORDER BY b.mahsulot""").fetchall()
print(f" {r}")
print("\n=== 4. Yangilash (bir joyda) ===")
c.execute("UPDATE mijoz SET tel='222' WHERE id=1") # bir marta
r = c.execute("SELECT DISTINCT m.tel FROM buyurtma b JOIN mijoz m ON b.mijoz_id=m.id").fetchall()
print(f" yangi tel (barcha buyurtmada): {r[0][0]}")
print(" ⭐ normalizatsiya — mijoz bir joyda, bir marta yangilanadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Yomon: takrorli dizayn ===
[('Python', 'Ali'), ('Go', 'Ali')]
⚠️ Ali ma'lumoti har qatorda takror (tel o'zgarsa — ikki joyda)
=== 2. Yaxshi: normallashtirilgan ===
mijoz bir marta, buyurtma havola qiladi (FK)
=== 3. JOIN bilan birlashtirish ===
[('Go', 'Ali', '111'), ('Python', 'Ali', '111')]
=== 4. Yangilash (bir joyda) ===
yangi tel (barcha buyurtmada): 222
⭐ normalizatsiya — mijoz bir joyda, bir marta yangilanadiNima ko'rsatdi: 2.1, 2.2-bo'limlar.
Misol 2 — Cheklovlar (himoya)
"""cheklovlar: FK (mavjud havola), UNIQUE (takrorsiz), NOT NULL, CHECK — baza to'g'riligi."""
import sqlite3
def main() -> None:
c = sqlite3.connect(":memory:")
c.execute("PRAGMA foreign_keys=ON")
c.execute("CREATE TABLE muallif (id INTEGER PRIMARY KEY, nom TEXT NOT NULL)")
c.execute("CREATE TABLE kurs (id INTEGER PRIMARY KEY, nom TEXT NOT NULL, narx INTEGER CHECK(narx>=0), muallif_id INTEGER REFERENCES muallif(id))")
c.execute("INSERT INTO muallif(nom) VALUES('Ali')")
print("=== 1. FK cheklovi (mavjud muallif) ===")
c.execute("INSERT INTO kurs(nom,narx,muallif_id) VALUES('Python',100,1)")
try:
c.execute("INSERT INTO kurs(nom,narx,muallif_id) VALUES('X',100,99)") # yo'q muallif
print(" qabul qilindi (yomon)")
except sqlite3.IntegrityError:
print(" ⚠️ yo'q muallifga bog'lash BLOKLANDI (yaxshi)")
print("\n=== 2. CHECK cheklovi (narx >= 0) ===")
try:
c.execute("INSERT INTO kurs(nom,narx,muallif_id) VALUES('Y',-50,1)")
print(" manfiy narx qabul (yomon)")
except sqlite3.IntegrityError:
print(" ⚠️ manfiy narx BLOKLANDI (yaxshi)")
print("\n=== 3. UNIQUE cheklovi (email) ===")
c.execute("CREATE TABLE foydalanuvchi (id INTEGER PRIMARY KEY, email TEXT UNIQUE NOT NULL)")
c.execute("INSERT INTO foydalanuvchi(email) VALUES('a@x.uz')")
try:
c.execute("INSERT INTO foydalanuvchi(email) VALUES('a@x.uz')") # takror
print(" takror email qabul (yomon)")
except sqlite3.IntegrityError:
print(" ⚠️ takror email BLOKLANDI (yaxshi)")
print("\n=== 4. NOT NULL cheklovi ===")
try:
c.execute("INSERT INTO muallif(nom) VALUES(NULL)")
print(" NULL nom qabul (yomon)")
except sqlite3.IntegrityError:
print(" ⚠️ NULL nom BLOKLANDI (yaxshi)")
print(" ⭐ cheklovlar — baza o'zi to'g'rilikni himoya qiladi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. FK cheklovi (mavjud muallif) ===
⚠️ yo'q muallifga bog'lash BLOKLANDI (yaxshi)
=== 2. CHECK cheklovi (narx >= 0) ===
⚠️ manfiy narx BLOKLANDI (yaxshi)
=== 3. UNIQUE cheklovi (email) ===
⚠️ takror email BLOKLANDI (yaxshi)
=== 4. NOT NULL cheklovi ===
⚠️ NULL nom BLOKLANDI (yaxshi)
⭐ cheklovlar — baza o'zi to'g'rilikni himoya qiladiNima ko'rsatdi: 2.4-bo'lim.
Misol 3 — Ko'p-ko'p bog'lanish (oraliq jadval)
"""ko'p-ko'p: kurs ↔ teg (bir kurs ko'p teg, bir teg ko'p kurs) — oraliq jadval bilan."""
import sqlite3
def main() -> None:
c = sqlite3.connect(":memory:")
c.execute("CREATE TABLE kurs (id INTEGER PRIMARY KEY, nom TEXT)")
c.execute("CREATE TABLE teg (id INTEGER PRIMARY KEY, nom TEXT)")
# oraliq jadval (junction) — ko'p-ko'p
c.execute("CREATE TABLE kurs_teg (kurs_id INTEGER, teg_id INTEGER, PRIMARY KEY(kurs_id, teg_id))")
c.execute("INSERT INTO kurs(nom) VALUES('Python'),('Go')")
c.execute("INSERT INTO teg(nom) VALUES('backend'),('data'),('system')")
# Python: backend+data; Go: backend+system
c.execute("INSERT INTO kurs_teg VALUES(1,1),(1,2),(2,1),(2,3)")
print("=== 1. Kurs → teglari ===")
r = c.execute("""SELECT k.nom, t.nom FROM kurs_teg kt
JOIN kurs k ON kt.kurs_id=k.id JOIN teg t ON kt.teg_id=t.id
WHERE k.nom='Python' ORDER BY t.nom""").fetchall()
print(f" Python teglari: {[x[1] for x in r]}")
print("\n=== 2. Teg → kurslari ===")
r = c.execute("""SELECT k.nom FROM kurs_teg kt JOIN kurs k ON kt.kurs_id=k.id
JOIN teg t ON kt.teg_id=t.id WHERE t.nom='backend' ORDER BY k.nom""").fetchall()
print(f" backend kurslari: {[x[0] for x in r]}")
print("\n=== 3. Teg bo'yicha kurslar soni ===")
r = c.execute("""SELECT t.nom, COUNT(*) FROM kurs_teg kt JOIN teg t ON kt.teg_id=t.id
GROUP BY t.nom ORDER BY t.nom""").fetchall()
print(f" {r}")
print("\n=== 4. Xulosa ===")
print(" bir kurs — ko'p teg, bir teg — ko'p kurs")
print(" ⭐ ko'p-ko'p — oraliq jadval (kurs_teg) bilan")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Kurs → teglari ===
Python teglari: ['backend', 'data']
=== 2. Teg → kurslari ===
backend kurslari: ['Go', 'Python']
=== 3. Teg bo'yicha kurslar soni ===
[('backend', 2), ('data', 1), ('system', 1)]
=== 4. Xulosa ===
bir kurs — ko'p teg, bir teg — ko'p kurs
⭐ ko'p-ko'p — oraliq jadval (kurs_teg) bilanNima ko'rsatdi: 2.5-bo'lim.
Misol 4 — Amaliy: to'liq sxema loyihalash
Real dizayn: entitylar, bog'lanishlar, kalitlar, cheklovlar — to'liq sxema. Bu — baza loyihalashning namunasi.
"""to'liq sxema: foydalanuvchi, kurs, buyurtma (1-ko'p, cheklov) — dizayn jarayoni."""
import sqlite3
def main() -> None:
c = sqlite3.connect(":memory:")
c.execute("PRAGMA foreign_keys=ON")
print("=== 1. Sxema loyihalash (entity + bog'lanish) ===")
c.executescript("""
CREATE TABLE foydalanuvchi (
id INTEGER PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
nom TEXT NOT NULL
);
CREATE TABLE kurs (
id INTEGER PRIMARY KEY,
nom TEXT NOT NULL,
narx INTEGER NOT NULL CHECK (narx >= 0)
);
CREATE TABLE buyurtma (
id INTEGER PRIMARY KEY,
foydalanuvchi_id INTEGER NOT NULL REFERENCES foydalanuvchi(id),
kurs_id INTEGER NOT NULL REFERENCES kurs(id),
sana TEXT NOT NULL
);
""")
print(" 3 jadval: foydalanuvchi, kurs, buyurtma (FK bilan)")
print("\n=== 2. Ma'lumot (cheklovlarga mos) ===")
c.execute("INSERT INTO foydalanuvchi(email,nom) VALUES('ali@x.uz','Ali')")
c.execute("INSERT INTO kurs(nom,narx) VALUES('Python',100),('Go',120)")
c.execute("INSERT INTO buyurtma(foydalanuvchi_id,kurs_id,sana) VALUES(1,1,'2024-01'),(1,2,'2024-02')")
print(" 1 foydalanuvchi, 2 kurs, 2 buyurtma")
print("\n=== 3. Hisobot (JOIN — 3 jadval) ===")
r = c.execute("""SELECT f.nom, k.nom, k.narx FROM buyurtma b
JOIN foydalanuvchi f ON b.foydalanuvchi_id=f.id
JOIN kurs k ON b.kurs_id=k.id ORDER BY k.nom""").fetchall()
for nom, kurs, narx in r:
print(f" {nom} → {kurs} ({narx})")
print("\n=== 4. Umumiy xarid (agregat) ===")
r = c.execute("""SELECT f.nom, SUM(k.narx) FROM buyurtma b
JOIN foydalanuvchi f ON b.foydalanuvchi_id=f.id
JOIN kurs k ON b.kurs_id=k.id GROUP BY f.nom""").fetchone()
print(f" {r[0]} jami xaridi: {r[1]}")
print(" ⭐ dizayn: entity → jadval → FK → cheklov → so'rov")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Sxema loyihalash (entity + bog'lanish) ===
3 jadval: foydalanuvchi, kurs, buyurtma (FK bilan)
=== 2. Ma'lumot (cheklovlarga mos) ===
1 foydalanuvchi, 2 kurs, 2 buyurtma
=== 3. Hisobot (JOIN — 3 jadval) ===
Ali → Go (120)
Ali → Python (100)
=== 4. Umumiy xarid (agregat) ===
Ali jami xaridi: 220
⭐ dizayn: entity → jadval → FK → cheklov → so'rovNima ko'rsatdi: 2.1–2.8-bo'limlar.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Hammani bir jadvalda" | Normalizatsiya (bo'l) |
| "Takror muammo emas" | Nomuvofiqlik xavfi |
| "FK keraksiz" | To'g'rilik himoyasi |
| "Ko'p-ko'p to'g'ridan" | Oraliq jadval kerak |
| "Cheklov sekinlashtiradi" | To'g'rilik muhimroq |
| "Denormalizatsiya yomon" | O'lchab, kerak bo'lsa |
| "Dizayn keyin tuzatiladi" | Keyinchalik juda qiyin |
| "3NF dan yuqori shart" | 3NF ko'p loyihaga yetarli |
6. Keng tarqalgan xatolar va yechimlari
1. Takrorli ma'lumot (normalizatsiyasiz)
buyurtma(mahsulot, mijoz_nom, mijoz_tel) -- ⚠️ takror
mijoz(...) + buyurtma(mijoz_id) -- ✅ (FK)2. Birlamchi kalitsiz jadval
CREATE TABLE kurs (nom TEXT, narx INTEGER) -- ⚠️ shaxs yo'q
CREATE TABLE kurs (id INTEGER PRIMARY KEY, ...) -- ✅3. FK cheklovsiz bog'lanish
muallif_id INTEGER -- ⚠️ yo'q muallifga bog'lab bo'ladi
muallif_id INTEGER REFERENCES muallif(id) -- ✅4. Ko'p-ko'pni bir jadvalda (vergul bilan)
kurs(teglar TEXT) -- "backend,data" -- ⚠️ so'rov qiyin
kurs_teg(kurs_id, teg_id) -- ✅ (oraliq)5. UNIQUE kerak joyda yo'q
email TEXT -- ⚠️ takror mumkin
email TEXT UNIQUE NOT NULL -- ✅6. Erta denormalizatsiya (o'lchamasdan)
-- "tez bo'ladi" deb takror qo'shish -- ⚠️ murakkablik
-- avval normalizatsiya, o'lcha, keyin -- ✅7. Indekssiz FK (23.3)
-- FK ustuni tez-tez JOIN'da, indekssiz -- ⚠️ sekin
CREATE INDEX ix_kurs_muallif ON kurs(muallif_id) -- ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 23.1-dars (o'tilgan): SQL — jadval yaratish
- 23.2-dars (o'tilgan): JOIN — bog'lanish o'qish
- 23.3-dars (o'tilgan): Indekslar — FK indeksi
- 23.7-dars (o'tilgan): ORM — model = jadval dizayni
- 24-qism: Test — sxema test'da
8. Eng yaxshi amaliyotlar
Normalizatsiya (3NF) — takrorni yo'qot.
Har jadvalda birlamchi kalit (
id).Bog'lanish — FK cheklovi bilan.
Ko'p-ko'p — oraliq jadval.
Cheklovlar (NOT NULL, UNIQUE, CHECK) — himoya.
Denormalizatsiya — faqat o'lchab, kerak bo'lsa.
FK ustunga indeks 23.3-bob.
Dizaynni kod'dan oldin (ER diagramma).
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # Normalizatsiya nima?
2. # nega takror yomon?
3. # birlamchi kalit nima?
4. # tashqi kalit nima?
5. # NOT NULL nima?
6. # UNIQUE nima?
7. # FK cheklovi nima?
8. # bir-ko'p nima?
9. # ko'p-ko'p qanday?
10. # denormalizatsiya nima?
11. # 3NF nima?
12. # dizayn qachon?Javoblar
- Ma'lumot takrorini yo'qotish (har fakt bir marta)
- Nomuvofiqlik (bir joyda yangilandi, boshqasida yo'q)
- Satrni noyob aniqlovchi (id)
- Boshqa jadvalga havola (bog'lanish)
- Bo'sh bo'lmasin
- Takrorlanmasin
- Havola mavjud bo'lsin
- Bir muallif — ko'p kurs (FK ko'p tomonda)
- Oraliq jadval bilan
- Ataylab takror (unumdorlik uchun)
- Ustun faqat kalitga bog'liq
- Kod'dan oldin (o'zgartirish qimmat)
Vazifa 2: Xatolarni tuzating
1. buyurtma(mahsulot, mijoz_nom, mijoz_tel) -- normalizatsiya
2. CREATE TABLE kurs (nom TEXT, narx INTEGER) -- id
3. muallif_id INTEGER -- REFERENCES
4. kurs(teglar TEXT) -- "backend,data" -- oraliq
5. email TEXT -- UNIQUEJavoblar
1. mijoz(...) + buyurtma(mijoz_id REFERENCES mijoz(id))
2. CREATE TABLE kurs (id INTEGER PRIMARY KEY, nom TEXT, narx INTEGER)
3. muallif_id INTEGER REFERENCES muallif(id)
4. kurs_teg(kurs_id, teg_id) -- oraliq jadval
5. email TEXT UNIQUE NOT NULLVazifa 3: Normalizatsiya
Takrorni yo'qot:
- Takrorli jadval
- Alohida jadvalga chiqar
- FK bilan bog'la
- JOIN bilan o'qi
Vazifa 4: Cheklovlar
Himoya:
- NOT NULL, UNIQUE
- CHECK (shart)
- FK
- Buzish urinishi (bloklanadi)
Vazifa 5: Bog'lanishlar
Uch tur:
- Bir-ko'p (FK)
- Ko'p-ko'p (oraliq)
- Bir-bir (FK)
- Har biri test
Vazifa 6: To'liq sxema
Loyiha:
- Entitylarni aniqla
- Jadval + kalit
- Bog'lanish + cheklov
- So'rov (JOIN)
Vazifa 7: O'ylash
Baza dizayni — 23-qismning yakuni — barcha o'rgangan bilimni (SQL, JOIN, indeks, ORM, NoSQL) birlashtiradi. Normalizatsiya "har fakt bir joyda" tamoyiliga asoslanadi — bu dasturlashning umumiy DRY (Don't Repeat Yourself — takrorlama) tamoyilining baza versiyasi. Nima uchun "har fakt bir manba" (single source of truth) muhim — baza dizaynida ham, kod'da ham, va yaxshi dizayn nima uchun oldindan o'ylashni (kod'dan keyin emas) talab qiladi?
Javob
Qisqa javob: Normalizatsiya — "har fakt bir joyda, bir marta" — bu DRY (Don't Repeat Yourself) tamoyilining baza versiyasi. Nima uchun muhim: takror bo'lsa, nomuvofiqlik xavfi (bir nusxa yangilandi, boshqasi eski qoldi — qaysi to'g'ri?). "Bitta haqiqat manbai" (single source of truth) — har fakt uchun bitta vakolatli joy. Bu kod'da ham (bir mantiq — bir funksiya, takror emas), bazada ham (bir fakt — bir jadval). Dizayn oldindan kerak, chunki bazani keyin o'zgartirish juda qiyin: ma'lumot ko'chirish (million satr), kod o'zgarish (barcha so'rov), ishlab turgan tizim (to'xtatib bo'lmaydi). Kod'ni refaktoring oson, sxemani — qiyin. "Dizaynga bir soat — keyin bir hafta tejaladi".
1. DRY va single source of truth
"Har fakt bir joyda" (normalizatsiya) = DRY (takrorlama). Har ma'lumot uchun bitta vakolatli manba. Takror → nomuvofiqlik (qaysi to'g'ri?).
2. Nega takror xavfli
| Takror | Muammo |
|---|---|
| Mijoz nomi 100 joyda | O'zgarsa — 100 yangilash |
| Bittasi unutildi | Nomuvofiqlik (qaysi to'g'ri?) |
| Joy isrofi | Ko'p nusxa |
3. Kod'da ham shu tamoyil
| Baza | Kod |
|---|---|
| Fakt bir jadvalda | Mantiq bir funksiyada |
| Normalizatsiya | DRY (takrorlama) |
| FK (havola) | Import (havola) |
4. Nega dizayn oldindan
| O'zgartirish | Qiyinlik |
|---|---|
| Kod refaktoring | Oson (IDE, test) |
| Sxema o'zgartirish | Qiyin (ma'lumot ko'chir, migratsiya) |
| Ishlab turgan baza | Juda qiyin (to'xtatib bo'lmaydi) |
Baza — poydevor (uy poydevori kabi): keyin o'zgartirish qimmat. Kod — devor (osonroq).
5. Muhandislik saboqlari
- Har fakt bir manba (DRY, normalizatsiya)
- Takror → nomuvofiqlik xavfi
- Dizayn oldindan (sxema o'zgarish qiyin)
- Baza — poydevor (ehtiyot bilan)
6. Xulosa
- Normalizatsiya = DRY (baza versiyasi)
- Single source of truth — nomuvofiqlikni oldini oladi
- Dizayn kod'dan oldin (o'zgarish qimmat)
- Yaxshi dizayn — vaqt tejaydi
Nimani mustahkamlaydi: 2.1–2.8-bo'limlar.
Xulosa
Bu darsda — 23-qism yakuni — baza dizayni tamoyillarini o'rgandik.
Eng muhim uch fikr:
Normalizatsiya — har fakt bir joyda. Normalizatsiya — ma'lumotni shunday tashkil qilishki, har fakt bir marta saqlansin (takror yo'q). Takror yomon: joy isrofi va nomuvofiqlik (bir joyda yangilandi, boshqasida yo'q). Yechim: takrorlanadigan ma'lumotni alohida jadvalga chiqar, havola (FK) bilan bog'la. Normal shakllar: 1NF (har katak bitta qiymat), 2NF (butun kalitga bog'liq), 3NF (faqat kalitga) — amaliyotda 3NF yetarli. Bu DRY (Don't Repeat Yourself) tamoyilining baza versiyasi — "bitta haqiqat manbai".
Kalitlar, cheklovlar, bog'lanishlar. Birlamchi kalit (primary key —
id) satrni noyob aniqlaydi; tashqi kalit (foreign key —muallif_id) boshqa jadvalga havola (bog'lanish). Cheklovlar baza to'g'riligini himoya qiladi: NOT NULL (bo'sh emas), UNIQUE (takrorsiz), CHECK (shart), FK (havola mavjud) — dastur xatosi ham bazani buzolmaydi. Bog'lanish turlari: bir-bir (FK), bir-ko'p (FK "ko'p" tomonda — eng keng tarqalgan), ko'p-ko'p (oraliq jadval —kurs_teg). Bu 23.1–23.3 (jadval, JOIN, indeks) ustida quriladi.Dizayn jarayoni va 23-qism yakuni. Dizayn: entity → jadval → bog'lanish → kalit → cheklov → normalizatsiya → indeks 23.3-bob. Denormalizatsiya — unumdorlik uchun ataylab takror (avval normalizatsiya, o'lchab kerak bo'lsa). Dizayn kod'dan oldin — sxemani keyin o'zgartirish juda qiyin (ma'lumot ko'chirish, migratsiya, ishlab turgan tizim). 23-qism yakuni: SQL asoslari (23.1–23.5), ORM (23.6–23.9 — SQLAlchemy Core/ORM, migratsiya, N+1), kesh (23.10 — Redis), NoSQL (23.11 — MongoDB), dizayn 23.12-bob. Ma'lumot — har ilovaning yuragi; uni to'g'ri saqlash, so'rash, loyihalash — muhim mahorat.
Keyingi qismda (24-qism: Ma'lumot tahlili) ma'lumot bilan ishlashni — NumPy (massiv, tez hisoblash), pandas (DataFrame, tozalash, guruhlash), Matplotlib/Seaborn (vizualizatsiya), statistikani o'rganamiz: ma'lumotdan xulosa chiqarish mahorati.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!