Vyvažovanie zapisuje a číta v databáze

Vyvažovanie zapisuje a číta v databáze
V predošlom článok Popísal som koncepciu a implementáciu databázy postavenej na základe funkcií, nie tabuliek a polí ako v relačných databázach. Poskytol mnoho príkladov ukazujúcich výhody tohto prístupu oproti klasickému. Mnohí ich považovali za nedostatočne presvedčivé.

V tomto článku ukážem, ako vám tento koncept umožňuje rýchlo a pohodlne vyvažovať zápisy a čítania do databázy bez akejkoľvek zmeny v prevádzkovej logike. Podobnú funkcionalitu sa pokúšali implementovať v moderných komerčných DBMS (najmä Oracle a Microsoft SQL Server). Na konci článku ukážem, že to, čo urobili, mierne povedané, veľmi nevyšlo.

Popis

Ako predtým, pre lepšie pochopenie začnem popis príkladmi. Povedzme, že potrebujeme implementovať logiku, ktorá vráti zoznam oddelení s počtom zamestnancov v nich a ich celkovou mzdou.

Vo funkčnej databáze by to vyzeralo takto:

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

Zložitosť vykonania tohto dotazu v akomkoľvek DBMS bude ekvivalentná O (počet zamestnancov)pretože tento výpočet vyžaduje naskenovať celú tabuľku zamestnancov a následne ich zoskupiť podľa oddelení. V závislosti od zvoleného plánu bude existovať aj nejaký malý (domnievame sa, že zamestnancov je oveľa viac ako oddelení). O (zaznamenaný počet zamestnancov) alebo O (počet oddelení) na zoskupovanie a pod.

Je jasné, že réžia vykonávania môže byť v rôznych DBMS odlišná, ale zložitosť sa nijako nezmení.

V navrhovanej implementácii funkčný DBMS vygeneruje jeden poddotaz, ktorý vypočíta požadované hodnoty pre oddelenie a potom vytvorí JOIN s tabuľkou oddelení, aby získal názov. Pre každú funkciu je však pri deklarácii možné nastaviť špeciálny fix MATERIALIZED. Systém automaticky vytvorí zodpovedajúce pole pre každú takúto funkciu. Pri zmene hodnoty funkcie sa v tej istej transakcii zmení aj hodnota poľa. Pri prístupe k tejto funkcii sa sprístupní vopred vypočítané pole.

Najmä ak nastavíte funkcie MATERIALIZED countEmployees и mzdaSum, následne do tabuľky so zoznamom oddelení pribudnú dve polia, v ktorých bude uložený počet zamestnancov a ich celková mzda. Vždy, keď dôjde k zmene zamestnancov, ich platov alebo príslušnosti k oddeleniam, systém automaticky zmení hodnoty týchto polí. Vyššie uvedený dotaz bude pristupovať priamo k týmto poliam a bude vykonaný v O (počet oddelení).

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

Príklad:

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

Táto funkcia je definovaná pre nekonečný počet hodnôt N (vhodná je napríklad akákoľvek záporná hodnota). Preto naň nemôžete dať MATERIALIZED. Ide teda o logické obmedzenie, nie technické (teda nie preto, že by sme ho nevedeli implementovať). V opačnom prípade neexistujú žiadne obmedzenia. Môžete použiť zoskupenia, triedenie, AND a OR, PARTITION, rekurziu atď.

Napríklad v probléme 2.2 predchádzajúceho článku môžete použiť MATERIALIZED na obe funkcie:

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;

Systém sám vytvorí jednu tabuľku s typovými kľúčmi Zákazník, Produkt и INTEGER, pridá doň dve polia a aktualizuje hodnoty polí v nich so všetkými zmenami. Keď sa uskutočnia ďalšie volania týchto funkcií, nebudú sa vypočítavať, ale hodnoty sa načítajú z príslušných polí.

Pomocou tohto mechanizmu sa môžete napríklad zbaviť rekurzie (CTE) v dotazoch. Zvážte najmä skupiny, ktoré tvoria strom pomocou vzťahu dieťa/rodič (každá skupina má prepojenie na svojho rodiča):

parent = DATA Group (Group);

Vo funkčnej databáze môže byť rekurzná logika špecifikovaná takto:

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;

Keďže pre funkciu je rodič je označený MATERIALIZOVANÝ, potom sa k nemu vytvorí tabuľka s dvoma kľúčmi (skupinami), v ktorej pole je rodič bude pravdivé iba vtedy, ak je prvý kľúč potomkom druhého. Počet záznamov v tejto tabuľke sa bude rovnať počtu skupín vynásobenému priemernou hĺbkou stromu. Ak potrebujete napríklad spočítať počet potomkov určitej skupiny, môžete použiť túto funkciu:

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

V dotaze SQL nebude CTE. Namiesto toho bude jednoduchý GROUP BY.

Pomocou tohto mechanizmu môžete tiež ľahko denormalizovať databázu, ak je to potrebné:

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

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

Pri volaní funkcie dáta pre riadok objednávky sa pole, pre ktoré existuje index, načíta z tabuľky s riadkami objednávky. Keď sa dátum objednávky zmení, systém sám automaticky prepočíta denormalizovaný dátum v riadku.

Výhody

Načo je celý tento mechanizmus? V klasických DBMS, bez prepisovania dotazov, môže vývojár alebo DBA meniť iba indexy, určovať štatistiky a povedať plánovačovi dotazov, ako ich vykonať (a HINTy sú dostupné len v komerčných DBMS). Bez ohľadu na to, ako veľmi sa snažia, nebudú môcť dokončiť prvý dotaz v článku v O (počet oddelení) bez zmeny dopytov alebo pridávania spúšťačov. V navrhovanej schéme vo fáze vývoja nemusíte premýšľať o štruktúre ukladania údajov a o tom, ktoré agregácie použiť. To všetko sa dá jednoducho meniť za behu, priamo v prevádzke.

V praxi to vyzerá takto. Niektorí ľudia rozvíjajú logiku priamo na základe danej úlohy. Nerozumejú algoritmom a ich zložitosti, ani realizačným plánom, ani typom spojení, ani iným technickým komponentom. Títo ľudia sú viac obchodnými analytikmi ako vývojármi. Potom to všetko ide do testovania alebo prevádzky. Umožňuje zaznamenávanie dlhotrvajúcich dopytov. Keď sa zistí dlhý dopyt, iní ľudia (technickejší - v podstate DBA) sa rozhodnú povoliť MATERIALIZED na nejakej medziľahlej funkcii. To trochu spomalí nahrávanie (keďže vyžaduje aktualizáciu dodatočného poľa v transakcii). Výrazne sa však zrýchľuje nielen tento dopyt, ale aj všetky ostatné, ktoré túto funkciu využívajú. Rozhodnúť sa, ktorú funkciu zhmotniť, je zároveň pomerne jednoduché. Dva hlavné parametre: počet možných vstupných hodnôt (to znamená, koľko záznamov bude v príslušnej tabuľke) a ako často sa používa v iných funkciách.

analógy

Moderné komerčné DBMS majú podobné mechanizmy: MATERIALIZOVANÉ ZOBRAZENIE s FAST REFRESH (Oracle) a INDEXEDNÉ ZOBRAZENIE (Microsoft SQL Server). V PostgreSQL nie je možné MATERIALIZED VIEW aktualizovať v transakcii, ale iba na požiadanie (a aj to s veľmi prísnymi obmedzeniami), takže to neuvažujeme. Ale majú niekoľko problémov, ktoré výrazne obmedzujú ich použitie.

Po prvé, materializáciu môžete povoliť iba vtedy, ak ste už vytvorili bežný VIEW. V opačnom prípade budete musieť prepísať zostávajúce požiadavky na prístup k novovytvorenému pohľadu, aby ste mohli použiť túto materializáciu. Alebo nechajte všetko tak, ale bude to prinajmenšom neúčinné, ak existujú určité už vopred vypočítané údaje, ale mnohé dopyty ich nie vždy používajú, ale prepočítavajú.

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

veštec

5.3.8.4 Všeobecné obmedzenia rýchleho obnovenia

Definujúci dotaz materializovaného zobrazenia je obmedzený takto:

  • Zhmotnený pohľad nesmie obsahovať odkazy na neopakujúce sa výrazy ako napr SYSDATE a ROWNUM.
  • Zhmotnený pohľad nesmie obsahovať odkazy na RAW or LONG RAW dátové typy.
  • Nemôže obsahovať a SELECT vypísať poddotaz.
  • Nemôže obsahovať analytické funkcie (napr. RANK) v SELECT klauzula.
  • Nemôže odkazovať na tabuľku, na ktorej je an XMLIndex index je definovaný.
  • Nemôže obsahovať a MODEL klauzula.
  • Nemôže obsahovať a HAVING klauzula s poddotazom.
  • Nemôže obsahovať vnorené dopyty, ktoré majú ANY, ALL, Alebo NOT EXISTS.
  • Nemôže obsahovať a [START WITH …] CONNECT BY klauzula.
  • Nemôže obsahovať viacero podrobných tabuliek na rôznych miestach.
  • ON COMMIT materializované zobrazenia nemôžu mať vzdialené tabuľky podrobností.
  • Vnorené materializované zobrazenia musia mať spojenie alebo súhrn.
  • Zhmotnené zobrazenia spojenia a zhmotnené súhrnné zobrazenia s a GROUP BY klauzula nemôže vyberať z tabuľky usporiadanej podľa indexu.

5.3.8.5 Obmedzenia rýchleho obnovenia zhmotnených zobrazení iba s pripojením

Definovanie dotazov pre materializované zobrazenia iba so spojeniami a bez agregátov má nasledujúce obmedzenia rýchleho obnovenia:

  • Všetky obmedzenia od «Všeobecné obmedzenia rýchleho obnovenia".
  • Nemôžu mať GROUP BY doložky alebo agregáty.
  • Rad všetkých stolov v FROM zoznam sa musí objaviť v SELECT zoznam dopytu.
  • Protokoly materializovaných zobrazení musia existovať s riadkami pre všetky základné tabuľky v FROM zoznam dopytu.
  • Nemôžete vytvoriť rýchlo obnoviteľný materializovaný pohľad z viacerých tabuliek s jednoduchými spojeniami, ktoré obsahujú stĺpec typu objektu v SELECT vyhlásenia.

Spôsob obnovenia, ktorý zvolíte, nebude optimálne účinný, ak:

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

5.3.8.6 Obmedzenia rýchleho obnovenia materializovaných zobrazení s agregátmi

Definovanie dotazov pre materializované zobrazenia pomocou agregátov alebo spojení má nasledujúce obmedzenia rýchleho obnovenia:

Rýchle obnovenie je podporované pre obe ON COMMIT a ON DEMAND zhmotnené názory, platia však tieto obmedzenia:

  • Všetky tabuľky v materializovanom zobrazení musia mať denníky materializovaných zobrazení a denníky materializovaných zobrazení musia:
    • Obsahuje všetky stĺpce z tabuľky, na ktorú odkazuje materializované zobrazenie.
    • Špecifikujte pomocou ROWID a INCLUDING NEW VALUES.
    • Určite SEQUENCE klauzulu, ak sa očakáva, že tabuľka bude obsahovať kombináciu vložení/priameho načítania, odstránenia a aktualizácií.

  • Iba SUM, COUNT, AVG, STDDEV, VARIANCE, MIN a MAX sú podporované pre rýchle obnovenie.
  • COUNT(*) musí byť špecifikované.
  • Agregátne funkcie sa musia vyskytovať len ako vonkajšia časť výrazu. Teda agregáty ako napr AVG(AVG(x)) or AVG(x)+ AVG(x) nie sú dovolené.
  • Pre každý agregát ako napr AVG(expr), zodpovedajúce COUNT(expr) musí byť prítomný. Oracle to odporúča SUM(expr) byť špecifikovaný.
  • If VARIANCE(expr) or STDDEV(expr) je špecifikovaný, COUNT(expr) a SUM(expr) musí byť špecifikované. Oracle to odporúča SUM(expr *expr) byť špecifikovaný.
  • SELECT stĺpec v definujúcom dotaze nemôže byť zložitý výraz so stĺpcami z viacerých základných tabuliek. Možným riešením tohto problému je použitie vnoreného materializovaného zobrazenia.
  • SELECT zoznam musí obsahovať všetky GROUP BY stĺpy.
  • Materializovaný pohľad nie je založený na jednej alebo viacerých vzdialených tabuľkách.
  • Ak použijete a CHAR typu údajov v stĺpcoch filtra protokolu materializovaného zobrazenia, znakové sady hlavnej lokality a materializovaného zobrazenia musia byť rovnaké.
  • Ak má materializovaný pohľad jednu z nasledujúcich možností, rýchle obnovenie je podporované iba na konvenčných vložkách DML a priamom načítaní.
    • Zhmotnené pohľady s MIN or MAX agregáty
    • Zhmotnené pohľady, ktoré majú SUM(expr) ale nie COUNT(expr)
    • Zhmotnené pohľady bez COUNT(*)

    Takýto zhmotnený pohľad sa nazýva len vložkový zhmotnený pohľad.

  • Zhmotnený pohľad s MAX or MIN je rýchlo obnoviteľný po vymazaní alebo zmiešaných príkazoch DML, ak nemá a WHERE klauzula.
    Rýchle obnovenie max/min po odstránení alebo zmiešanom DML nemá rovnaké správanie ako v prípade iba vloženia. Vymaže a prepočíta maximálne/min hodnoty pre dotknuté skupiny. Musíte si uvedomiť jeho vplyv na výkon.
  • Materializované zobrazenia s pomenovanými zobrazeniami alebo poddotazmi v FROM klauzulu možno rýchlo obnoviť za predpokladu, že pohľady možno úplne zlúčiť. Informácie o tom, ktoré zobrazenia sa zlúčia, nájdete v časti Referenčný jazyk SQL databázy Oracle.
  • Ak neexistujú žiadne vonkajšie spojenia, môžete mať ľubovoľné výbery a spojenia WHERE klauzula.
  • Zhmotnené agregované pohľady s vonkajšími spojmi sa dajú rýchlo obnoviť po konvenčnom DML a priamom zaťažení za predpokladu, že bola upravená iba vonkajšia tabuľka. Tiež musia existovať jedinečné obmedzenia pre stĺpce spojenia vnútornej tabuľky spojení. Ak existujú vonkajšie spojenia, všetky spojenia musia byť spojené pomocou ANDs a musia použiť rovnosť (=) operátor.
  • Pre zhmotnené pohľady s CUBE, ROLLUP, zoskupovanie množín alebo ich zreťazenie, platia nasledujúce obmedzenia:
    • SELECT zoznam by mal obsahovať rozlišovač zoskupení, ktorý môže byť a GROUPING_ID fungovať na všetkých GROUP BY výrazy resp GROUPING funguje jedna pre každého GROUP BY výraz. Napríklad, ak GROUP BY klauzula materializovaného pohľadu je „GROUP BY CUBE(a, b)", potom SELECT zoznam by mal obsahovať buď "GROUPING_ID(a, b)» alebo «GROUPING(a) AND GROUPING(b)» aby bol zhmotnený pohľad rýchlo obnoviteľný.
    • GROUP BY by nemalo viesť k žiadnym duplicitným zoskupeniam. Napríklad, "GROUP BY a, ROLLUP(a, b)"nie je rýchlo obnoviteľné, pretože vedie k duplicitným zoskupeniam"(a), (a, b), AND (a)".

5.3.8.7 Obmedzenia rýchleho obnovenia materializovaných zobrazení s UNION ALL

Zhmotnené pohľady s UNION ALL nastaviť podporu operátora REFRESH FAST možnosť, ak sú splnené tieto podmienky:

  • Definujúci dotaz musí mať UNION ALL operátora na najvyššej úrovni.

    UNION ALL Operátor nemôže byť vložený do poddotazu, s jednou výnimkou: The UNION ALL môže byť v poddotaze v FROM za predpokladu, že definujúci dotaz má formu SELECT * FROM (zobraziť alebo poddotaz s UNION ALL) ako v nasledujúcom príklade:

    CREATE VIEW view_with_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 'Jones'); VYTVORIŤ MATERIALIZOVANÉ ZOBRAZENIE unionall_inside_view_mv RÝCHLE OBNOVENIE NA POŽIADANIE AKO VÝBER * FROM view_with_unionall;
    

    Všimnite si, že pohľad view_with_unionall spĺňa požiadavky na rýchle obnovenie.

  • Každý blok dopytu v UNION ALL dotaz musí spĺňať požiadavky rýchleho obnoviteľného materializovaného zobrazenia s agregátmi alebo rýchlo obnoviteľného materializovaného zobrazenia so spojeniami.

    Príslušné protokoly materializovaného zobrazenia musia byť vytvorené na tabuľkách, ako sa to vyžaduje pre zodpovedajúci typ rýchlo obnoviteľného materializovaného zobrazenia.
    Všimnite si, že databáza Oracle umožňuje aj špeciálny prípad zhmotneného zobrazenia jednej tabuľky so spojeniami len za predpokladu, že ROWID stĺpec bol zahrnutý do SELECT zoznam a v denníku materializovaného zobrazenia. Toto je zobrazené v definujúcom dotaze pohľadu view_with_unionall.

  • SELECT zoznam každého dotazu musí obsahovať a UNION ALL značka a UNION ALL Každý stĺpec musí mať samostatnú konštantnú číselnú alebo reťazcovú hodnotu UNION ALL pobočka. Ďalej sa stĺpec značky musí objaviť v rovnakej poradovej polohe v SELECT zoznam každého bloku dotazu. Pozri "UNION ALL prepis značiek a dotazov» pre viac informácií o UNION ALL značkovače.
  • Niektoré funkcie, ako sú vonkajšie spojenia, len vložiť agregované dotazy materializovaného zobrazenia a vzdialené tabuľky nie sú podporované pre materializované zobrazenia s UNION ALL. Upozorňujeme však, že materializované zobrazenia používané pri replikácii, ktoré neobsahujú spojenia alebo agregáty, sa môžu rýchlo obnoviť, keď UNION ALL alebo sa používajú vzdialené stoly.
  • Parameter inicializácie kompatibility musí byť nastavený na 9.2.0 alebo vyšší, aby sa vytvoril rýchlo obnoviteľný materializovaný pohľad s UNION ALL.

Nechcem uraziť fanúšikov Oracle, ale súdiac podľa ich zoznamu obmedzení sa zdá, že tento mechanizmus nebol napísaný vo všeobecnom prípade pomocou nejakého modelu, ale tisíckami Indov, kde každý dostal príležitosť napísali svoju vlastnú vetvu a každý z nich urobil, čo mohol. Použitie tohto mechanizmu na skutočnú logiku je ako prechádzka mínovým poľom. Mínu môžete získať kedykoľvek stlačením jedného z nezrejmých obmedzení. Ako to funguje, je tiež samostatná otázka, ale to je nad rámec tohto článku.

Microsoft SQL Server

Ďalšie požiadavky

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

  • Používateľ, ktorý vykonáva CREATE INDEX musí byť vlastníkom zobrazenia.
  • Keď vytvoríte index, IGNORE_DUP_KEY musí byť nastavená na OFF (predvolené nastavenie).
  • Tabuľky musia byť odkazované dvojdielnymi názvami, schéma.názov tabuľky v definícii pohľadu.
  • Používateľom definované funkcie, na ktoré sa odkazuje v zobrazení, musia byť vytvorené pomocou WITH SCHEMABINDING možnosť.
  • Všetky používateľom definované funkcie, na ktoré sa odkazuje v zobrazení, musia byť odkazované dvojdielnymi názvami, ..
  • Vlastnosť prístupu k údajom funkcie definovanej používateľom musí byť NO SQLa vlastnosť externého prístupu musí byť NO.
  • Funkcie CLR (Common language runtime) sa môžu objaviť vo výberovom zozname zobrazenia, ale nemôžu byť súčasťou definície klastrovaného indexového kľúča. Funkcie CLR sa nemôžu objaviť v klauzule WHERE zobrazenia alebo v klauzule ON operácie JOIN v zobrazení.
  • Funkcie CLR a metódy užívateľom definovaných typov CLR použité v definícii pohľadu musia mať nastavené vlastnosti, ako je uvedené v nasledujúcej tabuľke.

    Majetok
    Poznámky

    DETERMINISTICKÝ = PRAVDA
    Musí byť explicitne deklarovaný ako atribút metódy Microsoft .NET Framework.

    PRESNÉ = PRAVDA
    Musí byť explicitne deklarovaný ako atribút metódy .NET Framework.

    PRÍSTUP K ÚDAJOM = BEZ SQL
    Určené nastavením atribútu DataAccess na DataAccessKind.None a atribútu SystemDataAccess na SystemDataAccessKind.None.

    EXTERNÝ PRÍSTUP = NIE
    Táto vlastnosť je štandardne nastavená na NO pre rutiny CLR.

  • Pohľad musí byť vytvorený pomocou WITH SCHEMABINDING možnosť.
  • Pohľad musí odkazovať len na základné tabuľky, ktoré sú v rovnakej databáze ako pohľad. Pohľad nemôže odkazovať na iné pohľady.
  • Príkaz SELECT v definícii pohľadu nesmie obsahovať nasledujúce prvky Transact-SQL:

    COUNT
    Funkcie ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, AND OPENXML)
    OUTER sa pripája (LEFT, RIGHT, Alebo FULL)

    Odvodená tabuľka (definovaná zadaním a SELECT vyhlásenie v FROM doložka)
    Vlastné spojenia
    Určenie stĺpcov pomocou SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, Alebo AVG
    Bežný tabuľkový výraz (CTE)

    vznášať sa1, text, ntext, obraz, XML, Alebo filestream stĺpce
    Poddotaz
    OVER klauzula, ktorá zahŕňa funkcie klasifikácie alebo agregácie okien

    Fulltextové predikáty (CONTAINS, FREETEXT)
    SUM funkcia, ktorá odkazuje na výraz s možnosťou null
    ORDER BY

    Používateľom definovaná agregačná funkcia CLR
    TOP
    CUBE, ROLLUP, Alebo GROUPING SETS Operátori

    MIN, MAX
    UNION, EXCEPT, Alebo INTERSECT Operátori
    TABLESAMPLE

    Tabuľkové premenné
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Riedke sady stĺpcov
    Vložené (TVF) alebo viacpríkazové tabuľkové funkcie (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Indexované zobrazenie môže obsahovať vznášať sa stĺpce; takéto stĺpce však nemožno zahrnúť do klastrovaného indexového kľúča.

  • If GROUP BY je prítomná, definícia VIEW musí obsahovať COUNT_BIG(*) a nesmie obsahovať HAVING. Tieto GROUP BY obmedzenia sa vzťahujú len na definíciu indexovaného zobrazenia. Dotaz môže použiť indexované zobrazenie vo svojom pláne vykonávania, aj keď ich nespĺňa GROUP BY obmedzenia.
  • Ak definícia pohľadu obsahuje a GROUP BY klauzula, kľúč jedinečného klastrovaného indexu môže odkazovať iba na stĺpce špecifikované v GROUP BY klauzula.

Tu je jasné, že Indiáni neboli zapojení, pretože sa rozhodli urobiť to podľa schémy „urobíme málo, ale dobre“. To znamená, že majú na ihrisku viac mín, ale ich umiestnenie je transparentnejšie. Najviac sklamaním je toto obmedzenie:

Pohľad musí odkazovať len na základné tabuľky, ktoré sú v rovnakej databáze ako pohľad. Pohľad nemôže odkazovať na iné pohľady.

V našej terminológii to znamená, že funkcia nemôže pristupovať k inej materializovanej funkcii. To v zárodku obmedzuje všetku ideológiu.
Toto obmedzenie (a ďalej v texte) tiež výrazne znižuje prípady použitia:

Príkaz SELECT v definícii pohľadu nesmie obsahovať nasledujúce prvky Transact-SQL:

COUNT
Funkcie ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, AND OPENXML)
OUTER sa pripája (LEFT, RIGHT, Alebo FULL)

Odvodená tabuľka (definovaná zadaním a SELECT vyhlásenie v FROM doložka)
Vlastné spojenia
Určenie stĺpcov pomocou SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, Alebo AVG
Bežný tabuľkový výraz (CTE)

vznášať sa1, text, ntext, obraz, XML, Alebo filestream stĺpce
Poddotaz
OVER klauzula, ktorá zahŕňa funkcie klasifikácie alebo agregácie okien

Fulltextové predikáty (CONTAINS, FREETEXT)
SUM funkcia, ktorá odkazuje na výraz s možnosťou null
ORDER BY

Používateľom definovaná agregačná funkcia CLR
TOP
CUBE, ROLLUP, Alebo GROUPING SETS Operátori

MIN, MAX
UNION, EXCEPT, Alebo INTERSECT Operátori
TABLESAMPLE

Tabuľkové premenné
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Riedke sady stĺpcov
Vložené (TVF) alebo viacpríkazové tabuľkové funkcie (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY a iné sú zakázané. Možno by bolo jednoduchšie špecifikovať, čo by sa dalo použiť, ako to, čo sa použiť nedalo. Zoznam by bol pravdepodobne oveľa menší.

Aby som to zhrnul: obrovský súbor obmedzení v každej (všimnime si komerčnej) DBMS oproti žiadnej (s výnimkou jedného logického, nie technického) v technológii LGPL. Treba však poznamenať, že implementácia tohto mechanizmu v relačnej logike je o niečo náročnejšia ako v opísanej funkčnej logike.

Реализация

Ako to funguje? PostgreSQL sa používa ako „virtuálny stroj“. Vo vnútri je zložitý algoritmus, ktorý vytvára dotazy. Tu zdroj. A nejde len o veľký súbor heuristiky s množstvom if. Takže, ak máte pár mesiacov na štúdium, môžete skúsiť porozumieť architektúre.

Funguje to efektívne? Celkom efektívne. Bohužiaľ, je to ťažké dokázať. Môžem len povedať, že ak vezmete do úvahy tisíce požiadaviek, ktoré existujú vo veľkých aplikáciách, potom sú v priemere efektívnejšie ako požiadavky dobrého vývojára. Vynikajúci SQL programátor dokáže napísať akýkoľvek dotaz efektívnejšie, no pri tisíckach dotazov na to jednoducho nebude mať motiváciu ani čas. Jediná vec, ktorú teraz môžem uviesť ako dôkaz efektívnosti, je, že na platforme postavenej na tomto DBMS pracuje niekoľko projektov ERP systémy, ktoré majú tisíce rôznych MATERIALIZOVANÝCH funkcií, s tisíckami používateľov a terabajtovými databázami so stovkami miliónov záznamov bežiacich na bežnom dvojprocesorovom serveri. Účinnosť si však môže každý skontrolovať/vyvrátiť stiahnutím plošina a PostgreSQL, zapnutý protokolovanie SQL dotazov a pokus o zmenu logiky a údajov tam.

V nasledujúcich článkoch tiež porozprávam o tom, ako si môžete nastaviť obmedzenia funkcií, pracovať so zmenami a mnoho iného.

Zdroj: hab.com

Pridať komentár