Balancimi i regjistrimit dhe leximit në bazën e të dhënave

Balancimi i regjistrimit dhe leximit në bazën e të dhënave
Në artikulli ynë Unë e përshkrova konceptin dhe realizimin e një baze të dhënash të ndërtuar mbi funksione, jo mbi tabela dhe fusha si në bazat e të dhënave relacionale. Atëherë janë paraqitur shumë shembuj që tregojnë përparësitë e këtij qasje përball klasikes. Shumë e konsideruan këtë si jo mjaft bindëse.

Në këtë artikull do të tregoj se si një koncept i tillë lejon që të balancojmë shpejt dhe lehtësisht regjistrimin dhe leximin në një bazë të dhënash pa bërë ndonjë ndryshim në logjikën e funksionimit. Një funksionalitet i ngjashëm është përpjekur të realizohet në sistemet komerciale moderne të bazave të dhënash (sidomos, Oracle dhe Microsoft SQL Server). Në fund të artikullit do të tregoj se çfarë arritën ata, le të themi, jo shumë mirë.

Përshkrimi

Si dhe më parë, për një kuptim më të mirë do të filloj përshkrimin me shembuj. Supozoni se na nevojitet të realizojmë logjikën që do të kthejë një listë departamentesh me numrin e punonjësve në to dhe pagën e tyre totale.

Në bazën e dhënash funksionale kjo do të duket si më poshtë:

CLASS Department ‘Departamenti’;
name ‘Emri’ = DATA STRING[100] (Departamenti);

CLASS Employee 'Punonjësi';
department 'Departamenti' = DATA Department (Employee);
salary 'Paga' = DATA NUMERIC[10,2] (Employee);

countEmployees 'Numri i punonjësve' (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
salarySum 'Paga totale' (Department d) = 
    GROUP SUM salary(Employee e) IF department(e) = d;

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

Vështirësia e realizimit të këtij kërkese në çdo SGBD do të jetë e barabartë me O(numri i punonjësve), pasi për këtë llogaritje kërkohet të skanohet e gjithë tabela e punonjësve dhe pastaj të grupohen ata sipas departamentit. Do të ketë gjithashtu një shtesë të vogël (le të supozojmë se numri i punonjësve është shumë më i madh se numri i departamenteve) në varësi të planit të zgjedhur O(log numri i punonjësve) ose O(numri i departamenteve) për grupimin dhe të tjera.

ËshtĂ« e qartĂ« se shpenzimet pĂ«r realizimin mund tĂ« jenĂ« tĂ« ndryshme nĂ« SGBD tĂ« ndryshme, por vĂ«shtirĂ«sia nuk do tĂ« ndryshojĂ« aspak.

Në implementimin e propozuar, sistemi i menaxhimit të bazave të dhënash funksionale do të formojë një nënpyetje, e cila do të llogarisi vlerat e nevojshme për departamentin dhe më pas do të kryejë JOIN me tabelën e departamenteve për të marrë emrin. Megjithatë, për çdo funksion në shpallje ka mundësinë të caktohet një shenjë speciale MATERIALIZED. Sistemi automatikisht do të krijojë një fushë përkatëse për çdo funksion të tillë. Kur ndërron vlera funksioni, do të ndodhi njëkohësisht ndërrimi i vlerës së fushës në të njëjtën transaksion. Kur iu qaseni këtij funksioni, do të bëhet kërkesë për fushën e llogaritur tashmë.

Në veçanti, nëse vendosni MATERIALIZED për funksionet countEmployees dhe salarySum, tabelës me listën e departamenteve do t'i shtohen dy fusha, në të cilat do të ruhen numri i punonjësve dhe paga e tyre totale. Në çdo ndryshim të punonjësve, pagave të tyre ose përkatësisë në departamente, sistemi do të ndryshojë automatikisht vlerat e këtyre fushave. Kërkesa e mëparshme do të bëhet në mënyrë të drejtpërdrejtë për këto fusha dhe do të realizohet për O(numri i departamenteve).

Cilat janë kufizimet? Vetëm një: ky funksion duhet të ketë një numër të caktuar hyrjesh, për të cilat vlera e tij është e përcaktuar. Ndryshe, nuk do të jetë e mundur të ndërtosh një tabelë që ruan të gjitha vlerat e saj, pasi nuk mund të ketë një tabelë me një numër të pafund rreshtash.

Shembulli:

numriPunonjĂ«sve ‘Numri i punonjĂ«sve me pagĂ« > N’ (Departamenti d, NUMERIC[10,2] N) = 
    GRUPI SUM pagĂ«n(PunonjĂ«si e) NËSE departamenti(e) = d DHE paga(e) > N;

Ky funksion Ă«shtĂ« i pĂ«rcaktuar pĂ«r njĂ« numĂ«r tĂ« pafund vlerash tĂ« numrit N (p.sh., çfarĂ«do vlerĂ« negative Ă«shtĂ« e pĂ«rshtatshme). Prandaj, mbi tĂ« nuk mund tĂ« vendosni MATERIALIZED. KĂ«shtu, kjo Ă«shtĂ« njĂ« kufizim logjik, dhe jo teknik (pra, jo sepse nuk e kemi realizuar). PĂ«r pjesĂ«n tjetĂ«r — nuk ka kufizime. Mund tĂ« pĂ«rdoren grupime, renditje, AND dhe OR, PARTITION, rekursione etj.

Për shembull, në detyrën 2.2 të artikullit të mëparshëm, mund të vendosni MATERIALIZED mbi të dy funksionet:

bleu 'Bleu' (Klienti c, Produkti p, INTEGER y) = 
    GRUPI SHUMË SUM(material d) NËSE 
        klienti(urdhër(d)) = c DHE 
        produkti(d) = p DHE 
        nxir vitin(data(urdhër(d))) = y MATERIALE;
vlerësimi 'Vlerësimi' (Klienti c, Produkti p, INTEGER y) = 
    PARTICIONI SUM 1 RENDITI ZBRITJE bleu(c, p, y), p PËR c, y MATERIALE;
ZGJOJ kontaktEmrin(Klienti c), emrin(Produkti p) KU vlerësimi(c, p, 1997) < 3;

Sistemi do të krijojë automatikisht një tabelë me çelësa tipash Klient, Produkti dhe INTEGER, do të shtojë dy fusha në të dhe do të përditësojë vlerat në to në çdo ndryshim. Në qasjet e mëtejshme në këto funksione, nuk do të ndodhin llogaritje, por do të lexohen vlerat nga fushat përkatëse.

Me këtë mekanizëm, është e mundur, për shembull, të hiqni nevojën për rekursione (CTE) në kërkesa. Në veçanti, le të shqyrtojmë grupet që formojnë një pemë përmes marrëdhënies child/parent (çdo grup ka një lidhje me prindin e tij):

prindi = GRUPA DATA (Grupi);

Në bazën e të dhënave funksionale, logjikën e rekursioneve mund ta përcaktoni si më poshtë:

nivel (FĂ«mijĂ« grupi, Prind grupi) = RIKURSION 1l NËSE fĂ«mija Ă«shtĂ« Grup dhe prindi == fĂ«mija
                                                             HAPI 2l NËSE prindi == prindi($prindi);
Ă«shtĂ«Prind (FĂ«mijĂ« grupi, Prind grupi) = E VERTET NËSE niveli(fĂ«mija, prindi) MATERIALIZUAR;

Duke qenë se për funksionin isParent është e vendosur MATERIALIZED, do të krijohet një tabelë me dy çelësa (grupe), në të cilën fusha isParent do të jetë e vërtetë vetëm nëse çelësi i parë është pasardhës i çelësit të dytë. Numri i regjistrimeve në këtë tabelë do të jetë i barabartë me numrin e grupeve, i shumëzuar me thellësinë mesatare të pemës. Nëse është e nevojshme, për shembull, të numërohet numri i pasardhësve të një grupi të caktuar, mund të përmendet ky funksion:

numriFĂ«mijĂ«ve (Grupi g) = GRUPI SUM 1 NËSE Ă«shtĂ«Prind(Grupi fĂ«mijĂ«, g);

Nuk do të ketë CTE në kërkesën SQL. Në vend të kësaj, do të ketë vetëm një GROUP BY të thjeshtë.

Me këtë mekanizëm, gjithashtu mund të bëni lehtësisht denormalizimin e bazës së të dhënave kur është e nevojshme:

KLASA Porosia 'Porosi';
data 'Data' = DATA DATE (Porosia);

CLASS OrderDetail 'Rreshti i porosisë';
order 'Porosi' = DATA Order (OrderDetail);
date 'Data' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;

Kur i referoheni funksionit date për rreshtin e porosisë do të bëhet leximi nga tabela me rreshtat e porosisë të fushës për të cilën ka një indeks. Kur ndryshohet data e porosisë, sistemi do ta rinovojë automatikisht datën denormalizuese në rresht.

Përfitimet

Për çfarë është i nevojshëm të gjithë ky mekanizëm? Në DB klasik, pa shkruar përsëri kërkesat, zhvilluesi ose DBA mund të ndryshojnë vetëm indekset, të përcaktojnë statistikat dhe të sugjerojnë planifikuesit të kërkesave se si t'i ekzekutojnë (për më tepër, HINT'ët ekzistojnë vetëm në DB komerciale). Sado që të përpiqen, ata nuk do të mund ta realizojnë kërkesën e parë në artikull për O (numri i departamenteve) pa modifikuar kërkesat dhe shtuar triggerat. Në skemën e propozuar, në fazën e zhvillimit nuk është e nevojshme të mendoni për strukturën e ruajtjes së të dhënave dhe për cilat agregacione të përdoren. Të gjithë këto mund të ndryshohen lehtësisht gjatë operimit.

Në praktikë, kjo duket kështu. Disa njerëz zhvillojnë logjikën direkt në bazë të detyrës së vendosur. Ata nuk kuptojnë aspak algoritmet dhe vështirësitë e tyre, as planet e ekzekutimit, as tipet e bashkimeve, asnjë aspekt tjetër teknik. Këta njerëz janë më shumë analistë biznesi sesa zhvillues. Më pas, gjithçka shkon për testim ose përdorim. Aktivizohet regjistrimi i kërkesave të gjata. Kur zbulohet një kërkesë e gjatë, një grup tjetër njerëzish (më teknikë - në thelb DBA) merr vendim për aktivizimin e MATERIALIZED në ndonjë funksion ndërmjetës. Kështu, shkrimi ngadalësohet pak (sepse kërkohet përditësimi i një fushe shtesë në transaksion). Megjithatë, jo vetëm që kjo kërkesë përshpejtohet, por edhe të gjitha kërkesat e tjera që përdorin këtë funksion. Në të njëjtën kohë, vendimi për cila funksion të materializohet merret relativisht lehtë. Dy parametra kryesorë: numri i vlerave të mundshme hyrëse (saktësisht kaq shumë regjistrime do të jenë në tabelën përkatëse), dhe sa shpesh përdoret ajo në funksione të tjera.

Analoge

Në sistemet moderne komerciale të menaxhimit të bazës së të dhënave, ka mekanizma të ngjashëm: MATERIALIZED VIEW me FAST REFRESH (Oracle) dhe INDEXED VIEW (Microsoft SQL Server). Në PostgreSQL, MATERIALIZED VIEW nuk mund të përditësohet në transaksion, por vetëm me kërkesë (dhe me kufizime të rrepta), prandaj nuk e shqyrtojmë. Por ata kanë disa probleme që e kufizojnë ndjeshëm përdorimin e tyre.

Së pari, materializimi mund të aktivizohet vetëm nëse keni krijuar më parë një VIEW të zakonshëm. Ndryshe, do t'ju duhet të rishkruani kërkesat e tjera për t'u drejtuar në pamjen e sapokrijuar për të përdorur këtë materializim. Ose ta lini gjithçka siç është, por do të jetë të paktën joefikas, nëse ka të dhëna të përcaktuara që janë tashmë të përllogaritura, ndërsa shumë kërkesa nuk i përdorin ato gjithmonë dhe i llogarisin nga fillimi.

Së dyti, ata kanë një numër të madh kufizimesh:

Oracle

5.3.8.4 Kufizimet e Përgjithshme për Shpejtësi të Ripërtëritjes

Kërkesa përcaktuese e pamjes së materializuar është e kufizuar si më poshtë:

  • Pamja e materializuar nuk duhet tĂ« pĂ«rmbajĂ« referenca nĂ« shprehje qĂ« nuk pĂ«rsĂ«riten si SYSDATE dhe ROWNUM.
  • Pamja e materializuar nuk duhet tĂ« pĂ«rmbajĂ« referenca nĂ« RAW or TIPET E DHËNAVE RAW .
  • Ajo nuk mund tĂ« pĂ«rmbajĂ« njĂ« SELECT nĂ«nkĂ«rkesĂ« liste.
  • Ajo nuk mund tĂ« pĂ«rmbajĂ« funksione analitike (pĂ«r shembuj, RANK) nĂ« SELECT klauzolĂ«n.
  • Ajo nuk mund tĂ« referohet njĂ« tabelĂ« mbi tĂ« cilĂ«n Ă«shtĂ« e caktuar njĂ« XMLIndex indeks.
  • Ajo nuk mund tĂ« pĂ«rmbajĂ« njĂ« MODEL klauzolĂ«n.
  • Ajo nuk mund tĂ« pĂ«rmbajĂ« njĂ« KLAUZOLË ME nĂ«nkĂ«rkesĂ«.
  • Ajo nuk mund tĂ« pĂ«rmbajĂ« kĂ«rkesa tĂ« ngjashme qĂ« kanĂ« ÇDO, TË GJITHA, ose NOT EKZISTON.
  • Ajo nuk mund tĂ« pĂ«rmbajĂ« njĂ« [START WITH 
] CONNECT BY klauzolĂ«n.
  • Nuk mund tĂ« pĂ«rmbajĂ« tabela tĂ« detajeve tĂ« shumta nĂ« vende tĂ« ndryshme.
  • PO KREJT Pamjet e materializuara nuk mund tĂ« kenĂ« tabela detajesh tĂ« largĂ«ta.
  • Pamjet e materializuara tĂ« pĂ«rfshira duhet tĂ« kenĂ« njĂ« bashkim ose pĂ«rmbledhje.
  • Pamjet e bashkimit tĂ« materializuara dhe pamjet e pĂ«rmbledhjes tĂ« materializuara me njĂ« GRUP ME klauzolĂ« nuk mund tĂ« zgjedhin nga njĂ« tabelĂ« tĂ« organizuar me index.

5.3.8.5 Kufizimet në Rrefreshin e Shpejtë në Pamje të Materializuara me Vetëm Bashkime

Këto qëllime për pamjet e materializuara me vetëm bashkime dhe pa përmbledhje kanë kufizime të mëposhtme në rrefreshin e shpejtë:

  • TĂ« gjitha kufizimet nga «Kufizimet e PĂ«rgjithshme mbi Rrefreshin e Shpejtë«.
  • Nuk mund tĂ« kenĂ« GRUP ME klauzola ose pĂ«rmbledhje.
  • Rowids e tĂ« gjitha tabelave nĂ« listĂ«n e FROM duhet tĂ« shfaqen nĂ« SELECT listĂ«n e kĂ«rkesĂ«s.
  • Regjistrat e pamjes sĂ« materializuar duhet tĂ« ekzistojnĂ« me rowids pĂ«r tĂ« gjitha tabelat bazĂ« nĂ« FROM listĂ«n e kĂ«rkesĂ«s.
  • Nuk mund tĂ« krijoni njĂ« pamje tĂ« materializuar qĂ« refresh-het shpejt nga disa tabela me bashkime tĂ« thjeshta qĂ« pĂ«rfshijnĂ« njĂ« kolonĂ« lloji objekt nĂ« SELECT deklaratĂ«n.

Gjithashtu, metoda e refresh-it që zgjidhni nuk do të jetë në mënyrë optimale efikase nëse:

  • KĂ«rkesa e pĂ«rcaktuar pĂ«rdor njĂ« bashkim tĂ« jashtĂ«m qĂ« funksionon si njĂ« bashkim tĂ« brendshĂ«m. NĂ«se kĂ«rkesa e pĂ«rcaktuar pĂ«rmban njĂ« tĂ« tillĂ«, merrni nĂ« konsideratĂ« shkruarjen e kĂ«rkesĂ«s sĂ« pĂ«rcaktuar pĂ«r tĂ« pĂ«rfshirĂ« njĂ« bashkim tĂ« brendshĂ«m.
  • I SELECT lista e pamjes sĂ« materializuar pĂ«rmban shprehje mbi kolona nga tabela tĂ« shumta.

5.3.8.6 Kufizimet mbi Rrefreshin e Shpejtë në Pamje të Materializuara me Përmbledhje

Kërkesat për pamjet e materializuara me përmbledhje ose bashkime kanë kufizimet e mëposhtme në rrefreshin e shpejtë:

Rrefreshi i shpejtĂ« mbĂ«shtetet pĂ«r tĂ« dy PO KREJT dhe PO KËRKESË pamjet e materializuara, megjithatĂ« kufizimet e mĂ«poshtme zbatohen:

  • TĂ« gjitha tabelat nĂ« pamjen e materializuar duhet tĂ« kenĂ« regjistrat e pamjes sĂ« materializuar, dhe regjistrat e pamjes sĂ« materializuar duhet tĂ«:
    • PĂ«rmbajnĂ« tĂ« gjitha kolonat nga tabela e referencuar nĂ« pamjen e materializuar.
    • Specifikoni me ROWID dhe PËRMBAN TË REJA VLERAT.
    • Specifikoni klauzolĂ«n SEQUENCE nĂ«se tabela pritet tĂ« ketĂ« njĂ« pĂ«rzierje tĂ« injeksioneve/drore, fshirjeve dhe azhurnimeve.

  • VetĂ«m SHTO, NUMRI, AVG, STDDEV, VARIANCE, MIN dhe MAX pĂ«rkrahĂ«n pĂ«r rrefreshin e shpejtĂ«.
  • COUNT(*) duhet tĂ« specifikohet.
  • Funksionet pĂ«rmbledhĂ«se duhet tĂ« ndodhen vetĂ«m si pjesa e jashtme e shprehjes. Kjo Ă«shtĂ«, pĂ«rmbledhjet si AVG(AVG(x)) or AVG(x)+ AVG(x) nuk lejohet.
  • PĂ«r çdo pĂ«rmbledhje si AVG(expr), pĂ«rkatĂ«sisht COUNT(expr) duhet tĂ« jetĂ« e pranishme. Oracle rekomandon qĂ« SHTO(expr) duhet tĂ« specifikohet.
  • NĂ«se VARIANCE(expr) or STDDEV(expr) Ă«shtĂ« specifikuar, COUNT(expr) dhe SHTO(expr) duhet tĂ« specifikohet. Oracle rekomandon qĂ« SHTO(expr *expr) duhet tĂ« specifikohet.
  • I SELECT kolona nĂ« kĂ«rkesĂ«n e pĂ«rcaktuar nuk mund tĂ« jetĂ« njĂ« shprehje komplekse me kolona nga tabela tĂ« shumta bazĂ«. NjĂ« zgjidhje e mundshme pĂ«r kĂ«tĂ« Ă«shtĂ« tĂ« pĂ«rdorni njĂ« pamje tĂ« materializuar tĂ« vendosur.
  • I SELECT lista duhet tĂ« pĂ«rmbajĂ« tĂ« gjitha GRUP ME kolonat.
  • Pamja e materializuar nuk Ă«shtĂ« e bazuar nĂ« njĂ« ose mĂ« shumĂ« tabela tĂ« largĂ«ta.
  • NĂ«se pĂ«rdorni njĂ« CHAR tip tĂ« dhĂ«nash nĂ« kolonat filtrues tĂ« njĂ« regjistri tĂ« pamjes sĂ« materializuar, setet e karaktereve tĂ« vendit master dhe pamjes sĂ« materializuar duhet tĂ« jenĂ« tĂ« njĂ«jta.
  • NĂ«se pamja e materializuar ka njĂ« nga tĂ« mĂ«poshtmet, atĂ«herĂ« rrefreshi i shpejtĂ« mbĂ«shtetet vetĂ«m pĂ«r injeksionet DML konvencionale dhe ngarkesa tĂ« drejtpĂ«rdrejta.
    • Pamjet e materializuara me MIN or MAX pĂ«rmbledhje
    • Pamjet e materializuara qĂ« kanĂ« SHTO(expr) por pa COUNT(expr)
    • Pamjet e materializuara pa COUNT(*)

    Një pamje e tillë e materializuar quhet pamja e materializuar e injeksioneve vetëm.

  • NjĂ« pamje e materializuar me MAX or MIN Ă«shtĂ« e ripĂ«rtrirĂ« shpejt pas fshirjes ose deklaratave DML tĂ« pĂ«rziera nĂ«se nuk ka njĂ« KU klauzolĂ«n.
    Max/min rrefreshi shpejt pas fshirjes ose DML të përziera nuk ka të njëjtin funksion si rasti i injeksioneve vetëm. Ai fshin dhe rërrethon përsëri vlerat maksimum/minimum për grupet e prekura. Duhet të jeni të vetëdijshëm për ndikimin e tij në performancë.
  • Pamjet e materializuara me pamje tĂ« emĂ«ruara ose nĂ«nkĂ«rkesa nĂ« klauzolĂ« mund tĂ« rrefreshohen shpejt nĂ«se pamjet mund tĂ« bashkohen plotĂ«sisht. PĂ«r informacion mbi cilat pamje do tĂ« bashkohen, shih FROM Referenca e GjuhĂ«s SQL tĂ« Oracle Database NĂ«se nuk ka bashkime tĂ« jashtme, mund tĂ« keni zgjedhje dhe bashkime arbitrare..
  • NĂ«se nuk ka bashkĂ«ngjitje tĂ« jashtme, mund tĂ« keni seleksione dhe bashkĂ«ngjitje arbitrare nĂ« KU klauzolĂ«n.
  • Shikimet e agreguara tĂ« materializuara me bashkime tĂ« jashtme janĂ« tĂ« shpejta pĂ«r ripĂ«rtĂ«ritje pas DML konvencionale dhe ngarkimeve direkte, me kusht qĂ« vetĂ«m tabela e jashtme tĂ« ketĂ« qenĂ« e modifikuar. Gjithashtu, duhet tĂ« ekzistojnĂ« kufizime unike mbi kolonnat e bashkimeve tĂ« tabelĂ«s sĂ« brendshme. DHEdhe duhet tĂ« pĂ«rdorin barazinĂ« (=) operator.
  • PĂ«r shikimet materializuara me CUBE, ROLLUP, grupe pĂ«rcaktuese, ose bashkimin e tyre, zbatohen kufizime tĂ« mĂ«poshtme:
    • I SELECT lista duhet tĂ« pĂ«rmbajĂ« ndarĂ«s grumbullimi qĂ« mund tĂ« jetĂ« ose njĂ« GROUPING_ID funksion mbi tĂ« gjitha GRUP ME shprehjet ose GRUPIM funksione, njĂ« pĂ«r çdo GRUP ME shprehje. PĂ«r shembull, nĂ«se GRUP ME klauzola e shikimit materializuar Ă«shtĂ« «GRUP ME CUBE(a, b)«, atĂ«herĂ« lista duhet tĂ« pĂ«rmbajĂ« ose « SELECT GROUPING_ID(a, b)» ose «GROUPING(a)GROUPING(b) DHE » pĂ«r shikimin materializuar pĂ«r tĂ« qenĂ« i shpejtĂ« nĂ« ripĂ«rtĂ«ritje.nuk duhet tĂ« rezultojĂ« nĂ« asnjĂ« grumbullim tĂ« dyfishtĂ«. PĂ«r shembull, «
    • GRUP ME GROUP BY a, ROLLUP(a, b)» nuk Ă«shtĂ« i shpejtĂ« nĂ« ripĂ«rtĂ«ritje sepse rezulton nĂ« grumbullime tĂ« dyfishta «(a), (a, b), DHE (a)5.3.8.7 Kufizimet nĂ« RipĂ«rtĂ«ritje tĂ« ShpejtĂ« mbi Shikimet Materializuara me UNION ALL«.

Shikimet materializuara me

operatori i grumbullit mbĂ«shtet opsionin UNION TË GJITHA RIPËRTËRI TË SHPEJTË nĂ«se kushtet e mĂ«poshtme plotĂ«sohen: KĂ«rkesa e pĂ«rcaktimit duhet tĂ« ketĂ«

  • operatori nĂ« nivelin e lartĂ«. UNION TË GJITHA operatori nuk mund tĂ« jetĂ« i vendosur brenda njĂ« nĂ«n-kĂ«rkese, me njĂ« pĂ«rjashtim: 

    I UNION TË GJITHA mund tĂ« jetĂ« nĂ« njĂ« nĂ«n-kĂ«rkese nĂ« UNION TË GJITHA klauzolĂ«n pĂ«r sa kohĂ« qĂ« kĂ«rkesa e pĂ«rcaktimit Ă«shtĂ« nĂ« formĂ«n FROM SELECT * FROM (shikim ose nĂ«n-kĂ«rkesĂ« me ) si nĂ« shembullin e mĂ«poshtĂ«m: UNION TË GJITHACREO SHIKIM shikim_me_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM customers c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM customers c WHERE c.cust_last_name = 'Jones');CREO SHIKIM TË MATERIALIZUAR unionall_brenda_view_mv RIPËRTËRI TË SHPEJTË NË KERKESË SI SELECT * FROM shikim_me_unionall;

    Kujdes, shikimi
    

    shikim_me_unionall plotĂ«son kĂ«rkesat pĂ«r ripĂ«rtĂ«ritje tĂ« shpejtĂ«. Çdo bllok kĂ«rkese nĂ«

  • kĂ«rkesĂ« duhet tĂ« plotĂ«sojĂ« kĂ«rkesat e njĂ« shikimi materializuar tĂ« shpejtĂ« nĂ« ripĂ«rtĂ«ritje me agregate ose njĂ« shikimi materializuar tĂ« shpejtĂ« nĂ« ripĂ«rtĂ«ritje me bashkime. UNION TË GJITHA LogĂ«t e shikimeve materializuara pĂ«rkatĂ«se duhet tĂ« krijohen mbi tabelat siç kĂ«rkohet pĂ«r llojin pĂ«rkatĂ«s tĂ« shikimeve materializuara tĂ« shpejta nĂ« ripĂ«rtĂ«ritje.

    Kujdes, gjithashtu Oracle Database lejon rastin special të një shikimi materializuar me një tabelë të vetme me bashkime vetëm nëse
    kolona është përfshirë në ROWID listë dhe në logun e shikimit materializuar. Kjo tregohet në kërkesën përcaktuese të shikimit SELECT lista e çdo kërkese duhet të përfshijë një plotëson kërkesat për ripërtëritje të shpejtë..

  • I SELECT marker, dhe UNION TË GJITHA kolona duhet tĂ« ketĂ« njĂ« vlerĂ« konstante numerike ose string tĂ« veçantĂ« nĂ« çdo UNION TË GJITHA dege. PĂ«r mĂ« tepĂ«r, kolona e markerit duhet tĂ« shfaqet nĂ« tĂ« njĂ«jtĂ«n pozitĂ« ordinal nĂ« UNION TË GJITHA listĂ«n e çdo blloku kĂ«rkese. Shih « SELECT MARKER TË UNION ALL dhe RISHKRUAR KËRKESAT» pĂ«r mĂ« shumĂ« informacion mbimarkerit. UNION TË GJITHA Disa karakteristika si bashkimet e jashtme, kĂ«rkesat pĂ«r shikimet materializuara me agregate qĂ« janĂ« vetĂ«m pĂ«r_insert dhe tabelat e largĂ«ta nuk mbĂ«shteten pĂ«r shikimet materializuara me
  • . Kujdes, megjithatĂ«, shikimet materializuara tĂ« pĂ«rdorura nĂ« replikim, tĂ« cilat nuk pĂ«rmbajnĂ« bashkime ose agregate, mund tĂ« ripĂ«rtĂ«rihen shpejt kur UNION TË GJITHAose tabelat e largĂ«ta pĂ«rdoren. UNION TË GJITHA Parametri pĂ«r fillimin e kompatibilitetit duhet tĂ« jetĂ« i vendosur nĂ« 9.2.0 ose mĂ« sipĂ«r pĂ«r tĂ« krijuar njĂ« shikim materializuar tĂ« ripĂ«rtĂ«ritshĂ«m shpejt me
  • Parametri i iniciimit tĂ« pĂ«rputhshmĂ«risĂ« duhet tĂ« vendoset nĂ« 9.2.0 ose mĂ« tĂ« lartĂ« pĂ«r tĂ« krijuar njĂ« pamje tĂ« materializuar qĂ« rifreskohet shpejt me UNION TË GJITHA.

Nuk dĂ«shiroj tĂ« ofendoj adhuruesit e Oracle, por sipas listĂ«s sĂ« tyre tĂ« kufizimeve, duket se ky mekanizĂ«m Ă«shtĂ« shkruar jo nĂ« njĂ« rast tĂ« pĂ«rgjithshĂ«m, duke pĂ«rdorur ndonjĂ« model, por nga mijĂ«ra indianĂ«, ku secilit iu dha mundĂ«sia tĂ« shkruajĂ« degĂ«n e tij, dhe çdo njeri bĂ«ri çfarĂ« mundi. PĂ«rdorimi i kĂ«tij mekanizmi pĂ«r logjikĂ«n reale Ă«shtĂ« sikur tĂ« ecĂ«sh nĂ« njĂ« fushĂ« mine. Çdo moment mund tĂ« gjesh njĂ« minĂ«, duke rĂ«nĂ« nĂ« njĂ« nga kufizimet e pabesueshme. Si funksionon kjo Ă«shtĂ« njĂ« pyetje tjetĂ«r, por ajo Ă«shtĂ« jashtĂ« kuadrit tĂ« kĂ«tij artikulli.

Microsoft SQL Server

Kërkesat Shtesë

Përveç kërkesave për opsionet SET dhe funksionet e përcaktuara, duhet të përmbushen kërkesat e mëposhtme:

  • PĂ«rdoruesi qĂ« ekzekuton KRIJO INDËKS duhet tĂ« jetĂ« pronari i pamjes.
  • Kur krijoni indeksin, opsioni IGNORE_DUP_KEY duhet tĂ« jetĂ« vendosur nĂ« OFF (caktimi i parazgjedhur).
  • TĂ« dhĂ«nat duhet tĂ« referohen me emra me dy pjesĂ«, schema.emri_tabelĂ«s nĂ« pĂ«rkufizimin e pamjes.
  • Funksionet e pĂ«rdoruesve tĂ« pĂ«rcaktuara qĂ« referohen nĂ« pamje duhet tĂ« krijohen duke pĂ«rdorur ME BINDJE_SCHEMATIC opsioni.
  • Çdo funksion i pĂ«rdoruesit tĂ« pĂ«rcaktuar qĂ« referohet nĂ« pamje duhet tĂ« referohet me emra me dy pjesĂ«, <schema>.<function>.
  • Prona e qasjes nĂ« tĂ« dhĂ«na e njĂ« funksioni tĂ« pĂ«rdoruesit tĂ« pĂ«rcaktuar duhet tĂ« jetĂ« PA SQL, dhe prona e qasjes sĂ« jashtme duhet tĂ« jetĂ« JO.
  • Funksionet e mjedisit tĂ« pĂ«rbashkĂ«t (CLR) mund tĂ« shfaqen nĂ« listĂ«n e zgjedhjes sĂ« pamjes, por nuk mund tĂ« jenĂ« pjesĂ« e pĂ«rkufizimit tĂ« çelĂ«sit tĂ« indekseve tĂ« grumbulluara. Funksionet CLR nuk mund tĂ« shfaqen nĂ« klauzolĂ«n WHERE tĂ« pamjes ose klauzolĂ«n ON tĂ« njĂ« operacioni JOIN nĂ« pamje.
  • Funksionet dhe metodat e tipeve tĂ« pĂ«rdoruesve tĂ« pĂ«rcaktuar CLR tĂ« pĂ«rdorur nĂ« pĂ«rkufizimin e pamjes duhet tĂ« kenĂ« pronat e vendosura siç Ă«shtĂ« treguar nĂ« tabelĂ«n e mĂ«poshtme.

    Pronë
    Note

    DETERMINISTIK = PO
    Duhet të shpallet eksplicitisht si një atribut i metodës Microsoft .NET Framework.

    PRECIZ = PO
    Duhet të shpallet eksplicitisht si një atribut i metodës .NET Framework.

    QASJA NË TË DHËNA = PA SQL
    E përcaktuar duke vendosur atributin DataAccess në DataAccessKind.None dhe atributin SystemDataAccess në SystemDataAccessKind.None.

    QASJA E JASHTME = JO
    Ky atribut është parazgjedhur në JO për rutinat CLR.

  • Pamja duhet tĂ« krijohet duke pĂ«rdorur ME BINDJE_SCHEMATIC opsioni.
  • Pamja duhet tĂ« referohet vetĂ«m tabelave bazĂ« qĂ« janĂ« nĂ« tĂ« njĂ«jtin bazĂ« tĂ« tĂ« dhĂ«nave me pamjen. Pamja nuk mund tĂ« referojĂ« pamje tĂ« tjera.
  • Deklarata SELECT nĂ« pĂ«rkufizimin e pamjes nuk duhet tĂ« pĂ«rmbajĂ« elementet e mĂ«poshtme T-SQL:

    NUMRI
    funksionet ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, DHE OPENXML)
    JONET E JASHTME ( E MAJTËE DJATHTË, Tabela e derivuar (e cila pĂ«rcaktohet duke specifikuar njĂ«, ose FULL)

    deklaratës në klauzolën SELECT Vetë-ndërlidhjet FROM Specifikimi i kolonave duke përdorur
    SELECT *
    SELECT .* STDEV or STDEVP

    DISTINCT
    VAR, VARP, Shprehja e tabelës së zakonshme (CTE), float, ose AVG
    ntext

    filestream1, text, kolona, image, XML, ose Nënpyetje MBI
    klauzolë, e cila përfshin funksione dritaruese ose agregate
    PĂ«rdorimet e tekstit tĂ« plotĂ« ( PËRMBAN

    FREETEXTfunksioni që referon një shprehje të mundshme, funksioni agregat i përdoruesve të përcaktuar CLR)
    SHTO MAJ
    ORDER BY

    GRUPIM SETET
    operatorët
    CUBE, ROLLUP, ose PËRBASHKIM NË GJDHE

    MIN, MAX
    UNION, MUE TABELATAMPLE, ose TĂ« dhĂ«nat e tabelave NË GJDHE
    APLIKIM I JASHTËM

    APLIKIM NË CROSS
    TABELA or MIRATIM
    PIVOT, PIVOT

    Grupet e kolonave sparse
    Funksionet e tipit të tabelës inline (TVF) ose funksionet e tipit të tabelës me shumë deklarata (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Pamja e indekseve mund të përmbajë filestream kolona; megjithatë, këto kolona nuk mund të përfshihen në çelësin e indekseve të grumbulluara.

  • NĂ«se GRUPIM NGA Ă«shtĂ« e pranishme, pĂ«rkufizimi i PAMJES duhet tĂ« pĂ«rmbajĂ« COUNT_BIG(*) dhe nuk duhet tĂ« pĂ«rmbajĂ« KLAUZOLË ME. KĂ«to GRUPIM NGA kufizime janĂ« tĂ« aplikueshme vetĂ«m pĂ«r pĂ«rkufizimin e pamjes sĂ« indekseve. NjĂ« pyetje mund tĂ« pĂ«rdorĂ« njĂ« pamje tĂ« indekseve nĂ« planin e ekzekutimit edhe nĂ«se nuk pĂ«rmbush kĂ«to GRUPIM NGA kufizime.
  • NĂ«se pĂ«rkufizimi i pamjes pĂ«rmban njĂ« GRUPIM NGA klauzolĂ«, çelĂ«si i indekseve tĂ« unike tĂ« grumbulluara mund tĂ« referojĂ« vetĂ«m kolonat e specifikuara nĂ« GRUPIM NGA klauzolĂ«n.

KĂ«tu shihet se indianĂ«t nuk ishin tĂ«rhequr, pasi ata vendosĂ«n tĂ« punojnĂ« sipas skemĂ«s “do tĂ« bĂ«jmĂ« pak, por mirĂ«â€. Kjo do tĂ« thotĂ« se ata kanĂ« mĂ« shumĂ« miniera nĂ« fushĂ«, por pozita e tyre Ă«shtĂ« mĂ« e qartĂ«. MĂ« shumĂ« se çdo gjĂ« mĂ« shqetĂ«son kjo kufizim:

Pamja duhet të referohet vetëm tabelave bazë që janë në të njëjtin bazë të të dhënave me pamjen. Pamja nuk mund të referojë pamje të tjera.

Në terminologjinë tonë, kjo do të thotë se funksioni nuk mund të thërrasë një funksion tjetër të materializuar. Kjo e prish të gjithë ideologjinë në rrënjë.
Po ashtu, ky kufizim (dhe më tej në tekst) zvogëlon shumë mundësitë e përdorimit:

Deklarata SELECT në përkufizimin e pamjes nuk duhet të përmbajë elementet e mëposhtme T-SQL:

NUMRI
funksionet ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, DHE OPENXML)
JONET E JASHTME ( E MAJTËE DJATHTË, Tabela e derivuar (e cila pĂ«rcaktohet duke specifikuar njĂ«, ose FULL)

deklaratës në klauzolën SELECT Vetë-ndërlidhjet FROM Specifikimi i kolonave duke përdorur
SELECT *
SELECT .* STDEV or STDEVP

DISTINCT
VAR, VARP, Shprehja e tabelës së zakonshme (CTE), float, ose AVG
ntext

filestream1, text, kolona, image, XML, ose Nënpyetje MBI
klauzolë, e cila përfshin funksione dritaruese ose agregate
PĂ«rdorimet e tekstit tĂ« plotĂ« ( PËRMBAN

FREETEXTfunksioni që referon një shprehje të mundshme, funksioni agregat i përdoruesve të përcaktuar CLR)
SHTO MAJ
ORDER BY

GRUPIM SETET
operatorët
CUBE, ROLLUP, ose PËRBASHKIM NË GJDHE

MIN, MAX
UNION, MUE TABELATAMPLE, ose TĂ« dhĂ«nat e tabelave NË GJDHE
APLIKIM I JASHTËM

APLIKIM NË CROSS
TABELA or MIRATIM
PIVOT, PIVOT

Grupet e kolonave sparse
Funksionet e tipit të tabelës inline (TVF) ose funksionet e tipit të tabelës me shumë deklarata (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY dhe të tjera janë të ndaluara. Ndoshta do të ishte më e lehtë të tregohej se çfarë mund të përdoret, sesa çfarë nuk mund të përdoret. Lista ndoshta do të ishte shumë më e vogël.

Duke përmbledhur: një set i madh kufizimesh në çdo (të cilin e theksoj komercial) SGBD përballë asnjë (përveç një logjike, e jo teknike) në teknologjinë LGPL. Megjithatë, duhet vënë në dukje se implementimi i këtij mekanizmi në logjikën relationale është paksa më i ndërlikuar se sa në logjikën funksionale të përshkruar.

Implementimi

Si funksionon kjo? Si “makinĂ« virtuale” pĂ«rdoret PostgreSQL. Brenda saj ndodhet njĂ« algoritĂ«m i ndĂ«rlikuar, i cili merret me ndĂ«rtimin e kĂ«rkesave. Ja kodin burimor. Dhe atje nuk ka vetĂ«m njĂ« set tĂ« madh heuristikash me shumĂ« if’ë. Pra, nĂ«se keni disa muaj pĂ«r tĂ« studiuar, mund tĂ« provoni tĂ« kuptoni arkitekturĂ«n.

A funksionon kjo efikasisht? Mjaft efikase. Fatkeqësisht, është e vështirë ta provohet këtë. Mund të them vetëm se nëse shqyrtohet mijëra kërkesat që ka në aplikacione të mëdha, atëherë në mesatare ato janë më efikase se ato të një zhvilluesi të mirë. Një programues i shkëlqyer SQL mund të shkruajë çdo kërkesë më efikaste, por në mijëra kërkesa ai thjesht nuk do të ketë motivim as kohë për ta bërë këtë. E vetmja gjë që mund të jap si provë aktuale të efikasitetit është se mbi platformën e ndërtuar mbi këtë SGBD punojnë disa projekte sistemet ERP, në të cilat ka mijëra funksione MATERIALIZED të ndryshme, me mijëra përdorues dhe baza terabajtësh me qindra milionë regjistrime, që punojnë në një server të zakonshëm me dy procesorë. Megjithatë, kushdo që dëshiron mund të verifikojë / të mohojë efikasitetin, duke shkarkuar platformën dhe PostgreSQL, të aktivizoni regjistrimin e kërkesave SQL dhe duke provuar të ndryshojë logjikën dhe të dhënat.

Në artikujt e ardhshëm, do të flas gjithashtu për mënyrën si mund të vendosen kufizime mbi funksionet, punën me seancat e ndryshimeve dhe shumë të tjera.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster