CodeGym /Kurslar /SQL SELF /Cədvəllər arasında ONE-TO-MANY əlaqəsinin m...

Cədvəllər arasında ONE-TO-MANY əlaqəsinin modelləşdirilməsi

SQL SELF
Səviyyə , Dərs
Mövcuddur

İndi gəlin bacarıqlarımızı bir az da inkişaf etdirək və relasional verilənlər bazalarında ən çox rast gəlinən əlaqələrdən birini - ONE-TO-MANY əlaqəsini quraq.

Təsəvvür elə ki, balaca bir şirkət var. Bir işçi yalnız bir şöbədə işləyə bilər, amma bir şöbədə onlarla işçi işləyə bilər. Bizim iki real obyektimiz var: işçilər və şöbələr. Onların arasındakı əlaqəni belə təsvir etmək olar: "bir şöbə bir çox işçini əhatə edə bilər", ya da rəsmi dildə "bir çoxa" (ONE-TO-MANY).

Elə bu cür ONE-TO-MANY münasibətləri hər yerdə var:

  • bir müştəri bir çox sifariş edə bilər;
  • bir müəllif bir çox kitab yaza bilər;
  • bir müəllim bir neçə tələbəyə dərs deyə bilər.

Realasional verilənlər bazasında ONE-TO-MANY əlaqəsi xarici açar (FOREIGN KEY) vasitəsilə qurulur. "Çox" (MANY) cədvəlinin sütunlarından biri "bir" (ONE) cədvəlinin əsas açarına işarə edir.

ONE-TO-MANY əlaqəsini necə qurmaq olar

Gəlin klassik nümunəyə baxaq: müştərilər və sifarişlər arasındakı əlaqə. Bir müştəri bir çox sifariş edə bilər, amma hər sifariş yalnız bir müştəriyə bağlıdır. İki cədvəl yaradacağıq: customers (müştərilər) və orders (sifarişlər).

customers cədvəli

Bu bizim "bir" cədvəlimizdir. Burada müştərilər haqqında məlumat saxlanacaq.

CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY, -- Müştərinin unikal identifikatoru
    name TEXT NOT NULL              -- Müştərinin adı
);

orders cədvəli

Bu "çox" cədvəldir. Burada sifarişlər saxlanılır və hər sifarişdə customer_id xarici açarı var, hansı ki, customers cədvəlindəki customer_id-ə işarə edir.

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,           -- Sifarişin unikal identifikatoru
    order_date DATE NOT NULL,              -- Sifariş tarixi
    customer_id INT REFERENCES customers(customer_id) -- Xarici açar
);

Praktiki tətbiq

Məlumatların daxil edilməsi

İndi cədvəllərimizə bir az məlumat əlavə edək və əlaqənin işlədiyini yoxlayaq.

customers cədvəlinə müştərilər əlavə edirik:

INSERT INTO customers (name)
VALUES
    ('Ada Lovelace'),
    ('Grace Hopper'),
    ('Linus Torvalds');

Nəticə:

customer_id name
1 Ada Lovelace
2 Grace Hopper
3 Linus Torvalds

orders cədvəlinə sifarişlər əlavə edirik:

INSERT INTO orders (order_date, customer_id)
VALUES
    ('2023-10-01', 1),  -- Ada-nın sifarişi
    ('2023-10-02', 2),  -- Grace-in sifarişi
    ('2023-10-03', 1);  -- Ada-nın daha bir sifarişi

orders cədvəli:

order_id order_date customer_id
1 2023-10-01 1
2 2023-10-02 2
3 2023-10-03 1

Diqqət et: sifariş əlavə edəndə mütləq mövcud customer_id göstərməlisən. Əgər mövcud olmayan ID yazsan, baza error atacaq. Bu, məlumatların bütövlüyünü qorumaq üçündür.

Əlaqənin yoxlanması

İndi baxaq, cədvəllərimiz necə əlaqəlidir. Məsələn, soruşaq: Ada Lovelace hansı sifarişləri edib?

SELECT orders.order_id, orders.order_date, customers.name
FROM orders
JOIN customers ON orders.customer_id = customers.customer_id
WHERE customers.name = 'Ada Lovelace';

Nəticə:

order_id order_date name
1 2023-10-01 Ada Lovelace
3 2023-10-03 Ada Lovelace

Burada JOIN əmri ilə iki cədvəli xarici açar əsasında birləşdirdik. Rahat, səliqəli və heç bir təkrarlanan məlumat yoxdur!

Niyə bu lazımdır

ONE-TO-MANY əlaqəsi real həyatda super yayğındır və çox faydalıdır. Təsəvvür elə, onlayn mağazadır, minlərlə müştəri və milyonlarla sifariş var. Hər sifarişdə müştəri məlumatını təkrarlamaq əvəzinə, unikal müştəriləri bir cədvəldə, sifarişləri isə başqa cədvəldə saxlayırıq. Bu, məlumatların həcmini azaldır və bazanı daha səliqəli edir.

Bundan əlavə, məlumatları əlaqələndirmək imkanımız olduqda, güclü analitik sorğular yaza bilərik. Məsələn, soruşa bilərik: "Hər müştəri neçə sifariş edib?" və ya "Son ay kimlər sifariş verib?".

Çətinliklər və tələlər

Yeni başlayanlar adətən bunlarda "yıxılır":

Xarici açarın olmaması. Əgər "çox" cədvəldə xarici açarı unutmusansa, əlaqə sadəcə başında olacaq, amma baza onu tətbiq edə bilməyəcək. Bu o deməkdir ki, "qırıq" baza ala bilərsən, yəni sifarişlər mövcud olmayan müştərilərə aid ola bilər.

"Bir" cədvəldən qeyd silmək cəhdi. Məsələn, customers cədvəlindən müştərini silsən, onun sifarişləri orders cədvəlində "asılı" qalacaq. Bunun qarşısını almaq üçün ON DELETE CASCADE istifadə edə bilərsən ki, müştəri silinəndə onun sifarişləri də avtomatik silinsin.

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    order_date DATE NOT NULL,
    customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE
);

İndi, əgər müştərini silsən:

DELETE FROM customers WHERE customer_id = 1;

Onun bütün sifarişləri də silinəcək. Baza təzə kofe kimi təmiz olacaq.

Məlumat daxil edərkən səhvlər. Əgər mövcud olmayan customer_id ilə sifariş əlavə etməyə çalışsan, belə bir error alacaqsan:

ERROR:  insert or update on table "orders" violates foreign key constraint
2
Tapşırıq
SQL SELF, səviyyə, dərs
Bağlanıb
`ONE-TO-MANY` əlaqəsi ilə cədvəllərin yaradılması
`ONE-TO-MANY` əlaqəsi ilə cədvəllərin yaradılması
2
Tapşırıq
SQL SELF, səviyyə, dərs
Bağlanıb
İşçilər və onların şöbələri haqqında məlumat almaq üçün cədvəllərin birləşdirilməsi
İşçilər və onların şöbələri haqqında məlumat almaq üçün cədvəllərin birləşdirilməsi
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION