Balansering van skryf en lees in die databasis

Balansering van skryf en lees in die databasis
In die vorige Artikel Ek het die konsep en implementering van 'n databasis beskryf wat op die basis van funksies gebou is, eerder as tabelle en velde soos in relasionele databasisse. Dit het baie voorbeelde verskaf wat die voordele van hierdie benadering bo die klassieke een toon. Baie het gevind dat hulle nie oortuigend genoeg was nie.

In hierdie artikel sal ek wys hoe hierdie konsep jou in staat stel om vinnig en gerieflik skryf en lees na die databasis te balanseer sonder enige verandering in die bedryfslogika. Soortgelyke funksionaliteit is gepoog om geïmplementeer te word in moderne kommersiële DBBS'e (veral Oracle en Microsoft SQL Server). Aan die einde van die artikel sal ek wys dat wat hulle gedoen het, om dit sagkens te stel, nie baie goed uitgewerk het nie.

Beskrywing

Soos voorheen, sal ek die beskrywing met voorbeelde begin om beter te verstaan. Kom ons sê ons moet logika implementeer wat 'n lys van departemente sal gee met die aantal werknemers daarin en hul totale salaris.

In 'n funksionele databasis sal dit soos volg lyk:

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

Die kompleksiteit van die uitvoering van hierdie navraag in enige DBBS sal gelykstaande wees aan O (aantal werknemers)want hierdie berekening vereis dat die hele tabel van werknemers geskandeer word en dan volgens departement gegroepeer word. Daar sal ook 'n paar klein (ons glo dat daar baie meer werknemers as departemente is) aanvulling wees, afhangende van die gekose plan O (log aantal werknemers) of O (aantal departemente) vir groepering en so meer.

Dit is duidelik dat die uitvoeringsbokoste in verskillende DBBS'e verskillend kan wees, maar die kompleksiteit sal op geen manier verander nie.

In die voorgestelde implementering sal die funksionele DBBS een subnavraag genereer wat die vereiste waardes vir die departement sal bereken, en dan 'n JOIN maak met die afdelingstabel om die naam te verkry. Vir elke funksie is dit egter moontlik om 'n spesiale MATERIALISEERDE merker in te stel wanneer dit verklaar word. Die stelsel sal outomaties 'n ooreenstemmende veld vir elke sodanige funksie skep. Wanneer die waarde van 'n funksie verander word, sal die waarde van die veld ook in dieselfde transaksie verander. Wanneer toegang tot hierdie funksie verkry word, sal toegang tot die voorafberekende veld verkry word.

Veral as jy MATERIALISED vir funksies instel tel Werknemers и salarisSom, dan sal twee velde by die tabel gevoeg word met die lys van departemente, wat die aantal werknemers en hul totale salaris sal stoor. Wanneer daar ook al 'n verandering in werknemers, hul salarisse of afdelingsaffiliasies is, sal die stelsel outomaties die waardes van hierdie velde verander. Die bogenoemde navraag sal direk toegang tot hierdie velde verkry en sal uitgevoer word in O (aantal departemente).

Wat is die beperkings? Net een ding: so 'n funksie moet 'n eindige aantal invoerwaardes hê waarvoor die waarde daarvan gedefinieer is. Andersins sal dit onmoontlik wees om 'n tabel te bou wat al sy waardes stoor, aangesien daar nie 'n tabel met 'n oneindige aantal rye kan wees nie.

Voorbeeld:

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

Hierdie funksie word gedefinieer vir 'n oneindige aantal waardes van N (byvoorbeeld, enige negatiewe waarde is geskik). Daarom kan jy nie MATERIALISED daarop sit nie. Dit is dus 'n logiese beperking, nie 'n tegniese een nie (dit is nie omdat ons dit nie kon implementeer nie). Andersins is daar geen beperkings nie. Jy kan groeperings, sortering, EN en OF, PARTISIE, rekursie, ens.

Byvoorbeeld, in probleem 2.2 van die vorige artikel kan jy MATERIALISED op beide funksies plaas:

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;

Die stelsel self sal een tabel met tipe sleutels skep Kliënt, Produk и HEELGETAL, sal twee velde daarby voeg en sal die veldwaardes daarin opdateer met enige veranderinge. Wanneer verdere oproepe na hierdie funksies gemaak word, sal dit nie bereken word nie, maar die waardes sal eerder uit die ooreenstemmende velde gelees word.

Deur hierdie meganisme te gebruik, kan jy byvoorbeeld ontslae raak van rekursies (CTE) in navrae. Oorweeg veral groepe wat 'n boom vorm deur die kind/ouer-verhouding te gebruik (elke groep het 'n skakel na sy ouer):

parent = DATA Group (Group);

In 'n funksionele databasis kan rekursielogika soos volg gespesifiseer word:

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;

Sedert vir die funksie is Ouer gemerk is MATERIALISED, dan sal 'n tabel met twee sleutels (groepe) daarvoor geskep word, waarin die veld is Ouer sal slegs waar wees as die eerste sleutel 'n kind van die tweede is. Die aantal inskrywings in hierdie tabel sal gelyk wees aan die aantal groepe vermenigvuldig met die gemiddelde diepte van die boom. As jy byvoorbeeld die aantal afstammelinge van 'n sekere groep moet tel, kan jy hierdie funksie gebruik:

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

Daar sal geen CTE in die SQL-navraag wees nie. In plaas daarvan sal daar 'n eenvoudige GROUP BY wees.

Deur hierdie meganisme te gebruik, kan jy ook die databasis maklik denormaliseer indien nodig:

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

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

Wanneer 'n funksie opgeroep word datum vir die bestelreël sal die veld waarvoor daar 'n indeks is, uit die tabel met bestellyne gelees word. Wanneer die besteldatum verander, sal die stelsel self outomaties die gedenormaliseerde datum in die lyn herbereken.

Voordele

Waarvoor is hierdie hele meganisme? In klassieke DBBS'e, sonder om navrae te herskryf, kan 'n ontwikkelaar of DBA slegs indekse verander, statistieke bepaal en die navraagbeplanner vertel hoe om dit uit te voer (en WENKE is slegs beskikbaar in kommersiële DBBS'e). Maak nie saak hoe hard hulle probeer nie, hulle sal nie die eerste navraag in die artikel in kan voltooi nie O (aantal departemente) sonder om navrae te verander of snellers by te voeg. In die voorgestelde skema hoef jy in die ontwikkelingstadium nie te dink aan die databergingstruktuur en watter samevoegings om te gebruik nie. Dit alles kan maklik verander word op die vlieg, direk in werking.

In die praktyk lyk dit so. Sommige mense ontwikkel logika direk op grond van die taak op hande. Hulle verstaan ​​nie algoritmes en hul kompleksiteit nie, ook nie uitvoeringsplanne, of tipes aansluitings, of enige ander tegniese komponent nie. Hierdie mense is meer sake-ontleders as ontwikkelaars. Dan gaan dit alles na toetsing of operasie. Maak aanteken van langlopende navrae moontlik. Wanneer 'n lang navraag bespeur word, besluit ander mense (meer tegnies - in wese DBA) om MATERIALISED op een of ander intermediêre funksie te aktiveer. Dit vertraag die opname 'n bietjie (aangesien dit die opdatering van 'n bykomende veld in die transaksie vereis). Nie net hierdie navraag word egter aansienlik bespoedig nie, maar ook alle ander wat hierdie funksie gebruik. Terselfdertyd is dit relatief maklik om te besluit watter funksie om te realiseer. Twee hoofparameters: die aantal moontlike invoerwaardes (dit is hoeveel rekords in die ooreenstemmende tabel sal wees), en hoe gereeld dit in ander funksies gebruik word.

analoë

Moderne kommersiële DBBS'e het soortgelyke meganismes: GEMATERIALISEERDE AANSIG met FAST REFRRESH (Oracle) en INDEXED VIEW (Microsoft SQL Server). In PostgreSQL kan MATERIALISED VIEW nie in 'n transaksie opgedateer word nie, maar slegs op versoek (en selfs met baie streng beperkings), so ons oorweeg dit nie. Maar hulle het verskeie probleme wat hul gebruik aansienlik beperk.

Eerstens kan jy slegs materialisering aktiveer as jy reeds 'n gewone VIEW geskep het. Andersins sal jy die oorblywende versoeke moet herskryf om toegang tot die nuutgeskepte aansig te kry om hierdie materialisering te gebruik. Of laat alles soos dit is, maar dit sal ten minste oneffektief wees as daar sekere reeds vooraf berekende data is, maar baie navrae gebruik dit nie altyd nie, maar herbereken dit.

Tweedens het hulle 'n groot aantal beperkings:

Oracle

5.3.8.4 Algemene beperkings op vinnige herlaai

Die bepalende navraag van die gematerialiseerde aansig word soos volg beperk:

  • Die gematerialiseerde siening mag nie verwysings bevat na nie-herhalende uitdrukkings soos SYSDATE en ROWNUM.
  • Die gematerialiseerde siening mag nie verwysings bevat na RAW or LONG RAW datatipes.
  • Dit kan nie 'n bevat nie SELECT lys subnavraag.
  • Dit kan nie analitiese funksies bevat nie (byvoorbeeld, RANK) In die SELECT klousule.
  • Dit kan nie verwys na 'n tabel waarop 'n XMLIndex indeks gedefinieer word.
  • Dit kan nie 'n bevat nie MODEL klousule.
  • Dit kan nie 'n bevat nie HAVING klousule met 'n subnavraag.
  • Dit kan nie geneste navrae bevat wat het ANY, ALL, of NOT EXISTS.
  • Dit kan nie 'n bevat nie [START WITH …] CONNECT BY klousule.
  • Dit kan nie veelvuldige detailtabelle by verskillende werwe bevat nie.
  • ON COMMIT gematerialiseerde aansigte kan nie afgeleë detailtabelle hê nie.
  • Geneste gematerialiseerde aansigte moet 'n samevoeging of samestelling hê.
  • Gematerialiseerde aansluitingsaansigte en gematerialiseerde totale aansigte met 'n GROUP BY klousule kan nie uit 'n indeks-georganiseerde tabel kies nie.

5.3.8.5 Beperkings op vinnige herlaai op gematerialiseerde aansigte met slegs aansluitings

Die definisie van navrae vir gematerialiseerde aansigte met slegs aansluitings en geen aggregate het die volgende beperkings op vinnige herlaai:

  • Alle beperkings vanaf «Algemene beperkings op Fast Refresh«.
  • Hulle kan nie hê nie GROUP BY klousules of aggregate.
  • Rowids van al die tabelle in die FROM lys moet verskyn in die SELECT lys van die navraag.
  • Gematerialiseerde aansigloglêers moet bestaan ​​met rye vir al die basistabelle in die FROM lys van die navraag.
  • Jy kan nie 'n vinnig herlaaibare gematerialiseerde aansig van veelvuldige tabelle skep met eenvoudige koppelings wat 'n objektipe kolom in die SELECT stelling.

Die verfrismetode wat u kies, sal ook nie optimaal doeltreffend wees as:

  • Die definiërende navraag gebruik 'n buitenste aansluiting wat optree soos 'n innerlike aansluiting. As die definiërende navraag so 'n koppeling bevat, oorweeg dit om die definiërende navraag te herskryf om 'n innerlike aansluiting te bevat.
  • Die SELECT lys van die gematerialiseerde aansig bevat uitdrukkings op kolomme van verskeie tabelle.

5.3.8.6 Beperkings op vinnige herlaai op gematerialiseerde aansigte met aggregate

Die definisie van navrae vir gematerialiseerde aansigte met aggregate of aansluitings het die volgende beperkings op vinnige herlaai:

Vinnige verversing word vir albei ondersteun ON COMMIT en ON DEMAND gerealiseerde sienings, maar die volgende beperkings geld:

  • Alle tabelle in die gematerialiseerde aansig moet gematerialiseerde aansigloglêers hê, en die gematerialiseerde aansigloglêers moet:
    • Bevat alle kolomme van die tabel waarna verwys word in die gematerialiseerde aansig.
    • Spesifiseer met ROWID en INCLUDING NEW VALUES.
    • spesifiseer die SEQUENCE klousule as die tabel na verwagting 'n mengsel van invoegings/direkte laaie, verwyderings en opdaterings sal hê.

  • Net SUM, COUNT, AVG, STDDEV, VARIANCE, MIN en MAX word ondersteun vir vinnige verversing.
  • COUNT(*) gespesifiseer moet word.
  • Aggregatfunksies moet slegs as die buitenste deel van die uitdrukking voorkom. Dit wil sê aggregate soos AVG(AVG(x)) or AVG(x)+ AVG(x) word nie toegelaat nie.
  • Vir elke totaal soos AVG(expr), die ooreenstemmende COUNT(expr) moet teenwoordig wees. Oracle beveel dit aan SUM(expr) gespesifiseer word.
  • If VARIANCE(expr) or STDDEV(expr) gespesifiseer word, COUNT(expr) en SUM(expr) gespesifiseer moet word. Oracle beveel dit aan SUM(expr *expr) gespesifiseer word.
  • Die SELECT kolom in die definiërende navraag kan nie 'n komplekse uitdrukking wees met kolomme van veelvuldige basistabelle nie. 'n Moontlike oplossing hiervoor is om 'n geneste gematerialiseerde aansig te gebruik.
  • Die SELECT lys moet alles bevat GROUP BY kolomme.
  • Die gematerialiseerde aansig is nie gebaseer op een of meer afgeleë tabelle nie.
  • As u a gebruik CHAR datatipe in die filterkolomme van 'n gematerialiseerde aansiglogboek, moet die karakterstelle van die meesterwerf en die gematerialiseerde aansig dieselfde wees.
  • As die gematerialiseerde aansig een van die volgende het, word vinnige herlaai slegs op konvensionele DML-insetsels en direkte vragte ondersteun.
    • Gematerialiseerde uitsigte met MIN or MAX aggregate
    • Gematerialiseerde sienings wat het SUM(expr) maar nee COUNT(expr)
    • Gematerialiseerde sienings sonder COUNT(*)

    So 'n gematerialiseerde siening word 'n insetsel-gematerialiseerde siening genoem.

  • N gematerialiseerde siening met MAX or MIN is vinnig herlaaibaar na verwydering of gemengde DML-stellings as dit nie 'n WHERE klousule.
    Die maksimum/min vinnige herlaai na uitvee of gemengde DML het nie dieselfde gedrag as die invoeging-alleen-kas nie. Dit verwyder en herbereken die maksimum/min-waardes vir die geaffekteerde groepe. Jy moet bewus wees van die prestasie-impak daarvan.
  • Gematerialiseerde aansigte met benoemde aansigte of subnavrae in die FROM klousule kan vinnig verfris word mits die sienings heeltemal saamgevoeg kan word. Vir inligting oor watter aansigte sal saamsmelt, sien Oracle-databasis SQL-taalverwysing.
  • As daar geen buitenste aansluitings is nie, kan jy arbitrêre keuses hê en aansluitings in die WHERE klousule.
  • Gematerialiseerde totale aansigte met buitenste verbindings is vinnig verfrisbaar na konvensionele DML en direkte vragte, mits slegs die buitenste tabel gewysig is. Daar moet ook unieke beperkings op die koppelingkolomme van die binneste aansluitingstabel bestaan. As daar buitenste verbindings is, moet al die verbindings deur verbind word ANDs en moet die gelykheid gebruik (=) operateur.
  • Vir gematerialiseerde sienings met CUBE, ROLLUP, groeperingsstelle of samevoeging daarvan, geld die volgende beperkings:
    • Die SELECT lys moet groeperingsonderskeid bevat wat óf 'n kan wees GROUPING_ID funksioneer op almal GROUP BY uitdrukkings of GROUPING funksies een vir elkeen GROUP BY uitdrukking. Byvoorbeeld, as die GROUP BY klousule van die gematerialiseerde siening is "GROUP BY CUBE(a, b)", Dan die SELECT lys moet óf "GROUPING_ID(a, b)» of «GROUPING(a) AND GROUPING(b)» vir die gematerialiseerde aansig om vinnig verfrisbaar te wees.
    • GROUP BY moet nie enige duplikaatgroeperings tot gevolg hê nie. Byvoorbeeld, "GROUP BY a, ROLLUP(a, b)" is nie vinnig herlaaibaar nie, want dit lei tot duplikaatgroeperings "(a), (a, b), AND (a)«.

5.3.8.7 Beperkings op vinnige herlaai op gematerialiseerde aansigte met UNION ALL

Gematerialiseerde sienings met die UNION ALL stel operateur ondersteun die REFRESH FAST opsie indien aan die volgende voorwaardes voldoen word:

  • Die definiërende navraag moet die UNION ALL operateur op die boonste vlak.

    Die UNION ALL operateur kan nie in 'n subnavraag ingebed word nie, met een uitsondering: Die UNION ALL kan in 'n subnavraag in die FROM klousule mits die definiërende navraag van die vorm is SELECT * FROM (bekyk of subnavraag met UNION ALL) soos in die volgende voorbeeld:

    SKEP VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM clients c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM kliënte c WHERE c.cust_last_name = 'Jones'); SKEPP GEMATERIALISEERDE AANSIG unionall_inside_view_mv VERFRAS VINNIG OP DRAAG AS KIES * VAN view_with_unionall;
    

    Let daarop dat die uitsig view_with_unionall voldoen aan die vereistes vir vinnige verversing.

  • Elke navraagblok in die UNION ALL navraag moet voldoen aan die vereistes van 'n vinnig verfrisbare gematerialiseerde aansig met aggregate of 'n vinnig verfrisbare gematerialiseerde aansig met verbindings.

    Die toepaslike gematerialiseerde aansig logs moet op die tabelle geskep word soos vereis vir die ooreenstemmende tipe vinnig verfrissbare gematerialiseerde aansig.
    Let daarop dat die Oracle-databasis ook die spesiale geval van 'n enkele tabel-gematerialiseerde aansig toelaat met verbindings slegs mits die ROWID kolom is ingesluit in die SELECT lys en in die gematerialiseerde aansig log. Dit word in die definiërende navraag van die aansig gewys view_with_unionall.

  • Die SELECT lys van elke navraag moet 'n insluit UNION ALL merker, en die UNION ALL kolom moet 'n duidelike konstante numeriese of stringwaarde in elk hê UNION ALL tak. Verder moet die merkerkolom in dieselfde rangordeposisie in die SELECT lys van elke navraagblok. Sien "UNION ALL Merker en navraag herskryf» vir meer inligting oor UNION ALL merkers.
  • Sommige kenmerke soos buitenste aansluitings, invoeging-alleen-aggregeerde gematerialiseerde aansignavrae en afgeleë tabelle word nie gesteun vir gematerialiseerde aansigte met UNION ALL. Let egter daarop dat gematerialiseerde aansigte wat in replikasie gebruik word, wat nie koppelings of aggregate bevat nie, vinnig verfris kan word wanneer UNION ALL of afgeleë tafels word gebruik.
  • Die versoenbaarheidsinisiasieparameter moet op 9.2.0 of hoër gestel word om 'n vinnige verfrisbare gematerialiseerde aansig te skep met UNION ALL.

Ek wil nie Oracle-aanhangers aanstoot gee nie, maar te oordeel aan hul lys van beperkings, blyk dit dat hierdie meganisme nie in die algemene geval geskryf is nie, met behulp van 'n soort model, maar deur duisende Indiërs, waar almal die geleentheid gegee is om skryf hulle eie tak, en elkeen van hulle het gedoen wat hy kon en gedoen het. Om hierdie meganisme vir ware logika te gebruik, is soos om deur 'n mynveld te stap. Jy kan enige tyd 'n myn kry deur een van die nie-vanselfsprekende beperkings te tref. Hoe dit werk is ook 'n aparte vraag, maar dit is buite die bestek van hierdie artikel.

Microsoft SQL Server

Bykomende vereistes

Benewens die SET-opsies en deterministiese funksievereistes, moet aan die volgende vereistes voldoen word:

  • Die gebruiker wat uitvoer CREATE INDEX moet die eienaar van die uitsig wees.
  • Wanneer jy die indeks skep, sal die IGNORE_DUP_KEY opsie moet op AF gestel word (die verstekinstelling).
  • Tabelle moet deur tweeledige name verwys word, skema.tafelnaam in die sieningsdefinisie.
  • Gebruiker-gedefinieerde funksies waarna verwys word in die aansig moet geskep word deur die gebruik van die WITH SCHEMABINDING opsie.
  • Enige gebruikergedefinieerde funksies waarna in die aansig verwys word, moet deur tweeledige name verwys word, ..
  • Die datatoegangseienskap van 'n gebruikergedefinieerde funksie moet wees NO SQL, en eksterne toegang eiendom moet wees NO.
  • Common Language runtime (CLR)-funksies kan in die kieslys van die aansig verskyn, maar kan nie deel wees van die definisie van die gegroepeerde indekssleutel nie. CLR-funksies kan nie in die WHERE-klousule van die aansig of die ON-klousule van 'n JOIN-bewerking in die aansig verskyn nie.
  • CLR-funksies en -metodes van CLR-gebruikergedefinieerde tipes wat in die aansigdefinisie gebruik word, moet die eienskappe hê wat ingestel is soos in die volgende tabel getoon.

    Eiendom
    nota

    DETERMINISTIES = WAAR
    Moet uitdruklik verklaar word as 'n kenmerk van die Microsoft .NET Framework-metode.

    PRESIES = WAAR
    Moet uitdruklik verklaar word as 'n kenmerk van die .NET Framework-metode.

    DATA TOEGANG = GEEN SQL
    Bepaal deur DataAccess-kenmerk op DataAccessKind.None en SystemDataAccess-kenmerk op SystemDataAccessKind.None te stel.

    EKSTERNE TOEGANG = GEEN
    Hierdie eienskap is verstek op NEE vir CLR-roetines.

  • Die aansig moet geskep word deur die gebruik van die WITH SCHEMABINDING opsie.
  • Die aansig moet slegs na basistabelle verwys wat in dieselfde databasis as die aansig is. Die siening kan nie na ander sienings verwys nie.
  • Die SELECT-stelling in die aansigdefinisie moet nie die volgende Transact-SQL-elemente bevat nie:

    COUNT
    ROWSET funksies (OPENDATASOURCE, OPENQUERY, OPENROWSET, EN OPENXML)
    OUTER sluit aan (LEFT, RIGHT, of FULL)

    Afgeleide tabel (gedefinieer deur 'n SELECT verklaring in die FROM klousule)
    Sluit self aan
    Spesifikasie van kolomme deur gebruik te maak SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, of AVG
    Algemene tabeluitdrukking (CTE)

    dryf1, teks, nteks, beeld, XML, of lêerstroom kolomme
    Subquery
    OVER klousule, wat rangorde of totale vensterfunksies insluit

    Volteks predikate (CONTAINS, FREETEXT)
    SUM funksie wat na 'n nulbare uitdrukking verwys
    ORDER BY

    CLR gebruiker-gedefinieerde totale funksie
    TOP
    CUBE, ROLLUP, of GROUPING SETS operateurs

    MIN, MAX
    UNION, EXCEPT, of INTERSECT operateurs
    TABLESAMPLE

    Tabel veranderlikes
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Skraal kolomstelle
    Inlyn (TVF) of multi-stelling tabelgewaardeerde funksies (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Die geïndekseerde aansig kan bevat dryf kolomme; sulke kolomme kan egter nie by die gegroepeerde indekssleutel ingesluit word nie.

  • If GROUP BY teenwoordig is, moet die VIEW-definisie bevat COUNT_BIG(*) en moet nie bevat nie HAVING. Hierdie GROUP BY beperkings is slegs van toepassing op die definisie van die geïndekseer aansig. 'n Navraag kan 'n geïndekseerde aansig in sy uitvoeringsplan gebruik, selfs al voldoen dit nie daaraan nie GROUP BY beperkings.
  • As die aansigdefinisie 'n GROUP BY klousule, kan die sleutel van die unieke gegroepeerde indeks slegs verwys na die kolomme wat in die GROUP BY klousule.

Dit is duidelik hier dat die Indiërs nie betrokke was nie, aangesien hulle besluit het om dit te doen volgens die skema "ons sal min doen, maar goed." Dit wil sê, hulle het meer myne op die veld, maar hul ligging is meer deursigtig. Die teleurstellendste ding is hierdie beperking:

Die aansig moet slegs na basistabelle verwys wat in dieselfde databasis as die aansig is. Die siening kan nie na ander sienings verwys nie.

In ons terminologie beteken dit dat 'n funksie nie toegang tot 'n ander gematerialiseerde funksie kan kry nie. Dit sny alle ideologie in die kiem af.
Hierdie beperking (en verder in die teks) verminder ook die gebruiksgevalle aansienlik:

Die SELECT-stelling in die aansigdefinisie moet nie die volgende Transact-SQL-elemente bevat nie:

COUNT
ROWSET funksies (OPENDATASOURCE, OPENQUERY, OPENROWSET, EN OPENXML)
OUTER sluit aan (LEFT, RIGHT, of FULL)

Afgeleide tabel (gedefinieer deur 'n SELECT verklaring in die FROM klousule)
Sluit self aan
Spesifikasie van kolomme deur gebruik te maak SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, of AVG
Algemene tabeluitdrukking (CTE)

dryf1, teks, nteks, beeld, XML, of lêerstroom kolomme
Subquery
OVER klousule, wat rangorde of totale vensterfunksies insluit

Volteks predikate (CONTAINS, FREETEXT)
SUM funksie wat na 'n nulbare uitdrukking verwys
ORDER BY

CLR gebruiker-gedefinieerde totale funksie
TOP
CUBE, ROLLUP, of GROUPING SETS operateurs

MIN, MAX
UNION, EXCEPT, of INTERSECT operateurs
TABLESAMPLE

Tabel veranderlikes
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Skraal kolomstelle
Inlyn (TVF) of multi-stelling tabelgewaardeerde funksies (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY en ander is verbode. Dit was dalk makliker om te spesifiseer wat gebruik kan word eerder as wat nie gebruik kan word nie. Die lys sal waarskynlik baie korter wees.

Om op te som: 'n groot stel beperkings in elke (kom ons let op kommersiële) DBMS vs geen (met die uitsondering van een logiese, nie tegnies nie) in LGPL-tegnologie. Daar moet egter op gelet word dat die implementering van hierdie meganisme in relasionele logika ietwat moeiliker is as in die beskryfde funksionele logika.

Implementering

Hoe dit werk? PostgreSQL word as 'n "virtuele masjien" gebruik. Daar is 'n komplekse algoritme binne wat navrae bou. Hier bron. En daar is nie net 'n groot stel heuristieke met 'n klomp as's nie. Dus, as jy 'n paar maande het om te studeer, kan jy probeer om argitektuur te verstaan.

Werk dit effektief? Nogal effektief. Ongelukkig is dit moeilik om te bewys. Ek kan net sê dat as jy die duisende navrae in ag neem wat in groot toepassings bestaan, dan is dit gemiddeld meer doeltreffend as dié van 'n goeie ontwikkelaar. 'n Uitstekende SQL-programmeerder kan enige navraag meer doeltreffend skryf, maar met 'n duisend navrae sal hy eenvoudig nie die motivering of tyd hê om dit te doen nie. Die enigste ding wat ek nou as bewys van doeltreffendheid kan aanhaal, is dat verskeie projekte werk op die platform wat op hierdie DBMS gebou is ERP stelsels, wat duisende verskillende MATERIALISEERDE funksies het, met duisende gebruikers en teragreep databasisse met honderde miljoene rekords wat op 'n gewone twee-verwerker bediener loop. Enigiemand kan egter die doeltreffendheid kontroleer/weerlê deur af te laai platform en PostgreSQL, Aanskakel SQL-navrae aan te teken en die logika en data daar te probeer verander.

In die volgende artikels sal ek ook praat oor hoe jy beperkings op funksies kan stel, met veranderingsessies kan werk, en nog baie meer.

Bron: will.com

Voeg 'n opmerking