Tasakaalustamine kirjutab ja loeb andmebaasis

Tasakaalustamine kirjutab ja loeb andmebaasis
Eelmises siit Kirjeldasin pigem funktsioonide, mitte tabelite ja väljade alusel üles ehitatud andmebaasi kontseptsiooni ja teostust nagu relatsiooniandmebaasides. See esitas palju näiteid, mis näitavad selle lähenemisviisi eeliseid klassikalise lähenemisviisi ees. Paljud leidsid, et need ei olnud piisavalt veenvad.

Selles artiklis näitan, kuidas see kontseptsioon võimaldab kiiresti ja mugavalt tasakaalustada andmebaasi kirjutamist ja lugemist ilma tööloogikat muutmata. Sarnast funktsionaalsust on proovitud rakendada ka tänapäevastes kommertsandmebaasisüsteemides (eriti Oracle'is ja Microsoft SQL Serveris). Artikli lõpus näitan, et see, mida nad tegid, ei tulnud pehmelt öeldes kuigi hästi välja.

Kirjeldus

Nagu varemgi, alustan paremaks mõistmiseks kirjeldust näidetega. Oletame, et peame rakendama loogikat, mis tagastab osakondade nimekirja, kus on märgitud töötajate arv ja nende kogupalk.

Funktsionaalses andmebaasis näeks see välja järgmine:

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

Selle päringu täitmise keerukus mis tahes DBMS-is on samaväärne O (töötajate arv)sest see arvutus nõuab kogu töötajate tabeli skaneerimist ja seejärel osakondade kaupa rühmitamist. Sõltuvalt valitud plaanist lisandub ka väike (usume, et töötajaid on palju rohkem kui osakondi) lisa O (logirist töötajate arv) või O (osakondade arv) rühmitamiseks ja nii edasi.

On selge, et täitmise üldkulud võivad erinevates DBMS-ides olla erinevad, kuid keerukus ei muutu kuidagi.

Kavandatavas teostuses genereerib funktsionaalne DBMS ühe alampäringu, mis arvutab osakonna jaoks nõutavad väärtused ja teeb seejärel nime saamiseks osakonna tabeliga LIITUMISE. Iga funktsiooni jaoks on aga deklareerimisel võimalik määrata spetsiaalne MATERIALISEERITUD marker. Süsteem loob iga sellise funktsiooni jaoks automaatselt vastava välja. Funktsiooni väärtuse muutmisel muutub samas tehingus ka välja väärtus. Sellele funktsioonile juurdepääsul pääseb juurde eelarvutatud väljale.

Eelkõige siis, kui määrate funktsioonide jaoks MATERIALIZED lugema töötajaid и palkSumma, siis lisatakse osakondade nimekirjaga tabelisse kaks välja, kuhu salvestatakse töötajate arv ja nende kogupalk. Iga kord, kui toimub muutus töötajates, nende palkades või osakondade kuuluvuses, muudab süsteem automaatselt nende väljade väärtusi. Ülaltoodud päring pääseb neile väljadele otse juurde ja see käivitatakse O (osakondade arv).

Millised on piirangud? Ainult üks asi: sellisel funktsioonil peab olema piiratud arv sisendväärtusi, mille jaoks selle väärtus on määratletud. Vastasel juhul on võimatu luua tabelit, mis salvestaks kõik selle väärtused, kuna ei saa olla lõpmatu arvu ridadega tabelit.

Näide:

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

See funktsioon on defineeritud lõpmatu arvu N väärtuste jaoks (näiteks sobib iga negatiivne väärtus). Seetõttu ei saa te sellele panna MATERIALISED. Seega on see loogiline, mitte tehniline piirang (st mitte sellepärast, et me ei saaks seda rakendada). Vastasel juhul pole piiranguid. Saate kasutada rühmitamist, sorteerimist, JA ja VÕI, PARTITSIOONI, rekursiooni jne.

Näiteks eelmise artikli ülesandes 2.2 saate mõlemale funktsioonile panna MATERIALIZED:

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;

Süsteem ise loob ühe tabeli tüübiklahvidega Klient, Toode и INTEGRE, lisab sellele kaks välja ja värskendab nende väljade väärtusi muudatustega. Kui nendele funktsioonidele tehakse täiendavaid kõnesid, siis neid ei arvutata, vaid pigem loetakse väärtusi vastavatelt väljadelt.

Seda mehhanismi kasutades saate näiteks päringutes vabaneda rekursioonidest (CTE). Eelkõige mõelge rühmadele, mis moodustavad puu, kasutades lapse/vanema suhet (igal rühmal on link oma vanemaga):

parent = DATA Group (Group);

Funktsionaalses andmebaasis saab rekursiooniloogikat määrata järgmiselt:

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;

Kuna funktsiooni jaoks isParent on märgitud MATERIALISEERITUD, siis luuakse selle jaoks kahe võtmega (rühmaga) tabel, milles väli isParent kehtib ainult siis, kui esimene võti on teise alamvõti. Selle tabeli kirjete arv võrdub rühmade arvuga, mis on korrutatud puu keskmise sügavusega. Kui teil on vaja näiteks teatud rühma järeltulijate arvu lugeda, saate kasutada seda funktsiooni:

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

SQL-päringus ei ole CTE-d. Selle asemel on lihtne GROUP BY.

Seda mehhanismi kasutades saate vajaduse korral ka andmebaasi hõlpsalt denormaliseerida:

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

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

Funktsiooni kutsumisel andmed tellimusrea jaoks loetakse tellimusridadega tabelist väli, mille jaoks on indeks. Kui tellimuse kuupäev muutub, arvutab süsteem ise automaatselt ümber real denormaliseeritud kuupäeva.

Eelised

Mille jaoks kogu see mehhanism on? Klassikalistes DBMS-ides saab arendaja või DBA ilma päringuid ümber kirjutamata muuta ainult indekseid, määrata statistikat ja öelda päringuplaneerijale, kuidas neid täita (ja vihjed on saadaval ainult kaubanduslikes DBMS-ides). Ükskõik kui kõvasti nad ka ei püüaks, ei suuda nad artikli esimest päringut täita O (osakondade arv) ilma päringuid muutmata või käivitajaid lisamata. Kavandatavas skeemis ei pea te arendusetapis mõtlema andmesalvestusstruktuurile ja sellele, milliseid liite kasutada. Seda kõike saab hõlpsasti muuta käigu pealt, otse töökorras.

Praktikas näeb see välja selline. Mõned inimesed arendavad loogikat otse käsiloleva ülesande põhjal. Nad ei mõista algoritme ja nende keerukust, täitmisplaane, ühenduste tüüpe ega muid tehnilisi komponente. Need inimesed on rohkem ärianalüütikud kui arendajad. Seejärel läheb see kõik testimiseks või käitamiseks. Võimaldab pikaajaliste päringute logimist. Kui tuvastatakse pikk päring, otsustavad teised inimesed (tehnilisemad – sisuliselt DBA) lubada mõnel vahepealsel funktsioonil MATERIALIZED. See aeglustab veidi salvestamist (kuna see nõuab tehingus täiendava välja värskendamist). Kuid mitte ainult see päring ei ole oluliselt kiirendatud, vaid ka kõik teised seda funktsiooni kasutavad. Samal ajal on suhteliselt lihtne otsustada, millist funktsiooni realiseerida. Kaks peamist parameetrit: võimalike sisendväärtuste arv (nii palju kirjeid on vastavas tabelis) ja kui sageli seda muudes funktsioonides kasutatakse.

Analoogid

Kaasaegsetel kaubanduslikel DBMS-idel on sarnased mehhanismid: MATERIALIZED VIEW koos FAST REFRESH-iga (Oracle) ja INDEXED VIEW (Microsoft SQL Server). PostgreSQL-is ei saa MATERIALIZED VIEW'i tehingus värskendada, vaid ainult nõudmisel (ja isegi väga rangete piirangutega), seega me seda ei arvesta. Kuid neil on mitmeid probleeme, mis piiravad oluliselt nende kasutamist.

Esiteks saate materialiseerimise lubada ainult siis, kui olete juba loonud tavalise VIEW. Vastasel juhul peate selle materialiseerimise kasutamiseks vastloodud vaatele juurdepääsu saamiseks ülejäänud taotlused ümber kirjutama. Või jätke kõik nii, nagu on, kuid see on vähemalt ebaefektiivne, kui on teatud juba eelnevalt arvutatud andmed, kuid paljud päringud ei kasuta neid alati, vaid arvutavad ümber.

Teiseks on neil tohutult palju piiranguid:

Oraakel

5.3.8.4 Kiire värskendamise üldised piirangud

Realiseeritud vaate määratlev päring on piiratud järgmiselt.

  • Realiseeritud vaade ei tohi sisaldada viiteid mittekorduvatele väljenditele nagu SYSDATE ja ROWNUM.
  • Realiseeritud vaade ei tohi sisaldada viiteid RAW or LONG RAW andmetüübid.
  • See ei tohi sisaldada a SELECT loendi alampäring.
  • See ei tohi sisaldada analüütilisi funktsioone (nt RANK) aastal SELECT klausel.
  • See ei saa viidata tabelile, millel an XMLIndex indeks on määratletud.
  • See ei tohi sisaldada a MODEL klausel.
  • See ei tohi sisaldada a HAVING alampäringuga klausel.
  • See ei saa sisaldada pesastatud päringuid, millel on ANY, ALLvõi NOT EXISTS.
  • See ei tohi sisaldada a [START WITH …] CONNECT BY klausel.
  • See ei tohi sisaldada eri saitidel mitut üksiktabelit.
  • ON COMMIT materialiseeritud vaadetel ei saa olla kaugdetailidetabeleid.
  • Pesastatud materialiseeritud vaadetel peab olema liitumine või koondvaade.
  • Realiseeritud liitvaated ja materialiseeritud koondvaated koos a GROUP BY klauslit ei saa indeksiga korraldatud tabelist valida.

5.3.8.5 Ainult liitumistega materialiseeritud vaadete kiire värskendamise piirangud

Päringute määratlemisel realiseerunud vaadete jaoks, millel on ainult liitumised ja ilma koondfailideta, on kiirel värskendamisel järgmised piirangud.

  • Kõik piirangud alates «Kiire värskendamise üldised piirangud"
  • Neil ei saa olla GROUP BY klauslid või agregaadid.
  • Kõikide tabelite read FROM nimekiri peab ilmuma SELECT päringu loend.
  • Materialiseeritud vaate logid peavad olema koos ridadega kõigi põhitabelite jaoks FROM päringu loend.
  • Kiiret värskendatavat materialiseeritud vaadet ei saa luua mitmest tabelist lihtsate ühendustega, mis sisaldavad objektitüübi veergu. SELECT avalduses.

Samuti ei ole teie valitud värskendusmeetod optimaalselt tõhus, kui:

  • Defineeriv päring kasutab välist ühendust, mis käitub nagu sisemine liitmine. Kui defineeriv päring sisaldab sellist liitumist, kaaluge defineeriva päringu ümberkirjutamist, et see sisaldaks sisemist ühendust.
  • . SELECT materialiseeritud vaate loend sisaldab avaldisi mitme tabeli veergudel.

5.3.8.6 Agregaatidega materialiseeritud vaadete kiire värskendamise piirangud

Agregaatide või liitumistega materialiseeritud vaadete päringute määratlemisel on kiirel värskendamisel järgmised piirangud.

Kiiret värskendamist toetatakse mõlema jaoks ON COMMIT ja ON DEMAND realiseerunud vaated, kuid kehtivad järgmised piirangud:

  • Kõik materialiseeritud vaate tabelid peavad sisaldama materialiseeritud vaate logisid ja materialiseeritud vaate logid peavad:
    • Sisaldab kõiki materialiseeritud vaates viidatud tabelis olevaid veerge.
    • Täpsustage koos ROWID ja INCLUDING NEW VALUES.
    • Märkida SEQUENCE klausel, kui tabelis eeldatakse segu lisamisi/otselaadimisi, kustutamisi ja värskendusi.

  • Ainult SUM, COUNT, AVG, STDDEV, VARIANCE, MIN ja MAX toetatakse kiireks värskendamiseks.
  • COUNT(*) tuleb täpsustada.
  • Koondfunktsioonid peavad esinema ainult avaldise välimise osana. See tähendab, et agregaadid nagu AVG(AVG(x)) or AVG(x)+ AVG(x) ei ole lubatud.
  • Iga agregaadi jaoks nagu AVG(expr), vastav COUNT(expr) peab kohal olema. Oracle soovitab seda SUM(expr) täpsustada.
  • If VARIANCE(expr) or STDDEV(expr) on täpsustatud, COUNT(expr) ja SUM(expr) tuleb täpsustada. Oracle soovitab seda SUM(expr *expr) täpsustada.
  • . SELECT veerg määratlevas päringus ei saa olla keerukas avaldis, mis sisaldab veerge mitmest põhitabelist. Võimalik lahendus sellele on kasutada pesastatud materialiseeritud vaadet.
  • . SELECT nimekiri peab sisaldama kõike GROUP BY veerud.
  • Realiseeritud vaade ei põhine ühel või mitmel kaugtabelil.
  • Kui kasutate a CHAR materialiseeritud vaate logi filtriveergude andmetüüp, põhisaidi ja materialiseeritud vaate märgistikud peavad olema samad.
  • Kui materialiseeritud vaatel on üks järgmistest, toetatakse kiiret värskendamist ainult tavaliste DML-i lisade ja otselaadimiste korral.
    • Materialiseeritud vaated koos MIN or MAX agregaatide
    • Realiseeritud vaated, millel on SUM(expr) kuid mitte COUNT(expr)
    • Materialiseeritud vaated ilma COUNT(*)

    Sellist materialiseerunud vaadet nimetatakse ainult sisestatud materialiseeritud vaateks.

  • Realiseeritud vaade koos MAX or MIN on kiiresti värskendatav pärast kustutamist või segatud DML-i avaldusi, kui sellel pole a WHERE klausel.
    Maksimaalne/min kiire värskendamine pärast kustutamist või segatud DML-i ei toimi samamoodi kui ainult sisestamise korral. See kustutab mõjutatud rühmade max/min väärtused ja arvutab need uuesti. Peate olema teadlik selle mõjust jõudlusele.
  • Nimetatud vaadete või alampäringutega materialiseeritud vaated FROM klauslit saab kiiresti värskendada, kui vaated saab täielikult liita. Teavet selle kohta, millised vaated liidetakse, vt Oracle Database SQL keele viide.
  • Kui väliseid liitumisi pole, võib teil olla suvalisi valikuid ja liitumisi WHERE klausel.
  • Väliste ühendustega materialiseeritud koondvaated on pärast tavapärast DML-i ja otselaadimist kiiresti värskendatavad, eeldusel, et muudetud on ainult välimist tabelit. Samuti peavad sisemise liitmistabeli liitumisveergudel olema kordumatud piirangud. Kui on väliseid liitekohti, peavad kõik ühendused olema ühendatud ANDs ja peavad kasutama võrdsust (=) operaator.
  • Realiseeritud vaadete jaoks koos CUBE, ROLLUP, rühmituskomplekte või nende ühendamist, kehtivad järgmised piirangud.
    • . SELECT loend peaks sisaldama rühmituste eristajat, mis võib olla kas a GROUPING_ID funktsioon kõigis GROUP BY väljendid või GROUPING funktsioonid üks igaühe jaoks GROUP BY väljendus. Näiteks kui GROUP BY materialiseeritud vaate klausel on "GROUP BY CUBE(a, b)", siis SELECT nimekiri peaks sisaldama kas "GROUPING_ID(a, b)» või «GROUPING(a) AND GROUPING(b)» et materialiseerunud vaade oleks kiiresti värskendatav.
    • GROUP BY ei tohiks põhjustada dubleerivaid rühmitusi. Näiteks, "GROUP BY a, ROLLUP(a, b)"ei ole kiiresti värskendatav, kuna selle tulemuseks on dubleeritud rühmitused"(a), (a, b), AND (a)"

5.3.8.7 Rakenduse UNION ALL materialiseeritud vaadete kiire värskendamise piirangud

Materialiseeritud vaated koos UNION ALL määra operaatori tugi REFRESH FAST valik, kui on täidetud järgmised tingimused:

  • Määratlevas päringus peab olema UNION ALL tipptasemel operaator.

    . UNION ALL operaatorit ei saa manustada alampäringu sisse, välja arvatud üks erand: The UNION ALL võib olla alampäringus FROM klausel tingimusel, et määratlev päring on sellisel kujul SELECT * FROM (vaadake või alampäringut kasutades UNION ALL) nagu järgmises näites:

    CREATE VIEW view_with_unionall AS (VALI c.rowid crid, c.cust_id, 2 umarker FROM klientidelt c WHERE c.cust_last_name = 'Smith' UNION KÕIK SELECT c.rowid crid, c.cust_id, 3 umarker FROM klientidelt c WHERE c.cust_last "Jones"); LOO MATERIALISEERITUD VAADE unionall_inside_view_mv VÄRSKENDAGE KIIRE NÕUDLUSEL AS SELECT * FROM view_with_unionall;
    

    Pange tähele, et vaade view_with_unionall vastab kiire värskendamise nõuetele.

  • Iga päringuplokk UNION ALL päring peab vastama koondandmetega kiiresti värskendatava materialiseeritud vaate või ühendustega kiiresti värskendatava materialiseeritud vaate nõuetele.

    Tabelitele tuleb luua vastavad materialiseeritud vaate logid, nagu on vaja vastavat tüüpi kiirelt värskendatava materialiseeritud vaate jaoks.
    Pange tähele, et Oracle'i andmebaas lubab ka ühe tabeli materialiseeritud vaate erijuhtumit koos liitumistega ainult juhul, kui ROWID veerg on lisatud veergu SELECT loendis ja materialiseeritud vaate logis. Seda näidatakse vaate defineerivas päringus view_with_unionall.

  • . SELECT iga päringu loend peab sisaldama a UNION ALL marker ja UNION ALL igas veerus peab olema erinev konstantne arv- või stringväärtus UNION ALL haru. Lisaks peab markeri veerg olema samas järjekorraasendis SELECT iga päringuploki loend. Vaata "UNION ALL Marker ja päring ümberkirjutamine» lisateabe saamiseks UNION ALL markerid.
  • Mõningaid funktsioone, nagu välimised ühendused, ainult sisestatavad materialiseeritud vaatepäringud ja kaugtabelid, ei toetata materialiseeritud vaadete puhul UNION ALL. Pange tähele, et replikatsioonis kasutatavaid materialiseeritud vaateid, mis ei sisalda liite ega agregaate, saab kiiresti värskendada, kui UNION ALL või kasutatakse kauglaudu.
  • Ühilduvuse lähtestamise parameeter peab olema seatud väärtusele 9.2.0 või kõrgem, et luua kiiresti värskendatav materialiseeritud vaade UNION ALL.

Ma ei taha Oracle'i fänne solvata, kuid nende piirangute nimekirja järgi otsustades tundub, et see mehhanism ei ole kirjutatud üldiselt, kasutades mingit mudelit, vaid tuhandete indiaanlaste poolt, kus kõigile anti võimalus kirjutage oma haru ja igaüks neist tegi, mis suutis. ja tegi. Selle mehhanismi kasutamine tõelise loogika jaoks on nagu kõndimine läbi miinivälja. Miini saate igal ajal, kui vajutate mõnda mitteilmsetest piirangutest. See, kuidas see toimib, on samuti omaette küsimus, kuid see jääb käesoleva artikli raamidest välja.

Microsoft SQL Server

Täiendavad nõuded

Lisaks SET-suvanditele ja deterministlike funktsioonide nõuetele peavad olema täidetud järgmised nõuded:

  • Kasutaja, kes täidab CREATE INDEX peab olema vaate omanik.
  • Indeksi loomisel kuvatakse IGNORE_DUP_KEY suvand peab olema seatud olekusse OFF (vaikesäte).
  • Tabelitele tuleb viidata kaheosaliste nimedega, kava.tabelinimi vaate definitsioonis.
  • Vaates viidatud kasutaja määratud funktsioonid tuleb luua kasutades WITH SCHEMABINDING valik.
  • Kõikidele vaates viidatud kasutaja määratud funktsioonidele tuleb viidata kaheosaliste nimedega, ..
  • Kasutaja määratud funktsiooni andmetele juurdepääsu atribuut peab olema NO SQL, ja välise juurdepääsu atribuut peab olema NO.
  • Ühise keele käitusaja (CLR) funktsioonid võivad ilmuda vaate valikuloendis, kuid ei saa olla osa rühmitatud indeksivõtme määratlusest. CLR-funktsioonid ei saa ilmuda vaate WHERE-klauslis ega vaates JOIN-toimingu klauslis ON.
  • Vaatedefinitsioonis kasutatavate CLR-i funktsioonide ja CLR-i kasutaja määratud tüüpide meetoditel peavad olema järgmised atribuudid, nagu on näidatud järgmises tabelis.

    vara
    märkused

    DETERMINISTILINE = TÕENE
    Tuleb selgelt deklareerida Microsoft .NET Frameworki meetodi atribuudina.

    TÄPSUS = TÕENE
    Tuleb selgelt deklareerida .NET Frameworki meetodi atribuudina.

    ANDMEJUURDE = SQL puudub
    Määratakse atribuudi DataAccess väärtuseks DataAccessKind.None ja SystemDataAccess atribuudiks SystemDataAccessKind.None.

    VÄLISPÄÄS = EI
    Selle atribuudi vaikeväärtus on CLR-rutiinide puhul NO.

  • Vaade tuleb luua kasutades WITH SCHEMABINDING valik.
  • Vaade peab viitama ainult põhitabelitele, mis on vaatega samas andmebaasis. Vaade ei saa viidata teistele vaadetele.
  • Vaatedefinitsioonis olev SELECT-lause ei tohi sisaldada järgmisi Transact-SQL-i elemente:

    COUNT
    ROWSET funktsioonid (OPENDATASOURCE, OPENQUERY, OPENROWSET, JA OPENXML)
    OUTER liitub (LEFT, RIGHTvõi FULL)

    Tuletatud tabel (määratletud, määrates a SELECT avaldus FROM klausel)
    Ise liitub
    Veergude määramine kasutades SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARPvõi AVG
    Ühine tabeliavaldis (CTE)

    ujuk1, tekst, ntekst, pilt, XMLvõi failivoog veerud
    Subquery
    OVER klausel, mis sisaldab järjestamise või koondakna funktsioone

    Täisteksti predikaadid (CONTAINS, FREETEXT)
    SUM funktsioon, mis viitab nullitavale avaldisele
    ORDER BY

    CLR kasutaja määratud koondfunktsioon
    TOP
    CUBE, ROLLUPvõi GROUPING SETS ettevõtjad

    MIN, MAX
    UNION, EXCEPTvõi INTERSECT ettevõtjad
    TABLESAMPLE

    Tabeli muutujad
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Hõredad veergude komplektid
    Tekstisisesed (TVF) või mitme lausega tabeliväärtusega funktsioonid (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Indekseeritud vaade võib sisaldada ujuk veerud; kuid selliseid veerge ei saa lisada rühmitatud indeksi võtmesse.

  • If GROUP BY on olemas, peab VIEW definitsioon sisaldama COUNT_BIG(*) ja ei tohi sisaldada HAVING. Need GROUP BY piirangud kehtivad ainult indekseeritud vaate määratlusele. Päring võib kasutada oma täitmisplaanis indekseeritud vaadet isegi siis, kui see neid ei rahulda GROUP BY piirangud.
  • Kui vaate definitsioon sisaldab a GROUP BY klausel, unikaalse rühmitatud indeksi võti saab viidata ainult veergudele, mis on määratud GROUP BY klausel.

Siin on selge, et indiaanlased ei olnud sellega seotud, kuna nad otsustasid seda teha skeemi "teeme vähe, aga hästi" järgi. See tähendab, et neil on põllul rohkem miine, kuid nende asukoht on läbipaistvam. Kõige pettumust valmistav on see piirang:

Vaade peab viitama ainult põhitabelitele, mis on vaatega samas andmebaasis. Vaade ei saa viidata teistele vaadetele.

Meie terminoloogias tähendab see, et funktsioon ei pääse juurde teisele materialiseeritud funktsioonile. See vähendab kogu ideoloogiat.
Samuti vähendab see piirang (ja veelgi tekstis) oluliselt kasutusjuhtumeid:

Vaatedefinitsioonis olev SELECT-lause ei tohi sisaldada järgmisi Transact-SQL-i elemente:

COUNT
ROWSET funktsioonid (OPENDATASOURCE, OPENQUERY, OPENROWSET, JA OPENXML)
OUTER liitub (LEFT, RIGHTvõi FULL)

Tuletatud tabel (määratletud, määrates a SELECT avaldus FROM klausel)
Ise liitub
Veergude määramine kasutades SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARPvõi AVG
Ühine tabeliavaldis (CTE)

ujuk1, tekst, ntekst, pilt, XMLvõi failivoog veerud
Subquery
OVER klausel, mis sisaldab järjestamise või koondakna funktsioone

Täisteksti predikaadid (CONTAINS, FREETEXT)
SUM funktsioon, mis viitab nullitavale avaldisele
ORDER BY

CLR kasutaja määratud koondfunktsioon
TOP
CUBE, ROLLUPvõi GROUPING SETS ettevõtjad

MIN, MAX
UNION, EXCEPTvõi INTERSECT ettevõtjad
TABLESAMPLE

Tabeli muutujad
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Hõredad veergude komplektid
Tekstisisesed (TVF) või mitme lausega tabeliväärtusega funktsioonid (MSTVF)
OFFSET

CHECKSUM_AGG

VÄLISED LIITUMISED, ÜHENDUS, TELLIMUS ja teised on keelatud. Võib-olla oleks olnud lihtsam täpsustada, mida saab kasutada, mitte seda, mida ei saa kasutada. Nimekiri oleks ilmselt palju lühem.

Kokkuvõtteks: tohutu hulk piiranguid igas (märkigem kommertskasutuses) DBMS-is vs mitte ühtegi (välja arvatud üks loogiline, mitte tehniline) LGPL-tehnoloogias. Siiski tuleb märkida, et selle mehhanismi rakendamine relatsiooniloogikas on mõnevõrra keerulisem kui kirjeldatud funktsionaalse loogika puhul.

Реализация

Kuidas see töötab? PostgreSQL-i kasutatakse "virtuaalse masinana". Sees on keeruline algoritm, mis koostab päringuid. Siin allikas. Ja seal pole ainult suur hulk heuristikat koos hulga if-idega. Seega, kui teil on paar kuud õppida, võite proovida arhitektuurist aru saada.

Kas see toimib tõhusalt? Üsna tõhus. Kahjuks on seda raske tõestada. Võin vaid öelda, et kui arvestada tuhandete taotlustega, mis suurtes rakendustes eksisteerivad, siis on need keskmiselt tõhusamad kui hea arendaja omad. Suurepärane SQL-i programmeerija suudab kirjutada mis tahes päringu tõhusamalt, kuid tuhande päringu korral pole tal selleks lihtsalt motivatsiooni ega aega. Ainus asi, mida saan nüüd tõhususe tõestuseks mainida, on see, et sellele DBMS-ile ehitatud platvormil töötavad mitmed projektid ERP süsteemid, millel on tuhandeid erinevaid MATERIALISEERITUD funktsioone, millel on tuhanded kasutajad ja terabaidised andmebaasid sadade miljonite kirjetega tavalises kaheprotsessorilises serveris. Kuid igaüks saab allalaadimise abil tõhusust kontrollida/ümber lükata platvorm ja PostgreSQL, sisse lülitatud logides SQL päringuid ja üritades seal loogikat ja andmeid muuta.

Järgmistes artiklites räägin ka sellest, kuidas saab määrata funktsioonidele piiranguid, töötada muudatusseanssidega ja paljust muust.

Allikas: www.habr.com

Lisa kommentaar