Vyváženie zápisu a čítania v databáze

Vyváženie zápisu a čítania v databáze
V predchádzajúcom článku Opísal som koncept a realizáciu databázy, ktorá je založená na funkciách, nie na tabuľkách a políčkach ako v relačných databázach. Obsahovala množstvo príkladov, ktoré ukazujú výhody takéhoto prístupu v porovnaní s klasickým. Mnohí ich považovali za nedostatočne presvedčivé.

V tomto článku ukážem, ako takýto koncept umožňuje rýchlo a pohodlne vyvážiť zápis a čítanie do databázy bez akejkoľvek zmeny logiky fungovania. Podobnú funkcionalitu sa snažili realizovať súčasné komerčné DBMS (najmä Oracle a Microsoft SQL Server). Na konci článku ukážem, aké výsledky dosiahli, jemne povedané, nie veľmi dobré.

Popis

Ako už predtým, na lepšie pochopenie začnem popis na príkladoch. Predpokladajme, že potrebujeme realizovať logiku, ktorá bude vracať zoznam oddelení s počtom zamestnancov v nich a ich súhrnným platom.

V funkčnej databáze to bude vyzerať nasledovne:

CLASS Department ‘Oddelenie’;
name ‘Názov’ = DATA STRING[100] (Department);

CLASS Employee ‘Zamestnanec’;
department ‘Oddelenie’ = DATA Department (Employee);
salary ‘Plat’ = DATA NUMERIC[10,2] (Employee);

countEmployees ‘Počet zamestnancov’ (Department d) = 
    GROUP SUM 1 IF department(Employee e) = d;
salarySum ‘Súhrnný plat’ (Department d) = 
    GROUP SUM salary(Employee e) IF department(e) = d;

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

Zložitost vykonania tohto dotazu v akejkoľvek DBMS bude ekvivalentná O(pocet zamestnancov), pretože na tento výpočet je potrebné prehľadávať celú tabuľku zamestnancov a potom ich zoskupiť podľa oddelenia. Bude tu tiež malý prídavok (predpokladáme, že zamestnancov je omnoho viac než oddelení) v závislosti od zvoleného plánu O(log pocet zamestnancov) alebo O(pocet oddelení) na zoskupenie a iné.

Je jasné, že režijné náklady na vykonanie sa môžu líšiť v rôznych DBMS, ale zložitost sa nijako nezmení.

V navrhnutej implementácii funkčná DBMS vytvorí jeden poddotaz, ktorý vypočíta potrebné hodnoty podľa oddelenia, a potom vykoná JOIN s tabuľkou oddelení na získanie mena. Avšak pri každej funkcii pri deklarácii existuje možnosť nastaviť špeciálny marker MATERIALIZED. Systém automaticky vytvorí zodpovedajúce pole pre každú takú funkciu. Pri zmene hodnoty funkcie sa v tej istej transakcii zmení aj hodnota poľa. Pri prístupe k tejto funkcii sa bude pristupovať už k prepočítanému poľu.

Konkrétne, ak nastavíte MATERIALIZED pre funkcie countEmployees a salarySum, v tabuľke so zoznamom oddelení sa pridajú dve polia, v ktorých budú uložené počet zamestnancov a ich súhrnný plat. Pri akejkoľvek zmene zamestnancov, ich platov alebo patrnosti k oddeleniam systém automaticky zmení hodnoty týchto polí. Uvedený dotaz sa potom bude odvolávať priamo na tieto polia a bude vykonaný za O(pocet oddelení).

Aké sú obmedzenia? Iba jedno: taká funkcia musí mať konečný počet vstupných hodnôt, pre ktoré je jej hodnota definovaná. Inak nebude možné zostaviť tabuľku, ktorá uchováva všetky jej hodnoty, pretože nemôže existovať tabuľka s nekonečným počtom riadkov.

Príklad:

zamestnanciPočet ‘Počet zamestnancov s platmi > N’ (oddelenie d, NUMERIC[10,2] N) = 
    SKUPINA SÚČET plat (zamestnanec e) AK oddelenie(e) = d A plat(e) > N;

Táto funkcia je definovaná pre nekonečný počet hodnôt čísla N (napríklad vyhovuje akákoľvek záporná hodnota). Preto na ňu nemožno nastaviť MATERIALIZED. Takže to je logické, nie technické obmedzenie (t.j. nie preto, že sme to nedokázali realizovať). Inak – žiadne obmedzenia. Môžete používať agregácie, triedenia, AND a OR, PARTITION, rekurzie atď.

Napríklad v úlohe 2.2 predchádzajúceho článku môžete nastaviť MATERIALIZED na obe funkcie:

kúpil 'Kúpil' (Zákazník c, Produkt p, ČÍSLO y) = 
    SKUPINOVÝ ZOZNAM súčtov(Detail d) AK 
        zákazník(objednávka(d)) = c A 
        produkt(d) = p A 
        vyberRok(datum(objednávka(d))) = y MATERIALIZOVANÉ;
hodnotenie 'Hodnotenie' (Zákazník c, Produkt p, ČÍSLO y) = 
    PARTIČNÝ ZOZNAM 1 PORADIE ZOSTUPNE kúpené(c, p, y), p PODĽA c, y MATERIALIZOVANÉ;
VYBERTE contactName(Zákazník c), name(Produkt p) KDE hodnotenie(c, p, 1997) < 3;

Systém sám vytvorí jednu tabuľku s kľúčmi typov Zákazník, Product a INTEGER, pridá do nej dve polia a bude aktualizovať v nich hodnoty polí pri akýchkoľvek zmenách. Pri ďalších prístupoch k týmto funkciám sa nebudú vykonávať výpočty, ale budú sa čítať hodnoty z príslušných polí.

Pomocou tohto mechanizmu sa môžete, napríklad, zbavovať rekurzií (CTE) v dotazoch. Konkrétne, zvážime skupiny, ktoré vytvárajú strom pomocou vzťahu child/parent (každá skupina má odkaz na svojho rodiča):

parent = DATA Group (Group);

V funkčnej databáze je možné logiku rekurzií zadať nasledujúcim spôsobom:

úroveň (Skupina dieťa, Skupina rodič) = REKURZIA 1l AK dieťa JE Skupina A rodič == dieťa
                                                             KROK 2l AK rodič == rodič($parent);
jeRodič (Skupina dieťa, Skupina rodič) = PRAVDA AK úroveň(dieťa, rodič) ZHMOTNENÉ;

Keďže pre funkciu isParent je nastavený MATERIALIZED, pod ňu sa vytvorí tabuľka s dvoma kľúčmi (skupinami), v ktorej bude pole isParent pravdivé iba vtedy, ak je prvý kľúč potomkom druhého. Počet záznamov v tejto tabuľke bude rovný počtu skupín vynásobenému priemernou hĺbkou stromu. Ak je potrebné napríklad vypočítať počet potomkov určitej skupiny, je možné sa odvolať na túto funkciu:

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

Žiadne CTE v SQL dopyte pritom nebude. Namiesto toho bude jednoduché GROUP BY.

S pomocou tohto mechanizmu je tiež možné ľahko vykonať denormalizáciu databázy, ak je to potrebné:

CLASS Order 'Objednávka';
date 'Dátum' = DATA DATE (Objednávka);

CLASS OrderDetail 'Položka objednávky';
order 'Objednávka' = DATA Order (OrderDetail);
date 'Dátum' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED;

Pri volaní funkcie date pre položku objednávky bude prebiehať čítanie z tabuľky s položkami objednávok poľa, pre ktoré existuje index. Pri zmene dátumu objednávky systém automaticky prepočíta denormalizovaný dátum v položke.

Výhody

Na čo je celý tento mechanizmus potrebný? V klasických DBMS, bez prestavovania dopytov, vývojár alebo DBA môžu iba meniť indexy, určovať štatistiku a navrhovať plánovaču dopytov, ako ich vykonať (a HINT'y sú len v komerčných DBMS). Ako veľmi by sa snažili, nemôžu vykonať prvý dopyt v článku za O (počet oddelení) bez zmeny dopytov a pridávania triggerov. V navrhnutej schéme, v etape vývoja, nie je potrebné premýšľať o štruktúre ukladania dát a o tom, aké agregácie použiť. To všetko je možné kľudne meniť naživo už počas prevádzky.

V praxi to vyzerá takto. Niektorí ľudia vyvíjajú priamo logiku na základe zadanej úlohy. Nerozumejú algoritmom a ich zložitosti, ani plánom vykonávania, ani typom joinov, ani iným technickým aspektom. Títo ľudia sú skôr biznis analytici než vývojári. Potom to všetko ide na testovanie alebo do prevádzky. Aktivuje sa logovanie dlhých dotazov. Keď sa zistí dlhý dotaz, rozhodujú sa o ňom iní ľudia (technickejší — v podstate DBA) zahrnúť MATERIALIZED na niektorej medzifunkcii. Tým sa trochu spomalí zápis (keďže je potrebné aktualizovať ďalšie pole v transakcii). Avšak, výrazne sa urýchli nielen tento dotaz, ale aj všetky ostatné, ktoré používajú túto funkciu. Pri tom je rozhodovanie o tom, ktorú funkciu materializovať, relatívne jednoduché. Dva základné parametre: počet možných vstupných hodnôt (presne toľko záznamov bude v príslušnej tabuľke) a ak často sa používa v iných funkciách.

Analógy

V moderných komerčných DBMS existujú podobné mechanizmy: MATERIALIZED VIEW s RÝCHLYM OBNOVENÍM (Oracle) a INDEXED VIEW (Microsoft SQL Server). V PostgreSQL MATERIALIZED VIEW nevie aktualizovať v tranzakcii, len na vyžiadanie (a to s veľmi prísnymi obmedzeniami), takže ho nerealizujeme. Ale majú niekoľko problémov, ktoré výrazne obmedzujú ich použitie.

Po prvé, materializáciu je možné zapnúť len v prípade, že ste už vytvorili bežný VIEW. Inak budete musieť prepisovať ostatné dotazy na prístup k novo vytvorenému pohľadu, aby ste využili túto materializáciu. Alebo to nechať tak, ako je, ale bude to minimálne neefektívne, ak existujú určité už prepočítané údaje, no mnohé dotazy ich nie vždy používajú, ale počítajú ich opäť.

Po druhé, majú obrovské množstvo obmedzení:

Oracle

5.3.8.4 Všeobecné obmedzenia na rýchle obnovenie

Definujúci dotaz materializovaného pohľadu je obmedzený nasledujúcim spôsobom:

  • Materializovaný pohľad nesmie obsahovať odkazy na neopakujúce sa výrazy ako SYSDATE a ROWNUM.
  • Materializovaný pohľad nesmie obsahovať odkazy na RAW ale LONG RAW dátové typy.
  • Nemôže obsahovať SELECT poddotaz v zozname.
  • Nemôže obsahovať analytické funkcie (napríklad, RANK) v SELECT klauzuli.
  • Nemôže odkazovať na tabuľku, na ktorej je definovaný XMLIndex index.
  • Nemôže obsahovať MODEL klauzuli.
  • Nemôže obsahovať HAVING klauzulu s poddotazom.
  • Nemôže obsahovať vnorené dotazy, ktoré majú ANY, ALL, alebo NOT EXISTS.
  • Nemôže obsahovať [START WITH …] CONNECT BY klauzuli.
  • Nemôže obsahovať viacero tabuliek detailov na rôznych lokalitách.
  • ÁNO COMMIT materializované pohľady nemôžu mať vzdialené tabuľky detailov.
  • Vnorené materializované pohľady musia mať spojenie alebo agregáciu.
  • Materializované spojovacie pohľady a materializované agregátne pohľady s SKUPINA PO klauzula nemôže vyberať z tabuľky organizovanej podľa indexu.

5.3.8.5 Obmedzenia na rýchle obnovenie materializovaných pohľadov iba so spojeniami

Definovanie dotazov pre materializované pohľady s iba spojeniami a bez agregácií má nasledujúce obmedzenia na rýchle obnovenie:

  • Všetky obmedzenia z «Všeobecné obmedzenia na rýchle obnovenie«.
  • Nemôžu mať SKUPINA PO klauzuly ani agregácie.
  • Rowids všetkých tabuliek v FROM zozname sa musí objaviť v SELECT zozname dotazu.
  • Logy materializovaných pohľadov musia existovať s rowidmi pre všetky základné tabuľky v FROM zozname dotazu.
  • Nemôžete vytvoriť rýchlu obnovenú materializovanú predstavu z viacerých tabuliek s jednoduchými spojeniami, ktoré obsahujú stĺpec typu objektu v SELECT je vyhlásenie.

Rovnako metóda obnovenia, ktorú zvolíte, nebude optimálne efektívna, ak:

  • Definujúci dotaz používa vonkajšie spojenie, ktoré sa správa ako vnútorné spojenie. Ak definujúci dotaz obsahuje také spojenie, zvážte prepísanie definujúceho dotazu tak, aby obsahoval vnútorné spojenie.
  • The SELECT zoznam materializovaného pohľadu obsahuje výrazy na stĺpcoch z viacerých tabuliek.

5.3.8.6 Obmedzenia na rýchle obnovenie materializovaných pohľadov s agregáciami

Definujúce dotazy pre materializované pohľady s agregáciami alebo spojeniami majú nasledujúce obmedzenia na rýchle obnovenie:

Rýchle obnovenie je podporované pre oba ÁNO COMMIT a ÁNO POPTÁVKA materializované pohľady, avšak platia nasledujúce obmedzenia:

  • Všetky tabuľky v materializovanom pohľade musia mať logy materializovaných pohľadov a logy materializovaných pohľadov musia:
    • Obsahovať všetky stĺpce z tabuľky uvedenej v materializovanom pohľade.
    • Špecifikovať s ROWID a ZAHRNUTIE NOVÉ HODNOTY.
    • Špecifikovať SEKVENCIA klauzulu, ak sa očakáva, že tabuľka bude mať zmes vložení/priameho načítania, vymazaní a aktualizácií.

  • Iba SUMA, COUNT, AVG, STDDEV, VARIANCIA, MIN a MAX sú podporované pre rýchle obnovenie.
  • COUNT(*) musí byť špecifikovaný.
  • Agregátne funkcie musia vystupovať iba ako vonkajšia časť výrazu. To znamená, že agregáty ako AVG(AVG(x)) ale AVG(x)+ AVG(x) nie sú povolené.
  • Pre každý agregát ako AVG(expr), zodpovedajúci COUNT(expr) musí byť prítomný. Spoločnosť Oracle odporúča, aby SUM(expr) bola špecifikovaná.
  • Ak VARIANCIA(expr) ale STDDEV(expr) je špecifikovaný, COUNT(expr) a SUM(expr) musí byť špecifikovaný. Spoločnosť Oracle odporúča, aby SUM(expr *expr) bola špecifikovaná.
  • The SELECT stĺpec v definujúcom dotaze nemôže byť zložitý výraz s tabuľkami z viacerých základných tabuliek. Možným obchádzaním tohto je použiť vnorený materializovaný pohľad.
  • The SELECT zoznam musí obsahovať všetky SKUPINA PO stĺpce.
  • Materializovaný pohľad nie je založený na jednej alebo viacerých vzdialených tabuľkách.
  • Ak používate CHAR dátový typ v filtrovaných stĺpcoch logu materializovaného pohľadu, znaky sady znakov hlavnej lokality a materializovaného pohľadu musia byť rovnaké.
  • Ak má materializovaný pohľad jedno z nasledujúcich, rýchle obnovenie je podporované iba pri konvenčných dml vloženiach a priamych načítaniach.
    • Materializované pohľady s MIN ale MAX agregáciami
    • Materializované pohľady, ktoré majú SUM(expr) ale žiadne COUNT(expr)
    • Materializované pohľady bez COUNT(*)

    Takýto materializovaný pohľad sa nazýva iba-insert materializovaný pohľad.

  • Materializovaný pohľad s MAX ale MIN je rýchlo obnoviteľný po vymazaniach alebo zmiešaných DML príkazoch, ak nemá WHERE klauzuli.
    Max/Min rýchle obnovenie po vymazaniach alebo zmiešaných DML nemá rovnaké správanie ako prípad iba vložení. Vymazáva a prepočítava maximálne/minimálne hodnoty pre ovplyvnené skupiny. Musíte si byť vedomí jeho dopadu na výkon.
  • Materializované pohľady s pomenovanými pohľadmi alebo poddotazmi v FROM klauzule môžu byť rýchlo obnovené, ak môžu byť pohľady úplne zlúčené. Pre informácie o tom, ktoré pohľady sa zlúčia, pozri Oracle Database SQL Language Reference.
  • Ak nie sú žiadne vonkajšie spojenia, môžete mať ľubovoľné výbery a spojenia v WHERE klauzuli.
  • Materializované agregátne pohľady s vonkajšími spojeniami sú rýchlo obnoviteľné po bežnom DML a priamych načítaniach, pokiaľ bol upravený iba vonkajší tabulka. Taktiež musia existovať jedinečné obmedzenia na spojovacích stĺpcoch vnútornej spojovacej tabuľky. Ak sú prítomné vonkajšie spojenia, všetky spojenia musia byť prepojené Aa musia používať rovnostný (=) operátor.
  • Pre materializované pohľady s CUBE, ROLLUP, skupinovými súbormi alebo ich zlučovaním platia nasledujúce obmedzenia:
    • The SELECT zoznam by mal obsahovať rozlišovač skupín, ktorý môže byť buď GROUPING_ID funkcia na všetkých SKUPINA PO výrazoch alebo GROUPING funkcie pre každý SKUPINA PO výraz. Napríklad, ak je SKUPINA PO klauzula materializovaného pohľadu „SKUPINA PO CUBE(a, b)“tak zoznam by mal obsahovať buď „ SELECT GROUPING_ID(a, b)“alebo „GROUPING(a)GROUPING(b) A “ pre to, aby bol materializovaný pohľad rýchlo obnoviteľný.nemal by viesť k žiadnym duplicitným skupinám. Napríklad, „
    • SKUPINA PO GROUP BY a, ROLLUP(a, b)“nie je rýchlo obnoviteľné, pretože vedie k duplicitným skupinám „(a), (a, b), A (a)5.3.8.7 Obmedzenia na rýchlu obnovu materializovaných pohľadov s UNION ALL«.

Materializované pohľady s

UNION operátor podporujú ALL rázovú obnovu RÝCHLO možnosť, ak sú splnené nasledujúce podmienky: Definujúci dotaz musí mať

  • operátor na vrcholnej úrovni. operátor podporujú ALL operátor nemôže byť zabudovaný do poddotazu, s jednou výnimkou: táto

    The operátor podporujú ALL môže byť v poddotaze v operátor podporujú ALL klauzuli, pokiaľ je definujúci dotaz vo forme FROM SELECT * FROM (pohľad alebo poddotaz s ) ako v nasledujúcom príklade: operátor podporujú ALLVYTVORIŤ POHĽAD view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker Zákazníci z c, kde c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker Zákazníci z c, kde c.cust_last_name = 'Jones');VYTVORIŤ MATERIALIZOVANÝ POHĽAD unionall_inside_view_mv RÝCHLO OBNOVIŤ NA POŽIADANIE AS SELECT * FROM view_with_unionall;

    Všimnite si, že pohľad
    

    view_with_unionall spĺňa požiadavky na rýchlu obnovu. Každý dotazový blok v

  • dotaze musí spĺňať požiadavky rýchlo obnoviteľného materializovaného pohľadu s agregátmi alebo rýchlo obnoviteľného materializovaného pohľadu s spojeniami. operátor podporujú ALL Na tabuľkách musia byť vytvorené príslušné záznamy materializovaných pohľadov, ako je požadované pre zodpovedajúci typ rýchlo obnoviteľného materializovaného pohľadu.

    Všimnite si, že Oracle Database tiež umožňuje špeciálny prípad materializovaného pohľadu z jedinej tabuľky so spojeniami, pokiaľ bol obmedzený stĺpec zahrnutý do
    zoznamu a v záznamoch materializovaného pohľadu. To je znázornené v definujúcom dotaze pohľadu ROWID zoznam každého dotazu musí obsahovať SELECT marker a spĺňa požiadavky na rýchlu obnovu..

  • The SELECT stĺpec musí mať jedinečnú konštantnú číselnú alebo reťazcovú hodnotu v každej operátor podporujú ALL vetve. Ďalej, markerový stĺpec musí byť v rovnakom poradí v operátor podporujú ALL zozname každého dotazu bloku. Viď „ operátor podporujú ALL UNION ALL Marker a Otázka prepisovať SELECT “ pre viac informácií omarkeroch.Niektoré funkcie, ako vonkajšie spojenia, dotazy agregovaných materializovaných pohľadov iba na vloženie a vzdialené tabuľky, nie sú podporované pre materializované pohľady s operátor podporujú ALL . Všimnite si však, že materializované pohľady použité v replikácii, ktoré neobsahujú spojenia alebo agregáty, môžu byť rýchlo obnovené, keď
  • alebo vzdialené tabuľky sú použité. operátor podporujú ALLInicializačný parameter kompatibility musí byť nastavený na 9.2.0 alebo vyšší, aby sa vytvoril rýchlo obnoviteľný materializovaný pohľad s operátor podporujú ALL alebo vzdialené tabuľky sú používané.
  • Iniciačná parameter kompatibility musí byť nastavený na 9.2.0 alebo vyšší pre vytvorenie rýchlo obnoviteľného materializovaného pohľadu s operátor podporujú ALL.

Nechcem uraziť fanúšikov Oracle, ale podľa ich zoznamu obmedzení to vyzerá, že tento mechanizmus nebol vyvinutý v súlade s všeobecnými pravidlami, ale pravdepodobne tisíckami indických programátorov, kde každému pridelili vlastnú časť a každý prispel svojou troškou. Používanie tohto mechanizmu pre skutočnú logiku je ako chodenie po mínovom poli. Kedykoľvek sa môžete stretnúť s mínou, keď narazíte na jedno z nejasných obmedzení. Ako to funguje — to je tiež samostatná téma, ale to presahuje rámec tohto článku.

Microsoft SQL Server

Dodatočné požiadavky

Okrem požiadaviek na nastavenia SET a deterministické funkcie musia byť splnené nasledujúce požiadavky:

  • Užívateľ, ktorý vykonáva CREATE INDEX musí byť vlastníkom pohľadu.
  • Pri vytváraní indexu musíte nastaviť IGNORE_DUP_KEY vo vypnutej polohe (predvoľba).
  • Tabuľky musia byť odkazované pomocou dvojčíslicových názvov, schema.tablename v definícii pohľadu.
  • Užívateľské definované funkcie odkazované v pohľade musia byť vytvorené s použitím s možnosťou WITH SCHEMABINDING. Akékoľvek užívateľské definované funkcie, ktoré sú odkazované v pohľade, musia byť uvedené pomocou dvojčíslicových názvov,
  • <schéma> <funkcia>.Prístupová vlastnosť užívateľskej definovanej funkcie musí byť.
  • NO SQL , a externá prístupová vlastnosť musí byťNO Funkcie CLR môžu byť zahrnuté v select zozname pohľadu, ale nemôžu byť súčasťou definície kľúča clustered indexu. Funkcie CLR sa nemôžu objaviť v WHERE klauzule pohľadu alebo ON klauzule JOIN operácie v pohľade..
  • Funkcie CLR a metódy užívateľských definovaných typov CLR používané v definícii pohľadu musia mať nastavené vlastnosti, ako sú uvedené v nasledujúcej tabuľke.
  • Vlastnosť

    Poznámka
    DETERMINISTIC = TRUE

    Musí byť výslovne deklarovaná ako atribút metódy Microsoft .NET Framework.
    PRECISE = TRUE

    Musí byť výslovne deklarovaná ako atribút metódy .NET Framework.
    DATA ACCESS = NO SQL

    Stanovené nastavením atribútu DataAccess na hodnotu DataAccessKind.None a atribútu SystemDataAccess na hodnotu SystemDataAccessKind.None.
    EXTERNAL ACCESS = NO

    Tento vlastnosť predvolene platí na NO pre CLR rutiny.
    Pohľad musí byť vytvorený pomocou

  • Pohľad musí odkazovať iba na základné tabuľky, ktoré sú v tej istej databáze ako pohľad. Pohľad nemôže odkazovať na iné pohľady. s možnosťou WITH SCHEMABINDING. Akékoľvek užívateľské definované funkcie, ktoré sú odkazované v pohľade, musia byť uvedené pomocou dvojčíslicových názvov,
  • Výberový príkaz v definícii pohľadu nesmie obsahovať nasledujúce prvky Transact-SQL:
  • Funkcie ROWSET (

    COUNT
    OPENDATASOURCEOPENQUERY, OPENROWSET, , AOPENXML VONKAJŠIE)
    spojenia ( ĽAVÉPRAVÉ, CELKOVÉ, alebo Odvozená tabuľka (definovaná určením)

    príkazu v SELECT klauzule) FROM Sebapojenia
    Určenie stĺpcov pomocou
    SELECT * SELECT <názov_tabulky>.* ale DISTINCT

    STDEV
    STDEVP, VAR, VARP, Spoločný výraz tabuľky (CTE), alebo AVG
    ntext

    float1, text, XML, obrázok, filestream, alebo stĺpce Poddotaz
    OVER
    klauzula, ktorá obsahuje funkcie hodnotenia alebo agregátu Vlastnosti full-textu (

    CONTAINSFREETEXT, funkcia, ktorá odkazuje na nullable výraz)
    SUMA PORADIE PODĽA
    CLR užívateľská agregovaná funkcia

    TOP
    SETY SKUPINOVANIA
    CUBE, ROLLUP, alebo operátory EXCEPT

    MIN, MAX
    operátor podporujú, INTERSECT, alebo TABUĽOVÝ VZOR EXCEPT
    Tabuľkové premenne

    VONKAJŠÍ APLIKOVANIE
    OTÁČANIE ale CROSS APPLY
    OBRACANIE, Súpravy zriedkavých stĺpcov

    Inline (TVF) alebo viac-výrokové funkcie tabuľkových hodnôt (MSTVF)
    OFFSET
    CHECKSUM_AGG

    1 Indexed view môže obsahovať

    stĺpce; avšak takéto stĺpce nemôžu byť zahrnuté v kľúči clustered indexu. float VIDIEŤ

  • Ak je prítomný, definícia pohľadu musí obsahovať COUNT_BIG(*) a nesmie obsahovať . Tieto HAVINGobmedzenia sa vzťahujú iba na definíciu indexed view. Dotaz môže použiť indexed view vo svojom vykonávacom pláne, aj ak nespĺňa tieto je prítomný, definícia pohľadu musí obsahovať obmedzenia. je prítomný, definícia pohľadu musí obsahovať Ak definícia pohľadu obsahuje
  • klauzulu, kľúč jedinečného clustered indexu môže odkazovať iba na stĺpce uvedené v je prítomný, definícia pohľadu musí obsahovať klauzula, kľúč jedinečného zlúčeného indexu môže odkazovať iba na stĺpce špecifikované v je prítomný, definícia pohľadu musí obsahovať klauzuli.

Tu je jasné, že Indov to nepriťahovalo, pretože sa rozhodli ísť podľa schémy „urobíme málo, ale dobre“. To znamená, že majú viac mín na poli, ale ich umiestnenie je priesvitnejšie. Najviac znepokojuje toto obmedzenie:

Výberový príkaz v definícii pohľadu nesmie obsahovať nasledujúce prvky Transact-SQL:

V našej terminológii to znamená, že funkcia nemôže odkazovať na inú materializovanú funkciu. To podkopáva celú ideológiu.
Toto obmedzenie (a ďalej v texte) výrazne znižuje možnosti použitia:

Funkcie ROWSET (

COUNT
OPENDATASOURCEOPENQUERY, OPENROWSET, , AOPENXML VONKAJŠIE)
spojenia ( ĽAVÉPRAVÉ, CELKOVÉ, alebo Odvozená tabuľka (definovaná určením)

príkazu v SELECT klauzule) FROM Sebapojenia
Určenie stĺpcov pomocou
SELECT * SELECT <názov_tabulky>.* ale DISTINCT

STDEV
STDEVP, VAR, VARP, Spoločný výraz tabuľky (CTE), alebo AVG
ntext

float1, text, XML, obrázok, filestream, alebo stĺpce Poddotaz
OVER
klauzula, ktorá obsahuje funkcie hodnotenia alebo agregátu Vlastnosti full-textu (

CONTAINSFREETEXT, funkcia, ktorá odkazuje na nullable výraz)
SUMA PORADIE PODĽA
CLR užívateľská agregovaná funkcia

TOP
SETY SKUPINOVANIA
CUBE, ROLLUP, alebo operátory EXCEPT

MIN, MAX
operátor podporujú, INTERSECT, alebo TABUĽOVÝ VZOR EXCEPT
Tabuľkové premenne

VONKAJŠÍ APLIKOVANIE
OTÁČANIE ale CROSS APPLY
OBRACANIE, Súpravy zriedkavých stĺpcov

Inline (TVF) alebo viac-výrokové funkcie tabuľkových hodnôt (MSTVF)
OFFSET
CHECKSUM_AGG

1 Indexed view môže obsahovať

OUTER JOINS, UNION, ORDER BY a ďalšie sú zakázané. Možno by bolo jednoduchšie uviesť, čo je povolené, ako čo nie je. Zoznam by pravdepodobne bol oveľa kratší.

Na záver: obrovský počet obmedzení v každom (poznamenávam, komerčnom) DBMS vs. žiadne (okrem jedného logického, nie technického) v technológii LGPL. Je však potrebné poznamenať, že realizácia tohto mechanizmu v relačnej logike je trochu zložitejšia ako v popísanej funkčnej.

Implementácia

Ako to funguje? Ako „virtuálna mašina“ sa používa PostgreSQL. Uvnitř je zložitý algoritmus, ktorý sa zaoberá výstavbou požiadaviek. Tu je zdrojový kód. A tam nie je len veľká sústava heurisiek s množstvom podmienok. Takže ak máte niekoľko mesiacov na štúdium, môžete sa pokúsiť preniknúť do architektúry.

Funguje to efektívne? Dosť efektívne. Bohužiaľ, dokázať to je ťažké. Môžem len povedať, že ak sa pozriete na tisíce požiadaviek, ktoré existujú vo veľkých aplikáciách, priemerne sú efektívnejšie ako u dobrého vývojára. Skvelý SQL programátor môže napísať akúkoľvek požiadavku efektívnejšie, ale na tisíckach požiadaviek jednoducho nebude mať motiváciu ani čas robiť to. Jediná vec, ktorú teraz môžem uviesť ako dôkaz efektivity, je, že na báze platformy postavenej na tomto DBMS funguje niekoľko projektov ERP systémov, v ktorých je tisíce rôznych MATERIALIZED funkcií, s tisícmi používateľov a terabajtovými databázami so stovkami miliónov záznamov, fungujúcich na bežnom dvojprocesorovom serveri. Každý, kto chce, môže overiť/vyvrátiť efektivitu stiahnutím platformu a PostgreSQL, zapnutím logovania SQL požiadaviek a pokusom zmeniť tam logiku a údaje.

V nasledujúcich článkoch sa tiež poviem o tom, ako je možné zaviesť obmedzenia na funkcie, prácu so sedením zmien a mnoho ďalšieho.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster