- Superaçar, namizəd, ilkin və xarici açarı fərqləndirmək
- Funksional asılılıqlara əsasən cədvəli 3NF-ə qədər normallaşdırmaq
- ACID xassələrini izah etmək və indeksin qazancını hesablamaq
Onlayn mağaza hər sifarişi bir Excel sətrinə yazsaydı, Anar Bakıdan Gəncəyə köçəndə onun ünvanını yüzlərlə sətirdə dəyişmək lazım gələrdi, birini unutsaydın, bazada iki fərqli şəhər qalardı. Verilənlər bazası nəzəriyyəsi belə problemləri riyazi dəqiqliklə aradan qaldırır: verilənləri düzgün cədvəllərə bölür, onları eyni anda yüzlərlə istifadəçidən qoruyur və milyardlarla sətir arasında axtarışı millisaniyələrə endirir.
Relyasiya modeli və açarlar
1970-ci ildə Edqar Koddun təklif etdiyi relyasiya modelində verilənlər münasibətlərdə (cədvəllərdə) saxlanır. Münasibət — eyni atributlara malik kortejlər (sətirlər) çoxluğudur; hər atributun domeni (icazəli qiymətlər çoxluğu) var. Çoxluq olduğu üçün sətirlərin sırası yoxdur və iki eyni sətir ola bilməz. Sorğular relyasiya cəbri ilə ifadə olunur, SQL isə onun praktik dilidir.
- σseçmə (selection): şərtə uyğun sətirlər —
WHERE - πproyeksiya: lazımi sütunlar —
SELECTsiyahısı - ⋈birləşmə (join): iki münasibətin ortaq atribut üzrə birləşdirilməsi —
JOIN
| Açar | Tərif | Nümunə (students) |
|---|---|---|
| Superaçar | sətri birmənalı müəyyən edən istənilən atributlar çoxluğu | {id}, {id, city} |
| Namizəd açar | minimal superaçar (heç bir atributu atmaq olmaz) | {id} |
| İlkin açar | seçilmiş namizəd açar: unikal və NULL ola bilməz | id |
| Xarici açar | başqa cədvəlin ilkin açarına istinad (referensial bütövlük) | enrollments.student_id → students.id |
SELECT COUNT(*) AS students,
COUNT(email) AS with_email,
COUNT(DISTINCT email) AS distinct_emails,
COUNT(DISTINCT city) AS distinct_cities
FROM students;▸ Gözlənilən nəticə
students | with_email | distinct_emails | distinct_cities 12 | 10 | 10 | 7
city açar ola bilməz (12 sətirdə cəmi 7 fərqli şəhər). email doldurulmuş sətirlərdə unikaldır (10 = 10), amma 2 tələbədə NULL-dur — ona görə ilkin açar ola bilməz. Diqqət: verilənlərin indiki halı açarı sübut etmir, açar biznes qaydasıdır.Normallaşdırma: 1NF, 2NF, 3NF
Pis layihələndirilmiş cədvəl üç növ anomaliya yaradır. Yeniləmə anomaliyası: eyni fakt çox sətirdə təkrarlanır və biri yenilənməsə, ziddiyyət yaranır. Əlavə anomaliyası: hələ sifarişi olmayan yeni məhsulu cədvələ yazmaq mümkün deyil, çünki açarın bir hissəsi boş qalır. Silmə anomaliyası: müştərinin yeganə sifarişini silsən, müştəri haqqında bütün məlumat da itir. Normallaşdırma cədvəli itkisiz hissələrə bölərək bu anomaliyaları aradan qaldırır: hər fakt bir yerdə saxlanır.
X atributlarının qiyməti eyni olan iki sətirdə Y atributlarının qiyməti də mütləq eynidir. Məsələn, customer_id → customer_city: müştərini bilsən, şəhərini də bilirsən. Normallaşdırma məhz bu asılılıqlara əsaslanır.
| Forma | Tələb | Nəyi aradan qaldırır |
|---|---|---|
| 1NF | hər xanada bir atomar qiymət, təkrarlanan qruplar yoxdur | «Laptop, Qulaqlıq» kimi siyahı-xanaları |
| 2NF | 1NF + heç bir qeyri-açar atribut tərkibli açarın bir hissəsindən asılı deyil | qismən asılılıqları |
| 3NF | 2NF + qeyri-açar atributlar yalnız açardan asılıdır, bir-birindən yox | tranzitiv asılılıqları |
Mağaza cədvəli: order_id, order_date, customer_id, customer_name, customer_city, products və products xanasında «Laptop ×1, Headphones ×2» kimi siyahı. Qiymət və kateqoriya da bu siyahıdadır. Cədvəli 1NF, 2NF və 3NF-ə gətir.
Həllini göstərHəllini gizlət
(order_id, product_id, order_date, customer_id, customer_name, customer_city, product_name, category, price, quantity), açar (order_id, product_id).Asılılıqlar: order_id → order_date, customer_id; customer_id → customer_name, customer_city; product_id → product_name, category, price; (order_id, product_id) → quantity.
2NF: açarın hissəsindən asılı olanları ayırırıq:
order_items(order_id, product_id, quantity)orders(order_id, order_date, customer_id, customer_name, customer_city)products(product_id, product_name, category, price)3NF:
orders-da order_id → customer_id → customer_city tranzitivdir, ayırırıq:orders(order_id, order_date, customer_id) + customers(customer_id, customer_name, customer_city).Nəticə: 4 cədvəl. İndi Anarın şəhəri bir xanada dəyişir.
SELECT s.first_name, s.city, c.title, c.teacher, e.score
FROM enrollments AS e
JOIN students AS s ON s.id = e.student_id
JOIN courses AS c ON c.id = e.course_id
WHERE c.teacher = 'Ramin Səfərov'
ORDER BY c.title, s.first_name;▸ Gözlənilən nəticə
first_name | city | title | teacher | score Aysel | Bakı | Algebra | Ramin Səfərov | 92 Fidan | Naxçıvan | Algebra | Ramin Səfərov | 97 Murad | Gəncə | Algebra | Ramin Səfərov | 75 Nigar | Şəki | Algebra | Ramin Səfərov | 85 Leyla | Bakı | Geometry | Ramin Səfərov | 95 Orxan | Sumqayıt | Geometry | Ramin Səfərov | 70 Səbinə | Quba | Geometry | Ramin Səfərov | 79
students, courses, enrollments. JOIN «düz» cədvəli yalnız lazım olanda bərpa edir — burada müəllimin adı 7 dəfə təkrarlanır. Əgər o, cədvəldə belə saxlansaydı, müəllimin dəyişməsi 7 sətrin yenilənməsini tələb edərdi (yeniləmə anomaliyası).Tranzaksiyalar və ACID
| Xassə | Mənası | Necə təmin olunur |
|---|---|---|
| Atomarlıq (A) | ya hamısı, ya heç nə | ROLLBACK, geri qaytarma jurnalı |
| Uyğunluq (C) | baza bir düzgün vəziyyətdən digərinə keçir | məhdudiyyətlər: açarlar, CHECK, xarici açarlar |
| Təcridolunma (I) | paralel tranzaksiyalar bir-birinin yarımçıq işini görmür | kilidlər, çoxversiyalılıq (MVCC) |
| Davamlılıq (D) | COMMIT-dən sonra verilənlər elektrik kəsilsə də qalır | əvvəlcədən yazılan jurnal (WAL) |
BEGIN;
UPDATE products SET stock = stock - 2 WHERE name = 'Laptop';
INSERT INTO orders (customer_id, product_id, quantity, order_date)
VALUES (2, 1, 2, '2025-08-01');
ROLLBACK;
SELECT name, stock,
(SELECT COUNT(*) FROM orders) AS orders_total
FROM products
WHERE name = 'Laptop';▸ Gözlənilən nəticə
name | stock | orders_total Laptop | 8 | 12
ROLLBACK). Nəticədə hər iki dəyişiklik yoxa çıxdı: ehtiyat yenə 8, sifarişlər yenə 12-dir. COMMIT yazsaydıq, ikisi də birlikdə saxlanardı.Tam təcridolunma bahalıdır, ona görə SQL dörd təcrid səviyyəsi təklif edir. READ UNCOMMITTED-də «çirkli oxu» (başqasının hələ təsdiqlənməmiş dəyişikliyini görmək), READ COMMITTED-də «təkrarlanmayan oxu» (eyni sətir iki oxuda fərqli), REPEATABLE READ-də «fantomlar» (yeni sətirlərin peyda olması) mümkündür; SERIALIZABLE isə tranzaksiyaların ardıcıl icrası ilə eyni nəticəni təmin edir.
İndekslər, SQL və NoSQL
- hB-ağacı indeksinin hündürlüyü (axtarışda oxunan səhifələr)
- Ncədvəldəki sətirlərin sayı
- fbudaqlanma: bir səhifəyə sığan açarların sayı
Cədvəldə N = 10⁷ sətir var, bir disk səhifəsinə 100 sətir sığır. WHERE email = … sorğusu üçün indekssiz və f = 100 olan B-ağacı indeksi ilə neçə səhifə oxunur?
Həllini göstərHəllini gizlət
İndekslə: h = ⌈log 10⁷ / log 100⌉ = ⌈7/2⌉ = ⌈3,5⌉ = 4 səviyyə + 1 səhifə sətrin özü = ≈ 5 səhifə.
Qazanc ≈ 20 000 dəfə: O(N) əvəzinə O(log N). Bədəli: indeks yer tutur və hər INSERT/UPDATE onu da yeniləməlidir.
| Meyar | SQL (relyasiya) | NoSQL |
|---|---|---|
| model | cədvəllər və əlaqələr | sənəd, açar–qiymət, sütun ailələri, qraf |
| sxem | sərt, əvvəlcədən müəyyən | çevik |
| tranzaksiyalar | tam ACID | çox vaxt məhdud, «sonda uyğunluq» |
| miqyaslanma | əsasən şaquli (güclü server) | üfüqi (çoxlu server) |
| nümunələr | PostgreSQL, MySQL, SQLite, SQL Server | MongoDB, Redis, Cassandra, Neo4j |
Əsas fikirlər
- Münasibət — kortejlər çoxluğudur; namizəd açar minimal superaçardır, ilkin açar unikal və NOT NULL-dur, xarici açar bütövlüyü qoruyur.
- 1NF — atomar qiymətlər; 2NF — qismən asılılıq yoxdur; 3NF — tranzitiv asılılıq yoxdur.
- Normallaşdırma yeniləmə, əlavə və silmə anomaliyalarını aradan qaldırır.
- ACID: atomarlıq, uyğunluq, təcridolunma, davamlılıq; ROLLBACK tranzaksiyanı tam ləğv edir.
- B-ağacı indeksi axtarışı O(N)-dən O(log N)-ə endirir, amma yazmanı yavaşladır.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.
grades(student_id, course_id, student_name, score), açar (student_id, course_id), student_id → student_name. Cədvəl hansı normal formanı pozur?