Uravnoteženje pisanja in branja v bazi podatkov

Uravnoteženje pisanja in branja v bazi podatkov
V prejšnjem članek Opisal sem koncept in izvedbo baze podatkov, zgrajene na podlagi funkcij, ne pa tabel in polj kot v relacijskih bazah podatkov. Podal je številne primere, ki kažejo prednosti tega pristopa pred klasičnim. Mnogi so se zdeli premalo prepričljivi.

V tem članku bom pokazal, kako vam ta koncept omogoča hitro in priročno uravnoteženje pisanja in branja v bazo podatkov brez kakršne koli spremembe logike delovanja. Podobno funkcionalnost so poskušali implementirati v sodobne komercialne DBMS (zlasti Oracle in Microsoft SQL Server). Na koncu članka bom pokazal, da se to, kar so naredili, milo rečeno, ni najbolje obneslo.

Opis

Kot prej bom za boljše razumevanje opis začel s primeri. Recimo, da moramo implementirati logiko, ki bo vrnila seznam oddelkov s številom zaposlenih v njih in njihovo skupno plačo.

V funkcionalni bazi podatkov bi to izgledalo takole:

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);

Kompleksnost izvajanja te poizvedbe v kateri koli DBMS bo enakovredna O (število zaposlenih)ker ta izračun zahteva skeniranje celotne tabele zaposlenih in njihovo nato grupiranje po oddelkih. Glede na izbrani načrt bo na voljo tudi nekaj malega (verjamemo, da je zaposlenih veliko več kot oddelkov). O(log število zaposlenih) ali O (število oddelkov) za združevanje in tako naprej.

Jasno je, da so stroški izvajanja lahko različni v različnih DBMS, vendar se kompleksnost ne bo spremenila na noben način.

V predlagani izvedbi bo funkcionalni DBMS ustvaril eno podpoizvedbo, ki bo izračunala zahtevane vrednosti za oddelek, nato pa naredila JOIN s tabelo oddelka, da bi pridobila ime. Za vsako funkcijo pa je ob deklaraciji možno nastaviti poseben označevalec MATERIALIZED. Sistem bo za vsako tako funkcijo samodejno ustvaril ustrezno polje. Ko spremenite vrednost funkcije, se bo v isti transakciji spremenila tudi vrednost polja. Ko dostopate do te funkcije, se dostopa do vnaprej izračunanega polja.

Še posebej, če za funkcije nastavite MATERIALIZED countEmployees и plačaSum, nato pa bosta tabeli s seznamom oddelkov dodani dve polji, v katerih bo shranjeno število zaposlenih in njihova skupna plača. Kadar koli pride do spremembe zaposlenih, njihovih plač ali pripadnosti oddelku, bo sistem samodejno spremenil vrednosti teh polj. Zgornja poizvedba bo neposredno dostopala do teh polj in bo izvedena v O (število oddelkov).

Kakšne so omejitve? Samo ena stvar: takšna funkcija mora imeti končno število vhodnih vrednosti, za katere je definirana njena vrednost. V nasprotnem primeru bo nemogoče sestaviti tabelo, ki bi hranila vse svoje vrednosti, saj ne more obstajati tabela z neskončnim številom vrstic.

Primer:

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

Ta funkcija je definirana za neskončno število vrednosti N (primerna je na primer katera koli negativna vrednost). Zato nanj ne morete postaviti MATERIALIZIRANO. To je torej logična omejitev, ne tehnična (torej ne zato, ker je ne bi mogli implementirati). Sicer pa ni nobenih omejitev. Uporabite lahko združevanje, razvrščanje, IN in ALI, PARTICIJO, rekurzijo itd.

Na primer, v problemu 2.2 prejšnjega članka lahko postavite MATERIALIZED na obe funkciji:

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 bo sam ustvaril eno tabelo s tipskimi ključi Pomoč, Izdelek и CELO, mu bo dodal dve polji in z morebitnimi spremembami posodobil vrednosti polj v njih. Pri nadaljnjih klicih teh funkcij ne bodo izračunane, temveč bodo vrednosti prebrane iz ustreznih polj.

S tem mehanizmom se lahko na primer znebite rekurzij (CTE) v poizvedbah. Predvsem razmislite o skupinah, ki tvorijo drevo z odnosom otrok/starš (vsaka skupina ima povezavo do svojega starša):

parent = DATA Group (Group);

V funkcionalni bazi podatkov je rekurzijsko logiko mogoče podati na naslednji način:

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;

Ker za funkcijo isParent je označeno z MATERIALIZIRANO, potem se bo zanj ustvarila tabela z dvema ključema (skupinama), v kateri bo polje isParent bo resničen samo, če je prvi ključ otrok drugega. Število vnosov v tej tabeli bo enako številu skupin, pomnoženemu s povprečno globino drevesa. Če želite na primer prešteti število potomcev določene skupine, lahko uporabite to funkcijo:

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

V poizvedbi SQL ne bo CTE. Namesto tega bo na voljo preprosto GROUP BY.

S tem mehanizmom lahko po potrebi preprosto denormalizirate bazo podatkov:

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

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

Pri klicu funkcije Datum za naročilno vrstico bo polje, za katerega obstaja indeks, prebrano iz tabele z naročilnimi vrsticami. Ko se datum naročila spremeni, bo sistem sam samodejno preračunal denormalizirani datum v vrstici.

Prednosti

Čemu je namenjen ves ta mehanizem? V klasičnih DBMS lahko brez prepisovanja poizvedb razvijalec ali DBA samo spremeni indekse, določi statistiko in načrtovalcu poizvedb pove, kako naj jih izvede (namigi pa so na voljo samo v komercialnih DBMS). Ne glede na to, koliko se trudijo, ne bodo mogli dokončati prve poizvedbe v članku v O (število oddelkov) brez spreminjanja poizvedb ali dodajanja sprožilcev. V predlagani shemi vam na stopnji razvoja ni treba razmišljati o strukturi shranjevanja podatkov in o tem, katere agregacije uporabiti. Vse to je mogoče enostavno spremeniti sproti, neposredno med delovanjem.

V praksi je videti takole. Nekateri ljudje razvijejo logiko neposredno na podlagi naloge. Ne razumejo algoritmov in njihove kompleksnosti, niti izvedbenih načrtov, niti tipov povezav, niti katere koli druge tehnične komponente. Ti ljudje so bolj poslovni analitiki kot razvijalci. Nato gre vse to v testiranje ali delovanje. Omogoča beleženje dolgotrajnih poizvedb. Ko je zaznana dolga poizvedba, se drugi ljudje (bolj tehnični - v bistvu DBA) odločijo omogočiti MATERIALIZED na neki vmesni funkciji. To nekoliko upočasni snemanje (saj zahteva posodobitev dodatnega polja v transakciji). Vendar pa ni bistveno pohitrena samo ta poizvedba, ampak tudi vse ostale, ki to funkcijo uporabljajo. Hkrati je odločitev, katero funkcijo uresničiti, relativno enostavna. Dva glavna parametra: število možnih vhodnih vrednosti (to je, koliko zapisov bo v ustrezni tabeli) in kako pogosto se uporablja v drugih funkcijah.

Analogi

Sodobni komercialni DBMS-ji imajo podobne mehanizme: MATERIALIZIRANI POGLED s HITRO OSVEŽEVANJEM (Oracle) in INDEKSIRAN POGLED (Microsoft SQL Server). V PostgreSQL MATERIALIZED VIEW ni mogoče posodobiti v transakciji, ampak samo na zahtevo (in celo z zelo strogimi omejitvami), zato ga ne upoštevamo. Imajo pa več težav, ki bistveno omejujejo njihovo uporabo.

Prvič, materializacijo lahko omogočite le, če ste že ustvarili običajni POGLED. V nasprotnem primeru boste morali za uporabo te materializacije prepisati preostale zahteve za dostop do novo ustvarjenega pogleda. Ali pa pustite vse tako, kot je, vendar bo vsaj neučinkovito, če obstajajo določeni že vnaprej izračunani podatki, vendar jih veliko poizvedb ne uporablja vedno, ampak jih preračuna.

Drugič, imajo ogromno omejitev:

Oracle

5.3.8.4 Splošne omejitve za hitro osveževanje

Definirajoča poizvedba materializiranega pogleda je omejena na naslednji način:

  • Materializirani pogled ne sme vsebovati sklicevanj na izraze, ki se ne ponavljajo, kot je SYSDATE in ROWNUM.
  • Materializirani pogled ne sme vsebovati referenc na RAW or LONG RAW vrste podatkov.
  • Ne more vsebovati a SELECT seznam podpoizvedbe.
  • Ne more vsebovati analitičnih funkcij (npr. RANK) v SELECT klavzula.
  • Ne more se sklicevati na tabelo, na kateri je an XMLIndex indeks je določen.
  • Ne more vsebovati a MODEL klavzula.
  • Ne more vsebovati a HAVING stavek s podpoizvedbo.
  • Ne more vsebovati ugnezdenih poizvedb, ki imajo ANY, ALLali NOT EXISTS.
  • Ne more vsebovati a [START WITH …] CONNECT BY klavzula.
  • Ne more vsebovati več tabel s podrobnostmi na različnih mestih.
  • ON COMMIT materializirani pogledi ne morejo imeti tabel oddaljenih podrobnosti.
  • Ugnezdeni materializirani pogledi morajo imeti spoj ali agregat.
  • Materializirani združeni pogledi in materializirani združeni pogledi z a GROUP BY člena ni mogoče izbrati iz tabele, urejene z indeksom.

5.3.8.5 Omejitve hitrega osveževanja materializiranih pogledov samo z združitvami

Definiranje poizvedb za materializirane poglede samo z združitvami in brez agregatov ima naslednje omejitve pri hitrem osveževanju:

  • Vse omejitve iz «Splošne omejitve za hitro osveževanje".
  • Ne morejo imeti GROUP BY klavzul ali agregatov.
  • Vrstice vseh tabel v FROM seznam mora biti prikazan v SELECT seznam poizvedbe.
  • Dnevniki materializiranega pogleda morajo obstajati z vrsticami za vse osnovne tabele v FROM seznam poizvedbe.
  • Ne morete ustvariti materializiranega pogleda s hitrim osveževanjem iz več tabel s preprostimi spoji, ki vključujejo stolpec vrste predmeta v SELECT izjavo.

Prav tako izbrani način osveževanja ne bo optimalno učinkovit, če:

  • Definirajoča poizvedba uporablja zunanjo združitev, ki se obnaša kot notranja združitev. Če definirajoča poizvedba vsebuje tako združevanje, razmislite o prepisu definirajoče poizvedbe, da bo vsebovala notranje združevanje.
  • O SELECT seznam materializiranega pogleda vsebuje izraze za stolpce iz več tabel.

5.3.8.6 Omejitve hitrega osveževanja materializiranih pogledov z agregati

Definiranje poizvedb za materializirane poglede z agregati ali spoji ima naslednje omejitve pri hitrem osveževanju:

Hitro osveževanje je podprto za oba ON COMMIT in ON DEMAND materializirani pogledi, vendar veljajo naslednje omejitve:

  • Vse tabele v materializiranem pogledu morajo imeti dnevnike materializiranega pogleda, dnevniki materializiranega pogleda pa morajo:
    • Vsebuje vse stolpce iz tabele, na katero se sklicuje materializiran pogled.
    • Določite z ROWID in INCLUDING NEW VALUES.
    • določite SEQUENCE če se pričakuje, da bo tabela vsebovala mešanico vstavljanj/neposrednih nalaganj, brisanja in posodobitev.

  • samo SUM, COUNT, AVG, STDDEV, VARIANCE, MIN in MAX so podprti za hitro osveževanje.
  • COUNT(*) je treba navesti.
  • Združevalne funkcije se morajo pojaviti le kot najbolj oddaljeni del izraza. Se pravi agregati kot npr AVG(AVG(x)) or AVG(x)+ AVG(x) niso dovoljene.
  • Za vsak agregat kot npr AVG(expr), ustrezna COUNT(expr) mora biti prisoten. Oracle to priporoča SUM(expr) določiti.
  • If VARIANCE(expr) or STDDEV(expr) je določeno, COUNT(expr) in SUM(expr) je treba navesti. Oracle to priporoča SUM(expr *expr) določiti.
  • O SELECT stolpec v definirajoči poizvedbi ne more biti zapleten izraz s stolpci iz več osnovnih tabel. Možna rešitev za to je uporaba ugnezdenega materializiranega pogleda.
  • O SELECT seznam mora vsebovati vse GROUP BY stolpcev.
  • Materializirani pogled ne temelji na eni ali več oddaljenih tabelah.
  • Če uporabljate a CHAR tipa podatkov v stolpcih filtra dnevnika materializiranega pogleda, morajo biti nabori znakov glavnega mesta in materializiranega pogleda enaki.
  • Če ima materializiran pogled eno od naslednjega, je hitro osveževanje podprto samo pri običajnih vstavkih DML in neposrednih nalaganjih.
    • Materializirani pogledi z MIN or MAX agregati
    • Materializirani pogledi, ki imajo SUM(expr) vendar ne COUNT(expr)
    • Materializirani pogledi brez COUNT(*)

    Takšen materializiran pogled se imenuje materializiran pogled samo za vstavljanje.

  • Materializiran pogled z MAX or MIN se hitro osveži po izbrisu ali mešanih stavkih DML, če nima a WHERE klavzula.
    Največja/najmanjša hitra osvežitev po brisanju ali mešanem DML nima enakega vedenja kot primer samo vstavi. Izbriše in znova izračuna največje/najmanjše vrednosti za prizadete skupine. Zavedati se morate njegovega vpliva na uspešnost.
  • Materializirani pogledi z imenovanimi pogledi ali podpoizvedbami v FROM klavzulo je mogoče hitro osvežiti, če je mogoče poglede popolnoma združiti. Za informacije o tem, kateri pogledi se bodo združili, glejte Oracle Database SQL Reference Language.
  • Če ni zunanjih združevanj, imate morda poljubne izbire in združevanja v WHERE klavzula.
  • Materializirane agregatne poglede z zunanjimi spoji je mogoče hitro osvežiti po običajnem DML in neposrednih nalaganjih, če je bila spremenjena samo zunanja tabela. Prav tako morajo obstajati enolične omejitve za spojene stolpce notranje tabele za spajanje. Če obstajajo zunanji spoji, morajo biti vsi spoji povezani z ANDs in mora uporabiti enakost (=) operater.
  • Za materializirane poglede z CUBE, ROLLUP, združevanje nizov ali njihovo veriženje veljajo naslednje omejitve:
    • O SELECT seznam mora vsebovati razločevalnik združevanja, ki je lahko a GROUPING_ID delujejo na vseh GROUP BY izrazi oz GROUPING funkcije po eno za vsakega GROUP BY izražanje. Na primer, če je GROUP BY klavzula materializiranega pogleda je "GROUP BY CUBE(a, b)", nato pa SELECT seznam mora vsebovati "GROUPING_ID(a, b)» ali «GROUPING(a) AND GROUPING(b)» za hitro osveževanje materializiranega pogleda.
    • GROUP BY ne sme povzročiti podvojenih skupin. Na primer, "GROUP BY a, ROLLUP(a, b)" ni mogoče hitro osvežiti, ker povzroči podvojene skupine "(a), (a, b), AND (a)".

5.3.8.7 Omejitve hitrega osveževanja materializiranih pogledov z UNION ALL

Materializirani pogledi z UNION ALL nastavite operatersko podporo REFRESH FAST možnost, če so izpolnjeni naslednji pogoji:

  • Definirajoča poizvedba mora imeti UNION ALL operater na najvišji ravni.

    O UNION ALL operatorja ni mogoče vdelati v podpoizvedbo, z eno izjemo: The UNION ALL je lahko v podpoizvedbi v FROM klavzula pod pogojem, da je definirajoča poizvedba v obliki SELECT * FROM (ogled ali podpoizvedba z UNION ALL), kot v naslednjem primeru:

    CREATE VIEW view_with_unionall AS (IZBERI c.rowid crid, c.cust_id, 2 umarker FROM strank c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM strank c WHERE c.cust_last_name = 'Jones'); USTVARI MATERIALIZIRAN POGLED unionall_inside_view_mv HITRO OSVEŽI NA ZAHTEVO KOT IZBERI * IZ view_with_unionall;
    

    Upoštevajte, da pogled view_with_unionall izpolnjuje zahteve po hitrem osveževanju.

  • Vsak blok poizvedbe v UNION ALL poizvedba mora izpolnjevati zahteve materializiranega pogleda s hitrim osveževanjem z agregati ali materializiranega pogleda s hitrim osveževanjem z združitvami.

    Na tabelah je treba ustvariti ustrezne dnevnike materializiranih pogledov, kot je zahtevano za ustrezno vrsto materializiranega pogleda s hitrim osveževanjem.
    Upoštevajte, da zbirka podatkov Oracle dovoljuje tudi poseben primer materializiranega pogleda ene tabele s spoji samo pod pogojem ROWID stolpec je bil vključen v SELECT seznamu in v dnevniku materializiranega pogleda. To je prikazano v definicijski poizvedbi pogleda view_with_unionall.

  • O SELECT seznam vsake poizvedbe mora vsebovati a UNION ALL marker in UNION ALL stolpec mora imeti v vsakem ločeno konstantno številsko ali nizovno vrednost UNION ALL podružnica. Poleg tega se mora stolpec z označevalci pojaviti na istem ordinalnem mestu v SELECT seznam vsakega bloka poizvedbe. glej "Označevalnik UNION ALL in prepis poizvedbe» za več informacij o UNION ALL označevalci.
  • Nekatere funkcije, kot so zunanja združevanja, poizvedbe zbranih materializiranih pogledov samo za vstavljanje in oddaljene tabele, niso podprte za materializirane poglede z UNION ALL. Upoštevajte pa, da je mogoče materializirane poglede, uporabljene pri podvajanju, ki ne vsebujejo združevanj ali agregatov, hitro osvežiti, ko UNION ALL ali se uporabljajo oddaljene tabele.
  • Inicializacijski parameter združljivosti mora biti nastavljen na 9.2.0 ali višje, da ustvarite materializirani pogled s hitrim osveževanjem z UNION ALL.

Nočem užaliti oboževalcev Oracla, a sodeč po njihovem seznamu omejitev se zdi, da ta mehanizem ni bil napisan v splošnem primeru z uporabo nekakšnega modela, temveč na tisoče Indijcev, kjer je vsak dobil možnost, da napisati svojo vejo in vsak od njih je naredil, kar je lahko. in naredil. Uporaba tega mehanizma za pravo logiko je kot hoja skozi minsko polje. Rudnik lahko dobite kadar koli, tako da pritisnete eno od neočitnih omejitev. Kako deluje, je prav tako ločeno vprašanje, vendar presega obseg tega članka.

Microsoft SQL Server

Dodatne zahteve

Poleg možnosti SET in zahtev za deterministične funkcije morajo biti izpolnjene naslednje zahteve:

  • Uporabnik, ki izvaja CREATE INDEX mora biti lastnik pogleda.
  • Ko ustvarite indeks, se IGNORE_DUP_KEY možnost mora biti nastavljena na OFF (privzeta nastavitev).
  • Tabele se morajo sklicevati z dvodelnimi imeni, shema.ime tabele v definiciji pogleda.
  • Uporabniško definirane funkcije, navedene v pogledu, morajo biti ustvarjene z uporabo WITH SCHEMABINDING možnost.
  • Vse uporabniško definirane funkcije, navedene v pogledu, se morajo sklicevati z dvodelnimi imeni, ..
  • Lastnost dostopa do podatkov uporabniško definirane funkcije mora biti NO SQL, lastnost zunanjega dostopa pa mora biti NO.
  • Funkcije izvajalnega okolja skupnega jezika (CLR) so lahko prikazane na izbirnem seznamu pogleda, vendar ne morejo biti del definicije ključa indeksa v gručah. Funkcije CLR se ne morejo pojaviti v členu WHERE pogleda ali členu ON operacije JOIN v pogledu.
  • Funkcije CLR in metode uporabniško definiranih tipov CLR, ki se uporabljajo v definiciji pogleda, morajo imeti nastavljene lastnosti, kot je prikazano v naslednji tabeli.

    Nepremičnine
    Opombe

    DETERMINISTIČNO = PRAV
    Mora biti izrecno deklariran kot atribut metode Microsoft .NET Framework.

    NATANČNO = PRAV
    Mora biti izrecno deklariran kot atribut metode .NET Framework.

    DOSTOP DO PODATKOV = NI SQL
    Določeno z nastavitvijo atributa DataAccess na DataAccessKind.None in atributa SystemDataAccess na SystemDataAccessKind.None.

    ZUNANJI DOSTOP = ŠT
    Ta lastnost je privzeto nastavljena na NO za rutine CLR.

  • Pogled je treba ustvariti z uporabo WITH SCHEMABINDING možnost.
  • Pogled se mora sklicevati samo na osnovne tabele, ki so v isti bazi podatkov kot pogled. Pogled se ne more sklicevati na druge poglede.
  • Stavek SELECT v definiciji pogleda ne sme vsebovati naslednjih elementov Transact-SQL:

    COUNT
    Funkcije ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSETIN OPENXML)
    OUTER pridruži se (LEFT, RIGHTali FULL)

    Izpeljana tabela (definirana s podajanjem a SELECT izjava v FROM klavzula)
    Samopridruževanje
    Določanje stolpcev z uporabo SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPali AVG
    Izraz skupne tabele (CTE)

    float1, besedilo, ntext, slika, XMLali datotečni tok stolpci
    Podpoizvedba
    OVER klavzula, ki vključuje funkcije razvrščanja ali združevanja oken

    Predikati celotnega besedila (CONTAINS, FREETEXT)
    SUM funkcijo, ki se sklicuje na ničelni izraz
    ORDER BY

    Uporabniško definirana agregatna funkcija CLR
    TOP
    CUBE, ROLLUPali GROUPING SETS operaterji

    MIN, MAX
    UNION, EXCEPTali INTERSECT operaterji
    TABLESAMPLE

    Spremenljivke tabele
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Redki nizi stolpcev
    Funkcije v vrstici (TVF) ali funkcije z vrednostjo tabele z več stavki (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Indeksirani pogled lahko vsebuje float stolpci; vendar takšnih stolpcev ni mogoče vključiti v ključ indeksa v gručah.

  • If GROUP BY je prisoten, mora vsebovati definicija VIEW COUNT_BIG(*) in ne sme vsebovati HAVING. Ti GROUP BY omejitve veljajo samo za definicijo indeksiranega pogleda. Poizvedba lahko v svojem načrtu izvajanja uporablja indeksirani pogled, tudi če ne izpolnjuje teh GROUP BY omejitve.
  • Če definicija pogleda vsebuje a GROUP BY se lahko ključ edinstvenega gručastega indeksa sklicuje samo na stolpce, določene v GROUP BY klavzula.

Tukaj je jasno, da Indijci niso bili vpleteni, saj so se odločili za to po shemi "naredili bomo malo, a dobro." To pomeni, da imajo več min na terenu, vendar je njihova lokacija bolj pregledna. Najbolj razočaranje je ta omejitev:

Pogled se mora sklicevati samo na osnovne tabele, ki so v isti bazi podatkov kot pogled. Pogled se ne more sklicevati na druge poglede.

V naši terminologiji to pomeni, da funkcija ne more dostopati do druge materializirane funkcije. To v kali poseka vso ideologijo.
Tudi ta omejitev (in nadaljevanje v besedilu) močno zmanjša primere uporabe:

Stavek SELECT v definiciji pogleda ne sme vsebovati naslednjih elementov Transact-SQL:

COUNT
Funkcije ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSETIN OPENXML)
OUTER pridruži se (LEFT, RIGHTali FULL)

Izpeljana tabela (definirana s podajanjem a SELECT izjava v FROM klavzula)
Samopridruževanje
Določanje stolpcev z uporabo SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPali AVG
Izraz skupne tabele (CTE)

float1, besedilo, ntext, slika, XMLali datotečni tok stolpci
Podpoizvedba
OVER klavzula, ki vključuje funkcije razvrščanja ali združevanja oken

Predikati celotnega besedila (CONTAINS, FREETEXT)
SUM funkcijo, ki se sklicuje na ničelni izraz
ORDER BY

Uporabniško definirana agregatna funkcija CLR
TOP
CUBE, ROLLUPali GROUPING SETS operaterji

MIN, MAX
UNION, EXCEPTali INTERSECT operaterji
TABLESAMPLE

Spremenljivke tabele
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Redki nizi stolpcev
Funkcije v vrstici (TVF) ali funkcije z vrednostjo tabele z več stavki (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY in drugi so prepovedani. Morda bi bilo lažje določiti, kaj se lahko uporabi, namesto česa se ne sme uporabiti. Seznam bi bil verjetno precej krajši.

Če povzamem: ogromen nabor omejitev v vsakem (naj upoštevamo komercialnem) DBMS proti nobeni (z izjemo ene logične, ne tehnične) v tehnologiji LGPL. Vendar je treba opozoriti, da je implementacija tega mehanizma v relacijsko logiko nekoliko težja kot v opisani funkcionalni logiki.

Реализация

Kako deluje? PostgreSQL se uporablja kot "virtualni stroj". V notranjosti je zapleten algoritem, ki gradi poizvedbe. Tukaj vir. In ne obstaja samo velik nabor hevristik s kupom če-jev. Torej, če imate nekaj mesecev časa za študij, lahko poskusite razumeti arhitekturo.

Ali deluje učinkovito? Zelo učinkovito. Na žalost je to težko dokazati. Lahko samo rečem, da če upoštevate na tisoče poizvedb, ki obstajajo v velikih aplikacijah, potem so v povprečju učinkovitejše od tistih dobrega razvijalca. Odličen programer SQL lahko učinkoviteje napiše katero koli poizvedbo, a s tisoč poizvedbami preprosto ne bo imel motivacije ali časa za to. Edina stvar, ki jo lahko zdaj navedem kot dokaz učinkovitosti, je, da več projektov deluje na platformi, zgrajeni na tej DBMS ERP sistemi, ki imajo na tisoče različnih MATERIALIZIRANIH funkcij, s tisoči uporabnikov in terabajtnimi bazami podatkov s stotinami milijonov zapisov, ki tečejo na navadnem dvoprocesorskem strežniku. Učinkovitost pa lahko vsak preveri/ovrže s prenosom platforma in PostgreSQL, vključen beleženje poizvedb SQL in poskušanje tam spremeniti logiko in podatke.

V naslednjih člankih bom govoril tudi o tem, kako lahko nastavite omejitve funkcij, delate s sejami sprememb in še veliko več.

Vir: www.habr.com

Dodaj komentar