
V predchádzajúcom 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
SYSDATEaROWNUM.- Materializovaný pohľad nesmie obsahovať odkazy na
RAWaleLONGRAWdátové typy.- Nemôže obsahovať
SELECTpoddotaz v zozname.- Nemôže obsahovať analytické funkcie (napríklad,
RANK) vSELECTklauzuli.- Nemôže odkazovať na tabuľku, na ktorej je definovaný
XMLIndexindex.- Nemôže obsahovať
MODELklauzuli.- Nemôže obsahovať
HAVINGklauzulu s poddotazom.- Nemôže obsahovať vnorené dotazy, ktoré majú
ANY,ALL, aleboNOTEXISTS.- Nemôže obsahovať
[START WITH …] CONNECT BYklauzuli.- Nemôže obsahovať viacero tabuliek detailov na rôznych lokalitách.
ÁNOCOMMITmaterializované 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
SKUPINAPOklauzula 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 ««.
- Nemôžu mať
SKUPINAPOklauzuly ani agregácie.- Rowids všetkých tabuliek v
FROMzozname sa musí objaviť vSELECTzozname dotazu.- Logy materializovaných pohľadov musia existovať s rowidmi pre všetky základné tabuľky v
FROMzozname dotazu.- Nemôžete vytvoriť rýchlu obnovenú materializovanú predstavu z viacerých tabuliek s jednoduchými spojeniami, ktoré obsahujú stĺpec typu objektu v
SELECTje 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
SELECTzoznam 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:
- Všetky obmedzenia z ««.
Rýchle obnovenie je podporované pre oba
ÁNOCOMMITaÁNOPOPTÁVKAmaterializované 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
ROWIDaZAHRNUTIENOVÉHODNOTY.- Špecifikovať
SEKVENCIAklauzulu, 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,MINaMAXsú 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))aleAVG(x)+AVG(x)nie sú povolené.- Pre každý agregát ako
AVG(expr), zodpovedajúciCOUNT(expr)musí byť prítomný. Spoločnosť Oracle odporúča, abySUM(expr)bola špecifikovaná.- Ak
VARIANCIA(expr)aleSTDDEV(expr) je špecifikovaný,COUNT(expr)aSUM(expr)musí byť špecifikovaný. Spoločnosť Oracle odporúča, abySUM(expr *expr)bola špecifikovaná.- The
SELECTstĺ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
SELECTzoznam musí obsahovať všetkySKUPINAPOstĺpce.- Materializovaný pohľad nie je založený na jednej alebo viacerých vzdialených tabuľkách.
- Ak používate
CHARdá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
MINaleMAXagregáciami- Materializované pohľady, ktoré majú
SUM(expr)ale žiadneCOUNT(expr)- Materializované pohľady bez
COUNT(*)Takýto materializovaný pohľad sa nazýva iba-insert materializovaný pohľad.
- Materializovaný pohľad s
MAXaleMINje rýchlo obnoviteľný po vymazaniach alebo zmiešaných DML príkazoch, ak nemáWHEREklauzuli.
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
FROMklauzule 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 .- Ak nie sú žiadne vonkajšie spojenia, môžete mať ľubovoľné výbery a spojenia v
WHEREklauzuli.- 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
SELECTzoznam by mal obsahovať rozlišovač skupín, ktorý môže byť buďGROUPING_IDfunkcia na všetkýchSKUPINAPOvýrazoch aleboGROUPINGfunkcie pre každýSKUPINAPOvýraz. Napríklad, ak jeSKUPINAPOklauzula materializovaného pohľadu „SKUPINAPOCUBE(a, b)“tak zoznam by mal obsahovať buď „SELECTGROUPING_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, „SKUPINAPOGROUP 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úALLrázovú obnovuRÝCHLOmožnosť, ak sú splnené nasledujúce podmienky:Definujúci dotaz musí mať
- operátor na vrcholnej úrovni.
operátor podporujúALLoperátor nemôže byť zabudovaný do poddotazu, s jednou výnimkou: tátoThe
operátor podporujúALLmôže byť v poddotaze voperátor podporujúALLklauzuli, pokiaľ je definujúci dotaz vo formeFROMSELECT * 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ľadview_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úALLNa 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ľaduROWIDzoznam každého dotazu musí obsahovaťSELECTmarker aspĺňa požiadavky na rýchlu obnovu..- The
SELECTstĺpec musí mať jedinečnú konštantnú číselnú alebo reťazcovú hodnotu v každejoperátor podporujúALLvetve. Ďalej, markerový stĺpec musí byť v rovnakom poradí voperátor podporujúALLzozname každého dotazu bloku. Viď „operátor podporujúALLUNION ALL Marker a Otázka prepisovaťSELECT“ pre viac informácií oNiektoré 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 soperá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 soperátor podporujúALLalebo 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 INDEXmusí byť vlastníkom pohľadu.- Pri vytváraní indexu musíte nastaviť
IGNORE_DUP_KEYvo 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ťNOFunkcie 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 = TRUEMusí byť výslovne deklarovaná ako atribút metódy Microsoft .NET Framework.
PRECISE = TRUEMusí byť výslovne deklarovaná ako atribút metódy .NET Framework.
DATA ACCESS = NO SQLStanovené nastavením atribútu DataAccess na hodnotu DataAccessKind.None a atribútu SystemDataAccess na hodnotu SystemDataAccessKind.None.
EXTERNAL ACCESS = NOTento 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,, AOPENXMLVONKAJŠIE)
spojenia (ĽAVÉPRAVÉ,CELKOVÉ, aleboOdvozená tabuľka (definovaná určením)príkazu v
SELECTklauzule)FROMSebapojenia
Určenie stĺpcov pomocou
SELECT *SELECT <názov_tabulky>.*aleDISTINCT
STDEV
STDEVP,VAR,VARP,Spoločný výraz tabuľky (CTE), aleboAVG
ntextfloat1, text, XML, obrázok, filestream, alebo stĺpce Poddotaz
OVER
klauzula, ktorá obsahuje funkcie hodnotenia alebo agregátuVlastnosti full-textu (CONTAINS
FREETEXT,funkcia, ktorá odkazuje na nullable výraz)
SUMAPORADIE PODĽA
CLR užívateľská agregovaná funkciaTOP
SETY SKUPINOVANIA
CUBE,ROLLUP, alebooperátoryEXCEPT
MIN,MAX
operátor podporujú,INTERSECT, aleboTABUĽOVÝ VZOREXCEPT
Tabuľkové premenneVONKAJŠÍ APLIKOVANIE
OTÁČANIEaleCROSS APPLY
OBRACANIE,Súpravy zriedkavých stĺpcovInline (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ť. TietoHAVINGobmedzenia 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 tietoje 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é vje 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,, AOPENXMLVONKAJŠIE)
spojenia (ĽAVÉPRAVÉ,CELKOVÉ, aleboOdvozená tabuľka (definovaná určením)príkazu v
SELECTklauzule)FROMSebapojenia
Určenie stĺpcov pomocou
SELECT *SELECT <názov_tabulky>.*aleDISTINCT
STDEV
STDEVP,VAR,VARP,Spoločný výraz tabuľky (CTE), aleboAVG
ntextfloat1, text, XML, obrázok, filestream, alebo stĺpce Poddotaz
OVER
klauzula, ktorá obsahuje funkcie hodnotenia alebo agregátuVlastnosti full-textu (CONTAINS
FREETEXT,funkcia, ktorá odkazuje na nullable výraz)
SUMAPORADIE PODĽA
CLR užívateľská agregovaná funkciaTOP
SETY SKUPINOVANIA
CUBE,ROLLUP, alebooperátoryEXCEPT
MIN,MAX
operátor podporujú,INTERSECT, aleboTABUĽOVÝ VZOREXCEPT
Tabuľkové premenneVONKAJŠÍ APLIKOVANIE
OTÁČANIEaleCROSS APPLY
OBRACANIE,Súpravy zriedkavých stĺpcovInline (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 . 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 , 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 a PostgreSQL, 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
