Verilənlər bazasında yazmaq və oxumaq balanslaşdırılması

Verilənlər bazasında yazmaq və oxumaq balanslaşdırılması
Əvvəlkidə məqalə Relational verilənlər bazalarında olduğu kimi cədvəllər və sahələr deyil, funksiyalar əsasında qurulmuş verilənlər bazası konsepsiyası və tətbiqini təsvir etdim. Bu yanaşmanın klassikdən üstünlüyünü göstərən çoxlu nümunələr təqdim etdi. Çoxları onların kifayət qədər inandırıcı olmadığını gördü.

Bu yazıda mən bu konsepsiyanın əməliyyat məntiqində heç bir dəyişiklik etmədən verilənlər bazasına yazmaq və oxumağı tez və rahat şəkildə balanslaşdırmağa necə imkan verdiyini göstərəcəyəm. Oxşar funksionallıq müasir kommersiya DBMS-lərində (xüsusilə, Oracle və Microsoft SQL Server) həyata keçirilməyə cəhd edilmişdir. Məqalənin sonunda göstərəcəyəm ki, onların etdikləri, yumşaq desək, heç də yaxşı nəticə vermədi.

Təsvir

Əvvəlki kimi, daha yaxşı başa düşmək üçün təsvirə nümunələrlə başlayacağam. Deyək ki, işçilərin sayı və ümumi əmək haqqı ilə şöbələrin siyahısını qaytaracaq məntiqi həyata keçirməliyik.

Funksional verilənlər bazasında bu belə görünür:

CLASS Department ‘Отдел’;
name ‘Наименование’ = DATA STRING[100] (Department);

CLASS Employee ‘Сотрудник’;
department ‘Отдел’ = DATA Department (Employee);
salary ‘Зарплата’ =  DATA NUMERIC[10,2] (Employee);

countEmployees ‘Кол-во сотрудников’ (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
salarySum ‘Суммарная зарплата’ (Department d) = 
    GROUP SUM salary(Employee e) IF department(e) = d;

SELECT name(Department d), countEmployees(d), salarySum(d);

İstənilən DBMS-də bu sorğunun icrasının mürəkkəbliyi buna bərabər olacaqdır O (işçilərin sayı)çünki bu hesablama işçilərin bütün cədvəlini skan etmək və sonra onları şöbələr üzrə qruplaşdırmaq tələb edir. Seçilmiş plandan asılı olaraq kiçik (departamentlərdən daha çox işçinin olduğuna inanırıq) əlavələr də olacaq. O (işçilərin jurnal sayı) və ya O (departamentlərin sayı) qruplaşdırmaq üçün və s.

Aydındır ki, icra yükü müxtəlif DBMS-lərdə fərqli ola bilər, lakin mürəkkəblik heç bir şəkildə dəyişməyəcək.

Təklif olunan tətbiqdə, funksional DBMS şöbə üçün tələb olunan dəyərləri hesablayacaq bir alt sorğu yaradacaq və sonra adı əldə etmək üçün şöbə cədvəli ilə QOŞULUN. Bununla belə, hər bir funksiya üçün, elan edərkən, xüsusi MATERİALİZƏMİŞ marker təyin etmək mümkündür. Sistem avtomatik olaraq hər bir belə funksiya üçün müvafiq sahə yaradacaq. Bir funksiyanın dəyərini dəyişdirərkən, sahənin dəyəri də eyni əməliyyatda dəyişəcəkdir. Bu funksiyaya daxil olduqda, əvvəlcədən hesablanmış sahəyə daxil olacaqsınız.

Xüsusilə, əgər siz funksiyalar üçün MATERIALIZED təyin etsəniz İşçilərin sayı и əmək haqqı məbləği, sonra işçilərin sayını və onların ümumi əmək haqqını saxlayacaq şöbələrin siyahısı ilə cədvələ iki sahə əlavə olunacaq. İşçilərdə, onların maaşlarında və ya şöbə mənsubiyyətlərində dəyişiklik olduqda, sistem avtomatik olaraq bu sahələrin dəyərlərini dəyişəcək. Yuxarıdakı sorğu birbaşa bu sahələrə daxil olacaq və burada icra ediləcək O (departamentlərin sayı).

Məhdudiyyətlər hansılardır? Yalnız bir şey: belə bir funksiyanın dəyərinin müəyyən edildiyi sonlu sayda giriş dəyəri olmalıdır. Əks halda, sonsuz sayda cərgədən ibarət cədvəl ola bilməyəcəyi üçün bütün dəyərlərini saxlayan cədvəl qurmaq mümkün olmayacaq.

Misal:

employeesCount ‘Количество сотрудников с зарплатой > N’ (Department d, NUMERIC[10,2] N) = 
    GROUP SUM salary(Employee e) IF department(e) = d AND salary(e) > N;

Bu funksiya sonsuz sayda N dəyəri üçün müəyyən edilmişdir (məsələn, hər hansı bir mənfi dəyər uyğundur). Ona görə də üzərinə MATERİALİZƏLƏRİ qoya bilməzsiniz. Deməli, bu məntiqi məhdudiyyətdir, texniki deyil (yəni onu həyata keçirə bilmədiyimiz üçün deyil). Əks halda, heç bir məhdudiyyət yoxdur. Siz qruplaşdırma, çeşidləmə, AND və OR, PARTITION, rekursiya və s. istifadə edə bilərsiniz.

Məsələn, əvvəlki məqalənin 2.2-ci məsələsində siz hər iki funksiyaya MATERIALIZED qoya bilərsiniz:

bought 'Купил' (Customer c, Product p, INTEGER y) = 
    GROUP SUM sum(Detail d) IF 
        customer(order(d)) = c AND 
        product(d) = p AND 
        extractYear(date(order(d))) = y MATERIALIZED;
rating 'Рейтинг' (Customer c, Product p, INTEGER y) = 
    PARTITION SUM 1 ORDER DESC bought(c, p, y), p BY c, y MATERIALIZED;
SELECT contactName(Customer c), name(Product p) WHERE rating(c, p, 1997) < 3;

Sistem özü tip düymələri ilə bir cədvəl yaradacaq Müştəri, məhsul и İNTEGER, ona iki sahə əlavə edəcək və onlarda olan sahə dəyərlərini istənilən dəyişikliklə yeniləyəcək. Bu funksiyalara əlavə zənglər edildikdə, onlar hesablanmayacaq, əksinə dəyərlər müvafiq sahələrdən oxunacaq.

Bu mexanizmdən istifadə edərək, məsələn, sorğularda rekursiyalardan (CTE) xilas ola bilərsiniz. Xüsusilə, uşaq/valideyn münasibətindən istifadə edərək ağac meydana gətirən qrupları nəzərdən keçirin (hər qrupun öz valideyni ilə əlaqəsi var):

parent = DATA Group (Group);

Funksional verilənlər bazasında rekursiya məntiqi aşağıdakı kimi göstərilə bilər:

level (Group child, Group parent) = RECURSION 1l IF child IS Group AND parent == child
                                                             STEP 2l IF parent == parent($parent);
isParent (Group child, Group parent) = TRUE IF level(child, parent) MATERIALIZED;

Çünki funksiya üçün valideyndir MATERİALİZDƏ qeyd olunur, sonra onun üçün iki açar (qrup) olan bir cədvəl yaradılacaq, bu sahədə sahə valideyndir yalnız birinci açar ikincinin uşağı olarsa doğru olacaq. Bu cədvəldəki girişlərin sayı ağacın orta dərinliyinə vurulan qrupların sayına bərabər olacaqdır. Məsələn, müəyyən bir qrupun nəsillərinin sayını hesablamaq lazımdırsa, bu funksiyadan istifadə edə bilərsiniz:

childrenCount (Group g) = GROUP SUM 1 IF isParent(Group child, g);

SQL sorğusunda CTE olmayacaq. Bunun əvəzinə sadə bir GROUP BY olacaq.

Bu mexanizmdən istifadə edərək, zəruri hallarda verilənlər bazasını asanlıqla denormallaşdıra bilərsiniz:

CLASS Order 'Заказ';
date 'Дата' = DATA DATE (Order);

CLASS OrderDetail 'Строка заказа';
order 'Заказ' = DATA Order (OrderDetail);
date 'Дата' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;

Funksiyanı çağırarkən tarix sifariş xətti üçün indeksin olduğu sahə sifariş xətləri ilə cədvəldən oxunacaq. Sifariş tarixi dəyişdikdə, sistem özü avtomatik olaraq xəttdəki normallaşdırılmamış tarixi yenidən hesablayacaq.

Üstünlükləri

Bütün bu mexanizm nə üçündür? Klassik DBMS-lərdə sorğuları yenidən yazmadan tərtibatçı və ya DBA yalnız indeksləri dəyişdirə, statistik məlumatları müəyyən edə və sorğu planlayıcısına onları necə yerinə yetirəcəyini söyləyə bilər (və İPUCU yalnız kommersiya DBMS-lərində mövcuddur). Nə qədər çalışsalar da, məqalədəki ilk sorğunu tamamlaya bilməyəcəklər O (departamentlərin sayı) sorğuları dəyişdirmədən və ya tetikleyiciler əlavə etmədən. Təklif olunan sxemdə, inkişaf mərhələsində məlumatların saxlanması strukturu və hansı birləşmələrdən istifadə etmək barədə düşünmək lazım deyil. Bütün bunlar tez, birbaşa əməliyyatda asanlıqla dəyişdirilə bilər.

Praktikada belə görünür. Bəzi insanlar birbaşa tapşırığa əsaslanaraq məntiqi inkişaf etdirirlər. Onlar alqoritmləri və onların mürəkkəbliyini, nə icra planlarını, nə birləşmə növlərini, nə də başqa texniki komponentləri başa düşmürlər. Bu insanlar tərtibatçılardan daha çox biznes analitikləridir. Sonra bütün bunlar sınaq və ya əməliyyata keçir. Uzun müddət davam edən sorğuları qeyd etməyə imkan verir. Uzun sorğu aşkar edildikdə, digər insanlar (daha texniki - mahiyyətcə DBA) bəzi ara funksiyalarda MATERİALİZƏLƏMƏni aktivləşdirməyə qərar verirlər. Bu, qeydi bir az ləngidir (çünki bu, əməliyyatda əlavə sahənin yenilənməsini tələb edir). Bununla belə, təkcə bu sorğu deyil, həm də bu funksiyadan istifadə edən bütün digər sorğular da əhəmiyyətli dərəcədə sürətlənir. Eyni zamanda, hansı funksiyanın həyata keçiriləcəyinə qərar vermək nisbətən asandır. İki əsas parametr: mümkün giriş dəyərlərinin sayı (müvafiq cədvəldə nə qədər qeyd olacaq) və digər funksiyalarda nə qədər tez-tez istifadə olunur.

Analoglar

Müasir kommersiya DBMS-lərinin oxşar mexanizmləri var: FAST REFRESH (Oracle) və INDEXED VIEW (Microsoft SQL Server). PostgreSQL-də MATERİALIZA GÖRÜNÜŞ əməliyyatda yenilənə bilməz, ancaq sorğu əsasında (və hətta çox ciddi məhdudiyyətlərlə) buna görə də biz bunu nəzərə almırıq. Lakin onların istifadəsini əhəmiyyətli dərəcədə məhdudlaşdıran bir sıra problemlər var.

Birincisi, siz yalnız adi GÖRÜNÜŞ yaratmısınızsa, maddiləşdirməni aktivləşdirə bilərsiniz. Əks halda, bu materiallaşmadan istifadə etmək üçün yeni yaradılmış görünüşə daxil olmaq üçün qalan sorğuları yenidən yazmalı olacaqsınız. Və ya hər şeyi olduğu kimi buraxın, lakin əvvəlcədən hesablanmış müəyyən məlumatlar varsa, ən azı səmərəsiz olacaq, lakin bir çox sorğular həmişə ondan istifadə etmir, lakin onu yenidən hesablayır.

İkincisi, onların çoxlu sayda məhdudiyyətləri var:

Kahin

5.3.8.4 Tez Yeniləmə üzrə Ümumi Məhdudiyyətlər

Materiallaşdırılmış görünüşün müəyyənedici sorğusu aşağıdakı kimi məhdudlaşdırılır:

  • Maddiləşdirilmiş görünüş kimi təkrar olunmayan ifadələrə istinadlar ehtiva etməməlidir SYSDATEROWNUM.
  • Materiallaşdırılmış görünüşdə istinadlar olmamalıdır RAW or LONG RAW məlumat növləri.
  • O ehtiva edə bilməz a SELECT siyahı alt sorğu.
  • O, analitik funksiyaları ehtiva edə bilməz (məsələn, RANK) içində SELECT bənd.
  • Bu cədvələ istinad edə bilməz XMLIndex indeksi müəyyən edilir.
  • O ehtiva edə bilməz a MODEL bənd.
  • O ehtiva edə bilməz a HAVING alt sorğu ilə bənd.
  • O, iç-içə sorğuları ehtiva edə bilməz ANY, ALLvə ya NOT EXISTS.
  • O ehtiva edə bilməz a [START WITH …] CONNECT BY bənd.
  • O, müxtəlif saytlarda çoxlu təfərrüatlı cədvəllərdən ibarət ola bilməz.
  • ON COMMIT maddiləşdirilmiş görünüşlərdə uzaq detal cədvəlləri ola bilməz.
  • İç-içə materiallaşdırılmış görünüşlərdə birləşmə və ya ümumi olmalıdır.
  • Materiallaşdırılmış birləşmə görünüşləri və a ilə materiallaşdırılmış ümumi görünüşlər GROUP BY bənd indekslə təşkil edilmiş cədvəldən seçə bilməz.

5.3.8.5 Yalnız Qoşulmaqla Materiallaşdırılmış Baxışlarda Tez Yeniləmə üzrə məhdudiyyətlər

Yalnız birləşmələrlə və heç bir aqreqat olmayan materiallaşdırılmış görünüşlər üçün sorğuların təyin edilməsi sürətli yeniləmə ilə bağlı aşağıdakı məhdudiyyətlərə malikdir:

  • Bütün məhdudiyyətlər «Tez Yeniləmə üzrə Ümumi Məhdudiyyətlər".
  • Onlar ola bilməz GROUP BY bəndlər və ya aqreqatlar.
  • Bütün cədvəllərin cərgələri FROM siyahısında görünməlidir SELECT sorğunun siyahısı.
  • Materiallaşdırılmış görünüş jurnalları bütün əsas cədvəllər üçün sətirlərlə mövcud olmalıdır FROM sorğunun siyahısı.
  • Obyekt növü sütununu daxil edən sadə birləşmələri olan bir neçə cədvəldən tez yenilənə bilən materiallaşdırılmış görünüş yarada bilməzsiniz. SELECT bəyanat.

Həmçinin, seçdiyiniz yeniləmə metodu aşağıdakı hallarda optimal şəkildə effektiv olmayacaq:

  • Müəyyənedici sorğu daxili birləşmə kimi davranan xarici birləşmədən istifadə edir. Əgər müəyyənedici sorğuda belə birləşmə varsa, daxili birləşməni ehtiva etmək üçün müəyyənedici sorğunu yenidən yazmağı düşünün.
  • The SELECT materiallaşdırılmış görünüşün siyahısı çoxlu cədvəllərin sütunlarında ifadələrdən ibarətdir.

5.3.8.6 Aqreqatlarla Materiallaşdırılmış Görünüşlərdə Tez Yeniləmə üzrə məhdudiyyətlər

Aqreqatlar və ya birləşmələrlə maddiləşdirilmiş görünüşlər üçün sorğuların müəyyən edilməsi sürətli yeniləmə ilə bağlı aşağıdakı məhdudiyyətlərə malikdir:

Sürətli yeniləmə hər ikisi üçün dəstəklənir ON COMMITON DEMAND maddiləşdirilmiş fikirlər, lakin aşağıdakı məhdudiyyətlər tətbiq olunur:

  • Materiallaşdırılmış görünüşdəki bütün cədvəllərdə maddiləşdirilmiş baxış jurnalları olmalıdır və materiallaşdırılmış görünüş jurnalları:
    • Materiallaşdırılmış görünüşdə istinad edilən cədvəldəki bütün sütunları ehtiva edir.
    • ilə müəyyən edin ROWIDINCLUDING NEW VALUES.
    • dəqiqləşdirmək SEQUENCE Cədvəlin əlavələr/birbaşa yükləmələr, silmələr və yeniləmələr qarışığına malik olacağı gözlənilirsə.

  • Yalnız SUM, COUNT, AVG, STDDEV, VARIANCE, MINMAX sürətli yeniləmə üçün dəstəklənir.
  • COUNT(*) müəyyən edilməlidir.
  • Ümumi funksiyalar yalnız ifadənin ən kənar hissəsi kimi baş verməlidir. Yəni, kimi aqreqatlar AVG(AVG(x)) or AVG(x)+ AVG(x) icazə verilmir.
  • kimi hər bir aqreqat üçün AVG(expr), müvafiq COUNT(expr) mövcud olmalıdır. Oracle bunu tövsiyə edir SUM(expr) dəqiqləşdirilməlidir.
  • If VARIANCE(expr) or STDDEV(expr) müəyyən edilir, COUNT(expr)SUM(expr) müəyyən edilməlidir. Oracle bunu tövsiyə edir SUM(expr *expr) dəqiqləşdirilməlidir.
  • The SELECT müəyyənedici sorğuda sütun birdən çox əsas cədvəldən sütunları olan mürəkkəb ifadə ola bilməz. Bunun mümkün həlli daxili materiallaşdırılmış görünüşdən istifadə etməkdir.
  • The SELECT siyahı hamısını ehtiva etməlidir GROUP BY sütunlar.
  • Maddiləşdirilmiş görünüş bir və ya bir neçə uzaq cədvələ əsaslanmır.
  • Bir istifadə edirsinizsə CHAR materiallaşdırılmış görünüş jurnalının filtr sütunlarındakı məlumat növü, əsas saytın simvol dəstləri və materiallaşdırılmış görünüş eyni olmalıdır.
  • Materiallaşdırılmış görünüş aşağıdakılardan birinə malikdirsə, sürətli yeniləmə yalnız adi DML əlavələrində və birbaşa yüklərdə dəstəklənir.
    • ilə maddiləşdirilmiş baxışlar MIN or MAX aqreqatlar
    • Maddiləşdirilmiş baxışları olan SUM(expr) amma yox COUNT(expr)
    • olmadan maddiləşdirilmiş baxışlar COUNT(*)

    Belə maddiləşdirilmiş görünüşə yalnız əlavə edilən materiallaşdırılmış görünüş deyilir.

  • ilə maddiləşdirilmiş görünüş MAX or MIN sildikdən və ya qarışıq DML ifadələrindən sonra tez yenilənir WHERE bənd.
    Silindikdən və ya qarışıq DML-dən sonra maks/dəq sürətli yeniləmə yalnız daxiletmə halı ilə eyni davranışa malik deyil. Təsirə məruz qalan qruplar üçün maksimum/min dəyərlərini silir və yenidən hesablayır. Onun performans təsirindən xəbərdar olmalısınız.
  • Adlandırılmış görünüşlər və ya alt sorğularla materiallaşdırılmış görünüşlər FROM Baxışlar tamamilə birləşdirilə bilsə, bənd tez yenilənə bilər. Hansı görünüşlərin birləşdiriləcəyi haqqında məlumat üçün baxın Oracle Database SQL Language Reference.
  • Xarici birləşmələr yoxdursa, ixtiyari seçimlər və birləşmələr ola bilər WHERE bənd.
  • Xarici birləşmələrlə materiallaşdırılmış məcmu görünüşlər adi DML və birbaşa yüklərdən sonra yalnız xarici cədvəl dəyişdirildikdə tez yenilənir. Həmçinin, daxili birləşmə cədvəlinin birləşmə sütunlarında unikal məhdudiyyətlər mövcud olmalıdır. Xarici birləşmələr varsa, bütün birləşmələr ilə birləşdirilməlidir ANDs və bərabərlikdən istifadə etməlidir (=) operator.
  • İlə maddiləşdirilmiş görünüşlər üçün CUBE, ROLLUP, qruplaşdırma dəstləri və ya onların birləşdirilməsi üçün aşağıdakı məhdudiyyətlər tətbiq olunur:
    • The SELECT siyahıda a ola bilən qruplaşdırma fərqləndiricisi olmalıdır GROUPING_ID hamısında funksiya GROUP BY ifadələr və ya GROUPING hər biri üçün bir funksiya yerinə yetirir GROUP BY ifadə. Məsələn, əgər GROUP BY maddiləşdirilmiş görünüşün bəndi "GROUP BY CUBE(a, b)", sonra SELECT siyahıda hər ikisi olmalıdır"GROUPING_ID(a, b)» və ya «GROUPING(a) AND GROUPING(b)» materiallaşdırılmış görünüşün tez təzələnə bilməsi üçün.
    • GROUP BY heç bir təkrar qruplaşma ilə nəticələnməməlidir. Misal üçün, "GROUP BY a, ROLLUP(a, b)"tez təzələnə bilməz, çünki bu, təkrar qruplaşmalara səbəb olur"(a), (a, b), AND (a)".

5.3.8.7 UNION ALL ilə Materiallaşdırılmış Baxışlarda Tez Yeniləmə üzrə məhdudiyyətlər

ilə materiallaşdırılmış görünüşlər UNION ALL operator dəstəyini təyin edin REFRESH FAST aşağıdakı şərtlər yerinə yetirildikdə seçim:

  • Müəyyənedici sorğuda olmalıdır UNION ALL yüksək səviyyədə operator.

    The UNION ALL operator bir istisna olmaqla, alt sorğunun içərisinə daxil edilə bilməz: The UNION ALL -də alt sorğuda ola bilər FROM şərtlə ki, müəyyənedici sorğu formada olsun SELECT * FROM (baxın və ya alt sorğu ilə UNION ALL) aşağıdakı nümunədə olduğu kimi:

    CREATE VIEW_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM müştərilər c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM müştərilər c WHERE c.cust = "Cons"); MADDİYYƏTLİ GÖRÜNÜŞ YARADIN unionall_inside_view_mv SEÇİLƏK KİMİ TƏLƏB ÜZƏRƏ TEZLİK TƏZİL EDİN * FROM view_with_unionall;
    

    Qeyd edək ki, görünüşü view_with_unionall sürətli yeniləmə tələblərinə cavab verir.

  • Hər bir sorğu blokunda UNION ALL sorğu aqreqatlarla tez yenilənə bilən maddiləşdirilmiş görünüş və ya birləşmələrlə tez təzələnən materiallaşdırılmış görünüş tələblərinə cavab verməlidir.

    Cədvəllərdə müvafiq materiallaşdırılmış görünüş jurnalları, tez yenilənən materiallaşdırılmış görünüşün müvafiq növü üçün tələb olunduğu kimi yaradılmalıdır.
    Qeyd edək ki, Oracle Verilənlər Bazası yalnız təmin edilən birləşmələrlə tək cədvəlin materiallaşdırılmış görünüşünün xüsusi halına imkan verir ROWID sütununa daxil edilmişdir SELECT siyahıda və materiallaşdırılmış görünüş jurnalında. Bu, görünüşün müəyyənedici sorğusunda göstərilir view_with_unionall.

  • The SELECT hər sorğunun siyahısına a daxil edilməlidir UNION ALL marker və UNION ALL sütunun hər birində fərqli sabit ədədi və ya sətir dəyəri olmalıdır UNION ALL filialı. Bundan əlavə, marker sütunu eyni sıra mövqeyində görünməlidir SELECT hər bir sorğu blokunun siyahısı. Görmək "UNION ALL Marker və Sorğunu Yenidən Yazın» haqqında ətraflı məlumat üçün UNION ALL markerlər.
  • Xarici birləşmələr, yalnız daxil etmək üçün ümumiləşdirilmiş materiallaşdırılmış görünüş sorğuları və uzaq cədvəllər kimi bəzi xüsusiyyətlər materiallaşdırılmış görünüşlər üçün dəstəklənmir. UNION ALL. Bununla belə, qeyd edin ki, replikasiyada istifadə olunan, birləşmələr və ya aqreqatlar olmayan materiallaşdırılmış görünüşlər bu zaman tez yenilənə bilər. UNION ALL və ya uzaq masalardan istifadə edilir.
  • Uyğunluğun başlanğıc parametri 9.2.0 və ya daha yüksək səviyyəyə təyin edilməlidir. UNION ALL.

Oracle pərəstişkarlarını incitmək istəmirəm, lakin onların məhdudiyyətlər siyahısına əsasən, görünür, bu mexanizm ümumi vəziyyətdə deyil, bir növ modeldən istifadə edərək, minlərlə hindli tərəfindən yazılmışdır, burada hər kəsə imkan verilmişdir. öz dalını yazın və hər biri bacardığını etdi və etdi. Bu mexanizmdən həqiqi məntiq üçün istifadə etmək mina tarlasında gəzməyə bənzəyir. Qeyri-aşkar məhdudiyyətlərdən birini vurmaqla istənilən vaxt mina əldə edə bilərsiniz. Bunun necə işlədiyi də ayrı bir sualdır, lakin bu məqalənin əhatə dairəsi xaricindədir.

Microsoft SQL Server

Əlavə tələblər

SET variantları və deterministik funksiya tələblərinə əlavə olaraq, aşağıdakı tələblər yerinə yetirilməlidir:

  • İcra edən istifadəçi CREATE INDEX mənzərənin sahibi olmalıdır.
  • İndeksi yaratdığınız zaman IGNORE_DUP_KEY seçim OFF (standart parametr) vəziyyətinə qoyulmalıdır.
  • Cədvəllər iki hissəli adlarla istinad edilməlidir, sxem.masa adı görünüş tərifində.
  • Görünüşdə istinad edilən istifadəçi tərəfindən müəyyən edilmiş funksiyalar istifadə edərək yaradılmalıdır WITH SCHEMABINDING seçin.
  • Görünüşdə istinad edilən istənilən istifadəçi tərəfindən müəyyən edilmiş funksiyalar iki hissəli adlarla istinad edilməlidir, ..
  • İstifadəçi tərəfindən müəyyən edilmiş funksiyanın verilənlərə çıxış xüsusiyyəti olmalıdır NO SQL, və xarici giriş xüsusiyyəti olmalıdır NO.
  • Ümumi dil işləmə vaxtı (CLR) funksiyaları görünüşün seçilmiş siyahısında görünə bilər, lakin qruplaşdırılmış indeks açarının tərifinin bir hissəsi ola bilməz. CLR funksiyaları görünüşün WHERE bəndində və ya görünüşdə JOIN əməliyyatının ON bəndində görünə bilməz.
  • Görünüş tərifində istifadə edilən CLR istifadəçi tərəfindən müəyyən edilmiş növlərin CLR funksiyaları və metodları aşağıdakı cədvəldə göstərildiyi kimi təyin edilmiş xüsusiyyətlərə malik olmalıdır.

    Əmlak
    Qeyd

    DETERMİNİSTİK = DOĞRU
    Microsoft .NET Framework metodunun atributu kimi açıq şəkildə elan edilməlidir.

    DƏqiq = DOĞRU
    .NET Framework metodunun atributu kimi açıq şəkildə elan edilməlidir.

    DATA ACCESS = SQL YOXDUR
    DataAccess atributunu DataAccessKind.None və SystemDataAccess atributunu SystemDataAccessKind.None olaraq təyin etməklə müəyyən edilir.

    XARİCİ GİRİŞ = NO
    Bu xüsusiyyət CLR rutinləri üçün defolt olaraq NO-dur.

  • Görünüş istifadə edərək yaradılmalıdır WITH SCHEMABINDING seçin.
  • Görünüş yalnız görünüşlə eyni verilənlər bazasında olan əsas cədvəllərə istinad etməlidir. Görünüş digər baxışlara istinad edə bilməz.
  • Görünüş tərifindəki SELECT ifadəsi aşağıdakı Transact-SQL elementlərini ehtiva etməməlidir:

    COUNT
    ROWSET funksiyaları (OPENDATASOURCE, OPENQUERY, OPENROWSET, Və OPENXML)
    OUTER qoşulur(LEFT, RIGHTvə ya FULL)

    Törəmə cədvəli (a. işarəsi ilə müəyyən edilir SELECT ifadəsi FROM bənd)
    Öz-özünə qoşulur
    İstifadə edərək sütunların təyin edilməsi SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPvə ya AVG
    Ümumi cədvəl ifadəsi (CTE)

    axıtma1, mətn, ntext, təsvir, XMLvə ya fayl axını sütunları
    Alt sorğu
    OVER sıralama və ya ümumi pəncərə funksiyalarını ehtiva edən bənd

    Tam mətn predikatları (CONTAINS, FREETEXT)
    SUM null edilə bilən ifadəyə istinad edən funksiya
    ORDER BY

    CLR istifadəçi tərəfindən müəyyən edilmiş məcmu funksiya
    TOP
    CUBE, ROLLUPvə ya GROUPING SETS operatorları

    MIN, MAX
    UNION, EXCEPTvə ya INTERSECT operatorları
    TABLESAMPLE

    Cədvəl dəyişənləri
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Seyrək sütun dəstləri
    Daxili (TVF) və ya çox ifadəli cədvəl dəyərli funksiyalar (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 İndekslənmiş görünüşdə ola bilər axıtma sütunlar; lakin belə sütunlar klasterləşdirilmiş indeks açarına daxil edilə bilməz.

  • If GROUP BY varsa, VIEW tərifi olmalıdır COUNT_BIG(*) və ehtiva etməməlidir HAVING. Bu GROUP BY məhdudiyyətlər yalnız indeksləşdirilmiş görünüş tərifinə şamil edilir. Sorğu, hətta bunları təmin etməsə belə, icra planında indeksləşdirilmiş görünüşdən istifadə edə bilər GROUP BY məhdudiyyətlər.
  • Görünüş tərifində a varsa GROUP BY bəndində, unikal çoxluq indeksinin açarı yalnız göstərilən sütunlara istinad edə bilər GROUP BY bənd.

Buradan aydın olur ki, hindlilər bu işə qarışmayıblar, çünki onlar bunu “az iş görəcəyik, amma yaxşı” sxeminə əsasən etmək qərarına gəliblər. Yəni, yataqda daha çox mina var, amma yerləşdikləri yer daha şəffafdır. Ən məyusedici şey bu məhdudiyyətdir:

Görünüş yalnız görünüşlə eyni verilənlər bazasında olan əsas cədvəllərə istinad etməlidir. Görünüş digər baxışlara istinad edə bilməz.

Terminologiyamızda bu o deməkdir ki, funksiya başqa bir maddiləşdirilmiş funksiyaya daxil ola bilməz. Bu, qönçədəki bütün ideologiyanı kəsir.
Həmçinin, bu məhdudiyyət (və daha sonra mətndə) istifadə hallarını xeyli azaldır:

Görünüş tərifindəki SELECT ifadəsi aşağıdakı Transact-SQL elementlərini ehtiva etməməlidir:

COUNT
ROWSET funksiyaları (OPENDATASOURCE, OPENQUERY, OPENROWSET, Və OPENXML)
OUTER qoşulur(LEFT, RIGHTvə ya FULL)

Törəmə cədvəli (a. işarəsi ilə müəyyən edilir SELECT ifadəsi FROM bənd)
Öz-özünə qoşulur
İstifadə edərək sütunların təyin edilməsi SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPvə ya AVG
Ümumi cədvəl ifadəsi (CTE)

axıtma1, mətn, ntext, təsvir, XMLvə ya fayl axını sütunları
Alt sorğu
OVER sıralama və ya ümumi pəncərə funksiyalarını ehtiva edən bənd

Tam mətn predikatları (CONTAINS, FREETEXT)
SUM null edilə bilən ifadəyə istinad edən funksiya
ORDER BY

CLR istifadəçi tərəfindən müəyyən edilmiş məcmu funksiya
TOP
CUBE, ROLLUPvə ya GROUPING SETS operatorları

MIN, MAX
UNION, EXCEPTvə ya INTERSECT operatorları
TABLESAMPLE

Cədvəl dəyişənləri
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Seyrək sütun dəstləri
Daxili (TVF) və ya çox ifadəli cədvəl dəyərli funksiyalar (MSTVF)
OFFSET

CHECKSUM_AGG

KARŞI QOŞULMALAR, BİRLİKLƏR, ORDER BY və başqaları qadağandır. Nəyin istifadə oluna bilməyəcəyini deyil, nəyin istifadə oluna biləcəyini müəyyən etmək daha asan ola bilərdi. Siyahı yəqin ki, daha qısa olardı.

Xülasə etmək üçün: LGPL texnologiyasında hər bir DBMS-də (kommersiyaya diqqət yetirək) heç biri ilə (texniki olmayan bir məntiqi istisna olmaqla) böyük məhdudiyyətlər dəsti. Bununla belə, qeyd etmək lazımdır ki, bu mexanizmin əlaqə məntiqində həyata keçirilməsi təsvir olunan funksional məntiqdən bir qədər çətindir.

Tətbiq

Bu necə işləyir? PostgreSQL “virtual maşın” kimi istifadə olunur. İçəridə sorğular quran mürəkkəb bir alqoritm var. Burada mənbə. Və yalnız bir dəstə ifs ilə evristikanın böyük dəsti yoxdur. Beləliklə, bir neçə ay təhsiliniz varsa, memarlığı anlamağa cəhd edə bilərsiniz.

Effektiv işləyirmi? Olduqca təsirli. Təəssüf ki, bunu sübut etmək çətindir. Yalnız onu deyə bilərəm ki, böyük tətbiqlərdə mövcud olan minlərlə sorğunu nəzərə alsanız, orta hesabla yaxşı bir tərtibatçıdan daha səmərəlidir. Mükəmməl SQL proqramçısı istənilən sorğunu daha səmərəli yaza bilər, lakin min sorğu ilə onun bunu etmək üçün sadəcə motivasiyası və vaxtı olmayacaq. İndi effektivliyin sübutu kimi qeyd edə biləcəyim yeganə şey, bu DBMS üzərində qurulmuş platformada bir neçə layihənin işləməsidir. ERP sistemləriminlərlə istifadəçisi və adi iki prosessorlu serverdə işləyən yüz milyonlarla qeydi olan terabayt verilənlər bazası ilə minlərlə müxtəlif MATERİALlaşdırılmış funksiyaları olan . Bununla belə, hər kəs yükləyərək effektivliyi yoxlaya/təkzib edə bilər bir platforma və PostgreSQL, işə salındı SQL sorğularını qeyd etmək və oradakı məntiqi və məlumatları dəyişdirməyə çalışmaq.

Növbəti məqalələrdə mən həmçinin funksiyalara necə məhdudiyyət qoya biləcəyiniz, dəyişiklik seansları ilə işləmək və daha çox şey haqqında danışacağam.

Mənbə: www.habr.com

Добавить комментарий