8-bo‘lim

Uchinchi normal shakl va BCNF

Tranzitiv bog'liqlik, 3NF ga keltirish, BCNF va uning 3NF dan farqi, normal shakllar xulosasi.

🕑 17 daqiqa o‘qish 📄 801 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Tranzitiv bog'liqlik
  2. 3NF buzilgan jadval
  3. Bog'liqlikni aniqlash
  4. Anomaliyalar
  5. 3NF ga keltirish
  6. Anomaliyalar yo'qoldi
  7. BCNF - 3NF dan kuchliroq
  8. BCNF ga keltirish
  9. Normal shakllar xulosasi
  10. Xulosa

2NF kalitning qismiga bog'liqlikni yo'q qildi. 3NF esa kalitga umuman bog'liq bo'lmagan bog'liqliklarni oladi.

Tranzitiv bog'liqlik #

Tranzitiv bog'liqlik zanjiri xodim_id (kalit) aniqlaydi bolim_id (kalit emas) aniqlaydi bolim_boshligi (kalit emas) tranzitiv (bilvosita) bog'liqlik Kalit emas ustun boshqa kalit emas ustunni aniqlasa - 3NF buzilgan
Zanjirdagi o'rta bo'g'in muammoni ko'rsatadi

3NF buzilgan jadval #

SQL
CREATE TABLE xodimlar_yomon (
    id              INT PRIMARY KEY,
    ism             VARCHAR(100) NOT NULL,
    bolim_id        INT NOT NULL,
    bolim_nomi      VARCHAR(50)  NOT NULL,
    bolim_boshligi  VARCHAR(100) NOT NULL,
    bolim_qavati    TINYINT      NOT NULL
);

INSERT INTO xodimlar_yomon VALUES
    (1, 'Husanboy', 10, 'IT',      'Nodira Karimova', 3),
    (2, 'Malika',   20, 'Hisobot', 'Aziza Tosheva',   2),
    (3, 'Kamola',   10, 'IT',      'Nodira Karimova', 3),
    (4, 'Dilnoza',  10, 'IT',      'Nodira Karimova', 3);
SQL
SELECT id, ism, bolim_nomi, bolim_boshligi
FROM xodimlar_yomon
ORDER BY id;
Natija
+----+----------+------------+-----------------+
| id | ism      | bolim_nomi | bolim_boshligi  |
+----+----------+------------+-----------------+
|  1 | Husanboy | IT         | Nodira Karimova |
|  2 | Malika   | Hisobot    | Aziza Tosheva   |
|  3 | Kamola   | IT         | Nodira Karimova |
|  4 | Dilnoza  | IT         | Nodira Karimova |
+----+----------+------------+-----------------+

Bu jadval 2NF da - kalit bitta ustun (id), shuning uchun qisman bog'liqlik mumkin emas.

Lekin muammo bor: Nodira Karimova uch marta takrorlangan.

Bog'liqlikni aniqlash #

SQL
-- bolim_id -> bolim_nomi bog'liqligi bormi?
SELECT bolim_id,
       COUNT(DISTINCT bolim_nomi)     AS turli_nom,
       COUNT(DISTINCT bolim_boshligi) AS turli_boshliq,
       COUNT(*)                       AS qatorlar
FROM xodimlar_yomon
GROUP BY bolim_id
ORDER BY bolim_id;
Natija
+----------+-----------+---------------+----------+
| bolim_id | turli_nom | turli_boshliq | qatorlar |
+----------+-----------+---------------+----------+
|       10 |         1 |             1 |        3 |
|       20 |         1 |             1 |        1 |
+----------+-----------+---------------+----------+

bolim_id bir xil bo'lganda bolim_nomi va bolim_boshligi har doim bir xil. Demak bog'liqlik zanjiri shunday:

Natija
id -> bolim_id -> bolim_nomi, bolim_boshligi, bolim_qavati
3NF ta'rifi

Jadval 3NF da bo'ladi, agar u 2NF da bo'lsa va hech bir kalitga kirmaydigan ustun boshqa kalitga kirmaydigan ustunga bog'liq bo'lmasa.

Qisqacha eslab qolish uchun klassik ibora:

Har bir kalit emas ustun kalitga, butun kalitga va faqat kalitga bog'liq bo'lishi kerak.

QismQaysi normal shakl
"kalitga"1NF
"butun kalitga"2NF
"faqat kalitga"3NF

bolim_boshligi xodim_id ga emas, bolim_id ga bog'liq - ya'ni "faqat kalitga" sharti buzilgan.

Anomaliyalar #

SQL
-- 1. Bo'lim boshlig'i almashdi - uch qatorni yangilash kerak
UPDATE xodimlar_yomon
SET bolim_boshligi = 'Malika Yusupova'
WHERE id = 1;

SELECT bolim_id, COUNT(DISTINCT bolim_boshligi) AS turli_boshliq
FROM xodimlar_yomon
WHERE bolim_id = 10
GROUP BY bolim_id;
Natija
+----------+---------------+
| bolim_id | turli_boshliq |
+----------+---------------+
|       10 |             2 |
+----------+---------------+
SQL
-- 2. Xodimsiz bo'lim saqlanmaydi
DELETE FROM xodimlar_yomon WHERE bolim_id = 20;

SELECT COUNT(*) AS hisobot_bolimi_haqida
FROM xodimlar_yomon
WHERE bolim_nomi = 'Hisobot';
Natija
+-----------------------+
| hisobot_bolimi_haqida |
+-----------------------+
|                     0 |
+-----------------------+

3NF ga keltirish #

SQL
CREATE TABLE bolimlar (
    id       INT PRIMARY KEY,
    nom      VARCHAR(50)  NOT NULL UNIQUE,
    boshliq  VARCHAR(100) NOT NULL,
    qavat    TINYINT      NOT NULL
);

CREATE TABLE xodimlar (
    id       INT PRIMARY KEY,
    ism      VARCHAR(100) NOT NULL,
    bolim_id INT NOT NULL,
    FOREIGN KEY (bolim_id) REFERENCES bolimlar(id)
);

INSERT INTO bolimlar VALUES
    (10, 'IT',      'Nodira Karimova', 3),
    (20, 'Hisobot', 'Aziza Tosheva',   2),
    (30, 'Marketing', 'Dilnoza Yusupova', 1);

INSERT INTO xodimlar VALUES
    (1, 'Husanboy', 10),
    (2, 'Malika',   20),
    (3, 'Kamola',   10),
    (4, 'Dilnoza',  10);
SQL
SELECT x.ism, b.nom AS bolim, b.boshliq
FROM xodimlar x
JOIN bolimlar b ON b.id = x.bolim_id
ORDER BY x.id;
Natija
+----------+---------+-----------------+
| ism      | bolim   | boshliq         |
+----------+---------+-----------------+
| Husanboy | IT      | Nodira Karimova |
| Malika   | Hisobot | Aziza Tosheva   |
| Kamola   | IT      | Nodira Karimova |
| Dilnoza  | IT      | Nodira Karimova |
+----------+---------+-----------------+

Anomaliyalar yo'qoldi #

SQL
-- 1. Boshliq almashdi - BITTA qator
UPDATE bolimlar SET boshliq = 'Malika Yusupova' WHERE id = 10;

SELECT x.ism, b.boshliq
FROM xodimlar x
JOIN bolimlar b ON b.id = x.bolim_id
WHERE b.id = 10
ORDER BY x.id;
Natija
+----------+-----------------+
| ism      | boshliq         |
+----------+-----------------+
| Husanboy | Malika Yusupova |
| Kamola   | Malika Yusupova |
| Dilnoza  | Malika Yusupova |
+----------+-----------------+
SQL
-- 2. Xodimsiz bo'lim ham saqlanadi
SELECT b.nom, COUNT(x.id) AS xodimlar_soni
FROM bolimlar b
LEFT JOIN xodimlar x ON x.bolim_id = b.id
GROUP BY b.id, b.nom
ORDER BY b.id;
Natija
+-----------+---------------+
| nom       | xodimlar_soni |
+-----------+---------------+
| IT        |             3 |
| Hisobot   |             1 |
| Marketing |             0 |
+-----------+---------------+

Marketing bo'limi hali xodimsiz, lekin mavjud.

3NF buzilishini tanish belgilari

Amalda 3NF buzilishini quyidagi belgilar bilan topasiz:

BelgiMisol
Ustunlar umumiy prefiks bilanbolim_nomi, bolim_boshligi
_id ustuni yonida uning tafsilotlaribolim_id + bolim_nomi
Ma'lumot guruh-guruh takrorlanadiUch qatorda bir xil uchlik
"Bu ustun kim haqida?" savoliga boshqa javobXodim emas, bo'lim haqida

Eng oddiy tekshiruv - ustun nomlarini o'qing. Agar jadval xodimlar deb atalgan bo'lsa, lekin ustunlar bolim_ bilan boshlansa - ular boshqa jadvalga tegishli.

Yana bir klassik misol:

SQL
buyurtmalar (id, mijoz_id, mijoz_shahri, yetkazish_narxi)

yetkazish_narxi mijoz_shahri ga bog'liq bo'lsa - bu ham tranzitiv bog'liqlik. Narxlar alohida shaharlar jadvaliga chiqadi.

BCNF - 3NF dan kuchliroq #

Klassik misol: har fanni bir o'qituvchi o'qitadi, lekin bir o'qituvchi bir necha fan o'qitishi mumkin.

SQL
CREATE TABLE dars_biriktirish (
    talaba_id  INT NOT NULL,
    fan        VARCHAR(50) NOT NULL,
    oqituvchi  VARCHAR(100) NOT NULL,
    PRIMARY KEY (talaba_id, fan)
);

INSERT INTO dars_biriktirish VALUES
    (1, 'Matematika',  'Nodira Karimova'),
    (1, 'Fizika',      'Aziza Tosheva'),
    (2, 'Matematika',  'Nodira Karimova'),
    (3, 'Matematika',  'Nodira Karimova');
SQL
SELECT talaba_id, fan, oqituvchi
FROM dars_biriktirish
ORDER BY talaba_id, fan;
Natija
+-----------+------------+-----------------+
| talaba_id | fan        | oqituvchi       |
+-----------+------------+-----------------+
|         1 | Fizika     | Aziza Tosheva   |
|         1 | Matematika | Nodira Karimova |
|         2 | Matematika | Nodira Karimova |
|         3 | Matematika | Nodira Karimova |
+-----------+------------+-----------------+
SQL
-- fan -> oqituvchi bog'liqligi bor
SELECT fan, COUNT(DISTINCT oqituvchi) AS turli_oqituvchi
FROM dars_biriktirish
GROUP BY fan
ORDER BY fan;
Natija
+------------+-----------------+
| fan        | turli_oqituvchi |
+------------+-----------------+
| Fizika     |               1 |
| Matematika |               1 |
+------------+-----------------+
Bu jadval 3NF da, lekin BCNF da emas

Tekshiramiz:

  • 1NF: har katakda bitta qiymat - ha;
  • 2NF: oqituvchi (talaba_id, fan) juftligiga bog'liqmi? Aslida faqat fan ga bog'liq - qisman bog'liqlik!

To'xtang - demak bu 2NF ni ham buzadi?

Bu yerda nozik jihat bor. oqituvchi kalitga kiruvchi atribut hisoblanadimi? (fan, oqituvchi) ham nomzod kalit bo'lishi mumkin (agar talaba bir fanni bir o'qituvchidan o'qisa). Bunday holatda oqituvchi asosiy atribut bo'lib qoladi va 2NF/3NF ta'riflari unga qo'llanmaydi.

BCNF esa qat'iyroq:

Har bir funksional bog'liqlik X → Y da X super kalit bo'lishi kerak.

Bu yerda fan → oqituvchi bor, lekin fan super kalit emas (u yolg'iz qatorni aniqlamaydi). Demak BCNF buzilgan.

Yechim - jadvalni ikkiga bo'lish:

SQL
fan_oqituvchi (fan PK, oqituvchi)
talaba_fan    (talaba_id, fan)  PK (talaba_id, fan)

BCNF ga keltirish #

SQL
CREATE TABLE fan_oqituvchi (
    fan       VARCHAR(50)  PRIMARY KEY,
    oqituvchi VARCHAR(100) NOT NULL
);

CREATE TABLE talaba_fan (
    talaba_id INT NOT NULL,
    fan       VARCHAR(50) NOT NULL,
    PRIMARY KEY (talaba_id, fan),
    FOREIGN KEY (fan) REFERENCES fan_oqituvchi(fan)
);

INSERT INTO fan_oqituvchi VALUES
    ('Matematika', 'Nodira Karimova'),
    ('Fizika',     'Aziza Tosheva');

INSERT INTO talaba_fan VALUES
    (1, 'Matematika'), (1, 'Fizika'),
    (2, 'Matematika'), (3, 'Matematika');
SQL
SELECT tf.talaba_id, tf.fan, fo.oqituvchi
FROM talaba_fan tf
JOIN fan_oqituvchi fo ON fo.fan = tf.fan
ORDER BY tf.talaba_id, tf.fan;
Natija
+-----------+------------+-----------------+
| talaba_id | fan        | oqituvchi       |
+-----------+------------+-----------------+
|         1 | Fizika     | Aziza Tosheva   |
|         1 | Matematika | Nodira Karimova |
|         2 | Matematika | Nodira Karimova |
|         3 | Matematika | Nodira Karimova |
+-----------+------------+-----------------+
SQL
-- Endi o'qituvchini almashtirish - bitta qator
UPDATE fan_oqituvchi SET oqituvchi = 'Kamola Rasulova' WHERE fan = 'Matematika';

SELECT fan, oqituvchi FROM fan_oqituvchi ORDER BY fan;
Natija
+------------+-----------------+
| fan        | oqituvchi       |
+------------+-----------------+
| Fizika     | Aziza Tosheva   |
| Matematika | Kamola Rasulova |
+------------+-----------------+

Normal shakllar xulosasi #

Normal shakllar ierarxiyasi Normallashtirilmagan vergulli ro'yxat, takrorlanuvchi ustunlar 1NF har katakda bitta atomar qiymat 2NF butun kalitga bog'liq (kompozit kalitda muhim) 3NF faqat kalitga bog'liq - AMALDA YETARLI BCNF har bog'liqlikning chap tomoni super kalit
Ko'p loyihada 3NF yetarli, BCNF kamdan-kam kerak bo'ladi
Normal shaklNimani yo'q qiladi
1NFKo'p qiymatli va takrorlanuvchi ustunlar
2NFKalitning qismiga qisman bog'liqlik
3NFKalitga kirmaydigan ustunlar orasidagi bog'liqlik
BCNFHar qanday super kalit bo'lmagan aniqlovchi
4NF, 5NFKo'p qiymatli va birlashma bog'liqliklari
Amalda qayerda to'xtash kerak

3NF - amaliy standart. Ko'p loyiha uchun yetarli.

BCNF kerak bo'ladigan holat juda kam: jadvalda bir necha ustunli, kesishuvchi nomzod kalitlar bo'lganda. Odatiy sxemalarda bunday holat deyarli uchramaydi.

4NF va 5NF esa asosan nazariy - ular mustaqil ko'p qiymatli bog'liqliklarni ko'rib chiqadi. Amaliyotda ularni bilib, lekin qo'llamay ketaverasiz.

Amaliy tartib:

  1. Sxemani 3NF ga keltiring;
  2. Ishga tushiring va o'lchang;
  3. Sekin joylarni topsangiz - ongli ravishda denormallang (9-bo'lim).

Boshidan denormallash - erta optimallashtirish. Avval to'g'ri qiling, keyin tez qiling.

Amaliy topshiriq
  1. Tranzitiv bog'liqlikli jadval yaratib, ma'lumot kiriting.
  2. COUNT(DISTINCT) bilan bolim_id -> bolim_nomi ni isbotlang.
  3. Bo'lim boshlig'ini bir joyda o'zgartirib, ziddiyat hosil qiling.
  4. Bo'limning barcha xodimini o'chirib, ma'lumot yo'qolishini ko'ring.
  5. Jadvalni ikkiga bo'lib, 3NF ga keltiring.
  6. Xodimsiz bo'lim saqlanishini tekshiring.
  7. "Kalitga, butun kalitga, faqat kalitga" iborasini tushuntiring.
  8. BCNF va 3NF farqini o'z so'zingiz bilan ayting.
  9. fan -> oqituvchi bog'liqligini ajratib chiqaring.
  10. Amalda qaysi normal shaklda to'xtash kerakligini asoslang.

Xulosa #

  • Tranzitiv bog'liqlik: kalit emas ustun boshqa kalit emas ustunni aniqlaydi.
  • 3NF: har ustun faqat kalitga bog'liq bo'lsin.
  • Eslab qolish: "kalitga, butun kalitga, faqat kalitga".
  • Belgi: ustunlar umumiy prefiks bilan (bolim_nomi, bolim_boshligi).
  • _id ustuni yonida uning tafsilotlari turmasin.
  • BCNF: har bog'liqlikning chap tomoni super kalit bo'lsin.
  • BCNF faqat kesishuvchi nomzod kalitlarda kerak bo'ladi.
  • Amalda 3NF yetarli - 4NF va 5NF asosan nazariy.
  • Avval to'g'ri qiling, keyin o'lchab optimallashtiring.

Keyingi bo'limda qoidani ataylab buzishni - denormalizatsiyani ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.