Echilibrarea scrierilor și citirilor într-o bază de date

Echilibrarea scrierilor și citirilor într-o bază de date
În anteriorul articol Am descris conceptul și implementarea unei baze de date construite pe baza de funcții, mai degrabă decât pe tabele și câmpuri ca în bazele de date relaționale. A oferit numeroase exemple care arată avantajele acestei abordări față de cea clasică. Mulți le-au găsit că nu sunt suficient de convingătoare.

În acest articol, voi arăta cum acest concept vă permite să echilibrați rapid și convenabil scrierea și citirea în baza de date fără nicio modificare a logicii de funcționare. S-a încercat implementarea unei funcționalități similare în SGBD-urile comerciale moderne (în special, Oracle și Microsoft SQL Server). La sfârșitul articolului voi arăta că ceea ce au făcut, ca să spunem ușor, nu a funcționat prea bine.

descriere

Ca și înainte, pentru o mai bună înțelegere voi începe descrierea cu exemple. Să presupunem că trebuie să implementăm o logică care va returna o listă de departamente cu numărul de angajați din ele și salariul lor total.

Într-o bază de date funcțională ar arăta astfel:

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

Complexitatea executării acestei interogări în orice SGBD va fi echivalentă cu O (numar de angajati)deoarece acest calcul necesită scanarea întregului tabel de angajați și apoi gruparea acestora pe departamente. De asemenea, vor fi câteva suplimente mici (credem că sunt mult mai mulți angajați decât departamente) în funcție de planul ales O (număr log de angajați) sau O (numar de departamente) pentru grupare și așa mai departe.

Este clar că suprasarcina de execuție poate fi diferită în diferite SGBD, dar complexitatea nu se va schimba în niciun fel.

În implementarea propusă, SGBD funcțional va genera o subinterogare care va calcula valorile necesare pentru departament, apoi va face un JOIN cu tabelul departamentului pentru a obține numele. Totuși, pentru fiecare funcție, la declarare, este posibil să setați un marker MATERIALIZED special. Sistemul va crea automat un câmp corespunzător pentru fiecare astfel de funcție. La modificarea valorii unei funcții, valoarea câmpului se va modifica și în aceeași tranzacție. La accesarea acestei funcții, va fi accesat câmpul precalculat.

În special, dacă setați MATERIALIZED pentru funcții countAngajații и salarySum, apoi se vor adăuga două câmpuri la tabelul cu lista departamentelor, care vor stoca numărul de angajați și salariul total al acestora. Ori de câte ori are loc o modificare a angajaților, a salariilor acestora sau a afilierilor la departamente, sistemul va modifica automat valorile acestor câmpuri. Interogarea de mai sus va accesa direct aceste câmpuri și va fi executată în O (numar de departamente).

Care sunt restricțiile? Un singur lucru: o astfel de funcție trebuie să aibă un număr finit de valori de intrare pentru care este definită valoarea sa. În caz contrar, va fi imposibil să construiți un tabel care să stocheze toate valorile sale, deoarece nu poate exista un tabel cu un număr infinit de rânduri.

Exemplu:

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

Această funcție este definită pentru un număr infinit de valori ale lui N (de exemplu, orice valoare negativă este potrivită). Prin urmare, nu poți pune MATERIALIZED pe el. Deci aceasta este o limitare logică, nu una tehnică (adică nu pentru că nu am putea-o implementa). În caz contrar, nu există restricții. Puteți folosi grupări, sortare, AND și SAU, PARTITION, recursivitate etc.

De exemplu, în problema 2.2 a articolului anterior, puteți pune MATERIALIZED pe ambele funcții:

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;

Sistemul în sine va crea un tabel cu chei de tip Client, Produs и INTEGER, va adăuga două câmpuri la acesta și va actualiza valorile câmpurilor din ele cu orice modificări. Când se fac apeluri suplimentare la aceste funcții, acestea nu vor fi calculate, ci mai degrabă valorile vor fi citite din câmpurile corespunzătoare.

Folosind acest mecanism, puteți, de exemplu, să scăpați de recursiunile (CTE) în interogări. În special, luați în considerare grupurile care formează un arbore folosind relația copil/părinte (fiecare grup are un link către părintele său):

parent = DATA Group (Group);

Într-o bază de date funcțională, logica recursiunii poate fi specificată după cum urmează:

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;

Deoarece pentru funcţia esteParinte este marcat MATERIALIZAT, apoi va fi creat un tabel cu două chei (grupe) pentru acesta, în care câmpul esteParinte va fi adevărată numai dacă prima cheie este un copil al celei de-a doua. Numărul de intrări din acest tabel va fi egal cu numărul de grupuri înmulțit cu adâncimea medie a arborelui. Dacă aveți nevoie, de exemplu, să numărați numărul descendenților unui anumit grup, puteți utiliza această funcție:

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

Nu va exista CTE în interogarea SQL. În schimb, va exista un simplu GROUP BY.

Folosind acest mecanism, puteți, de asemenea, să denormalizați cu ușurință baza de date, dacă este necesar:

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

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

Când apelați o funcție data pentru linia de comandă, câmpul pentru care există un index va fi citit din tabelul cu linii de comandă. Când data comenzii se schimbă, sistemul însuși va recalcula automat data denormalizată în linie.

Avantaje

Pentru ce este tot acest mecanism? În SGBD-urile clasice, fără a rescrie interogările, un dezvoltator sau DBA poate doar să schimbe indexurile, să determine statistici și să spună planificatorului de interogări cum să le execute (iar Sfaturile sunt disponibile numai în SGBD-urile comerciale). Oricât s-ar strădui, nu vor putea finaliza prima interogare din articolul în O (numar de departamente) fără a modifica interogările sau a adăuga declanșatoare. În schema propusă, în etapa de dezvoltare nu trebuie să vă gândiți la structura de stocare a datelor și la ce agregare să utilizați. Toate acestea pot fi schimbate cu ușurință din mers, direct în funcțiune.

În practică arată așa. Unii oameni dezvoltă logica direct bazată pe sarcina pe care o îndeplinește. Ei nu înțeleg algoritmii și complexitatea lor, nici planurile de execuție, nici tipurile de îmbinări, nici orice altă componentă tehnică. Acești oameni sunt mai mult analiști de afaceri decât dezvoltatori. Apoi, toate acestea intră în testare sau operare. Permite înregistrarea interogărilor de lungă durată. Când este detectată o interogare lungă, alte persoane (mai tehnice - în esență DBA) decid să activeze MATERIALIZED pe o funcție intermediară. Acest lucru încetinește puțin înregistrarea (deoarece necesită actualizarea unui câmp suplimentar în tranzacție). Cu toate acestea, nu numai această interogare este accelerată semnificativ, ci și toate celelalte care folosesc această funcție. În același timp, a decide ce funcție să se materializeze este relativ ușor. Doi parametri principali: numărul de valori posibile de intrare (acesta este câte înregistrări vor fi în tabelul corespunzător) și cât de des este utilizat în alte funcții.

analogi

SGBD-urile comerciale moderne au mecanisme similare: MATERIALIZED VIEW with FAST REFRESH (Oracle) și INDEXED VIEW (Microsoft SQL Server). În PostgreSQL, MATERIALIZED VIEW nu poate fi actualizat într-o tranzacție, ci doar la cerere (și chiar cu restricții foarte stricte), așa că nu o luăm în considerare. Dar au mai multe probleme care le limitează semnificativ utilizarea.

În primul rând, puteți activa materializarea numai dacă ați creat deja o vizualizare obișnuită. În caz contrar, va trebui să rescrieți solicitările rămase pentru a accesa vizualizarea nou creată pentru a utiliza această materializare. Sau lăsați totul așa cum este, dar va fi cel puțin ineficient dacă există anumite date deja precalculate, dar multe interogări nu le folosesc întotdeauna, ci le recalculează.

În al doilea rând, au un număr mare de restricții:

Oracol

5.3.8.4 Restricții generale privind reîmprospătarea rapidă

Interogarea definitorie a vederii materializate este restricționată după cum urmează:

  • Vederea materializată nu trebuie să conțină referințe la expresii care nu se repetă precum SYSDATE și ROWNUM.
  • Vederea materializată nu trebuie să conţină referiri la RAW or LONG RAW tipuri de date.
  • Nu poate conține a SELECT subinterogare de listă.
  • Nu poate conține funcții analitice (de exemplu, RANK), În SELECT clauză.
  • Nu poate face referire la un tabel pe care an XMLIndex este definit indicele.
  • Nu poate conține a MODEL clauză.
  • Nu poate conține a HAVING clauză cu o subinterogare.
  • Nu poate conține interogări imbricate care au ANY, ALL, Sau NOT EXISTS.
  • Nu poate conține a [START WITH …] CONNECT BY clauză.
  • Nu poate conține mai multe tabele de detalii pe site-uri diferite.
  • ON COMMIT vederile materializate nu pot avea tabele cu detalii la distanță.
  • Vederile materializate imbricate trebuie să aibă o îmbinare sau un agregat.
  • Vizualizări de unire materializate și vizualizări agregate materializate cu a GROUP BY clauza nu poate selecta dintr-un tabel organizat pe index.

5.3.8.5 Restricții privind reîmprospătarea rapidă pentru vizualizările materializate numai cu îmbinări

Definirea interogărilor pentru vizualizările materializate numai cu îmbinări și fără agregate are următoarele restricții privind reîmprospătarea rapidă:

  • Toate restricțiile de la «Restricții generale privind reîmprospătarea rapidă“.
  • Ei nu pot avea GROUP BY clauze sau agregate.
  • Rândurile tuturor meselor din FROM lista trebuie să apară în SELECT lista interogării.
  • Jurnalele de vizualizare materializate trebuie să existe cu rowid-uri pentru toate tabelele de bază din FROM lista interogării.
  • Nu puteți crea o vizualizare materializată reîmprospătabilă rapidă din mai multe tabele cu îmbinări simple care includ o coloană tip obiect în SELECT afirmație.

De asemenea, metoda de reîmprospătare pe care o alegeți nu va fi eficientă optim dacă:

  • Interogarea definitorie folosește o îmbinare exterioară care se comportă ca o îmbinare interioară. Dacă interogarea definitorie conține o astfel de îmbinare, luați în considerare rescrierea interogării definitorii pentru a conține o îmbinare internă.
  • SELECT lista vizualizării materializate conține expresii pe coloane din mai multe tabele.

5.3.8.6 Restricții privind reîmprospătarea rapidă pe vizualizările materializate cu agregate

Definirea interogărilor pentru vizualizările materializate cu agregate sau îmbinări au următoarele restricții privind reîmprospătarea rapidă:

Reîmprospătarea rapidă este acceptată pentru ambele ON COMMIT și ON DEMAND vederi materializate, cu toate acestea se aplică următoarele restricții:

  • Toate tabelele din vizualizarea materializată trebuie să aibă jurnalele de vizualizare materializate, iar jurnalele de vizualizare materializate trebuie:
    • Conține toate coloanele din tabelul la care se face referire în vizualizarea materializată.
    • Specificați cu ROWID și INCLUDING NEW VALUES.
    • Se specifică SEQUENCE clauză dacă se așteaptă ca tabelul să aibă un amestec de inserări/încărcări directe, ștergeri și actualizări.

  • Numai SUM, COUNT, AVG, STDDEV, VARIANCE, MIN și MAX sunt acceptate pentru reîmprospătare rapidă.
  • COUNT(*) trebuie specificat.
  • Funcțiile agregate trebuie să apară doar ca parte exterioară a expresiei. Adică agregate precum AVG(AVG(x)) or AVG(x)+ AVG(x) nu sunt permise.
  • Pentru fiecare agregat cum ar fi AVG(expr), corespondența COUNT(expr) trebuie să fie prezent. Oracle recomandă asta SUM(expr) fi specificat.
  • If VARIANCE(expr) or STDDEV(expr) este specificat, COUNT(expr) și SUM(expr) trebuie specificat. Oracle recomandă asta SUM(expr *expr) fi specificat.
  • SELECT coloana din interogarea definitorie nu poate fi o expresie complexă cu coloane din mai multe tabele de bază. O posibilă soluție la aceasta este utilizarea unei vederi materializate imbricate.
  • SELECT lista trebuie să conțină toate GROUP BY coloane.
  • Vederea materializată nu se bazează pe unul sau mai multe tabele la distanță.
  • Dacă utilizați a CHAR tipul de date din coloanele de filtrare ale unui jurnal de vizualizare materializată, seturile de caractere ale site-ului principal și vizualizarea materializată trebuie să fie aceleași.
  • Dacă vizualizarea materializată are una dintre următoarele, atunci reîmprospătarea rapidă este acceptată numai pe inserții DML convenționale și încărcări directe.
    • Vederi materializate cu MIN or MAX agregate
    • Vederi materializate care au SUM(expr) dar nu COUNT(expr)
    • Vederi materializate fără COUNT(*)

    O astfel de vedere materializată se numește vedere materializată numai pentru inserare.

  • O vedere materializată cu MAX or MIN este reîmprospătabilă rapid după ștergerea sau amestecarea instrucțiunilor DML dacă nu are un WHERE clauză.
    Reîmprospătarea rapidă max/min după ștergere sau DML amestecat nu are același comportament ca și cazul numai pentru inserare. Șterge și recalculează valorile max/min pentru grupurile afectate. Trebuie să fii conștient de impactul său asupra performanței.
  • Vizualizări materializate cu vederi denumite sau subinterogări în FROM clauza poate fi reîmprospătată rapid cu condiția ca vizualizările să fie complet îmbinate. Pentru informații despre vizualizările care vor fuziona, consultați Referință pentru limbajul SQL pentru baza de date Oracle.
  • Dacă nu există îmbinări exterioare, este posibil să aveți selecții și îmbinări arbitrare în WHERE clauză.
  • Vizualizările agregate materializate cu îmbinări exterioare sunt reîmprospătabile rapid după DML convențional și încărcări directe, cu condiția ca numai tabelul exterior să fi fost modificat. De asemenea, trebuie să existe constrângeri unice pe coloanele de îmbinare ale tabelului de îmbinare interioară. Dacă există îmbinări exterioare, toate îmbinările trebuie să fie conectate prin ANDs și trebuie să folosească egalitatea (=) operator.
  • Pentru vederi materializate cu CUBE, ROLLUP, gruparea seturilor sau concatenarea acestora, se aplică următoarele restricții:
    • SELECT lista ar trebui să conțină un deosebitor de grupare care poate fi fie a GROUPING_ID functioneaza pe toate GROUP BY expresii sau GROUPING funcţionează câte una pentru fiecare GROUP BY expresie. De exemplu, dacă GROUP BY clauza vederii materializate este „GROUP BY CUBE(a, b)", apoi SELECT lista ar trebui să conțină fie „GROUPING_ID(a, b)» sau «GROUPING(a) AND GROUPING(b)» pentru ca vederea materializată să fie rapid reîmprospătată.
    • GROUP BY nu ar trebui să aibă ca rezultat grupări duble. De exemplu, "GROUP BY a, ROLLUP(a, b)„ nu poate fi reîmprospătat rapid, deoarece are ca rezultat grupări duplicat”(a), (a, b), AND (a)“.

5.3.8.7 Restricții privind reîmprospătarea rapidă a vizualizărilor materializate cu UNION ALL

Vederi materializate cu UNION ALL setați suportul operatorului REFRESH FAST opțiune dacă sunt îndeplinite următoarele condiții:

  • Interogarea definitorie trebuie să aibă UNION ALL operator la nivelul superior.

    UNION ALL operatorul nu poate fi încorporat într-o subinterogare, cu o singură excepție: The UNION ALL poate fi într-o subinterogare în FROM clauza cu condiția ca interogarea definitorie să fie de forma SELECT * FROM (vizualizare sau subinterogare cu UNION ALL) ca în exemplul următor:

    CREATE VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM clienți c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM clienți c WHERE c.cust_last_name „Jones”); CREAȚI VISUALIZARE MATERIALIZĂ unionall_inside_view_mv ACTUALIZARE RAPID LA CERERE CU SELECTARE * FROM view_with_unionall;
    

    Rețineți că vederea view_with_unionall îndeplinește cerințele pentru reîmprospătare rapidă.

  • Fiecare bloc de interogare din UNION ALL interogarea trebuie să satisfacă cerințele unei vederi materializate rapid reîmprospătabile cu agregate sau unei vizualizări materializate rapid reîmprospătabile cu îmbinări.

    Jurnalele de vizualizare materializată adecvate trebuie create pe tabele după cum este necesar pentru tipul corespunzător de vizualizare materializată reîmprospătabilă rapidă.
    Rețineți că baza de date Oracle permite, de asemenea, cazul special al unei vederi materializate de un singur tabel cu îmbinări doar cu condiția ROWID coloana a fost inclusă în SELECT listă și în jurnalul de vizualizare materializat. Acest lucru este afișat în interogarea definitorie a vizualizării view_with_unionall.

  • SELECT lista fiecărei interogări trebuie să includă a UNION ALL marker, iar UNION ALL coloana trebuie să aibă o valoare constantă distinctă numerică sau șir în fiecare UNION ALL ramură. În plus, coloana marcatorului trebuie să apară în aceeași poziție ordinală în SELECT lista fiecărui bloc de interogare. Vedea "UNION ALL Marker și Rescrierea interogărilor» pentru mai multe informatii referitoare la UNION ALL marcatori.
  • Unele caracteristici, cum ar fi îmbinările exterioare, interogările de vizualizare materializată agregată numai pentru inserare și tabelele la distanță nu sunt acceptate pentru vizualizările materializate cu UNION ALL. Rețineți, totuși, că vizualizările materializate utilizate în replicare, care nu conțin îmbinări sau agregate, pot fi reîmprospătate rapid atunci când UNION ALL sau sunt folosite mese la distanță.
  • Parametrul de inițializare a compatibilității trebuie setat la 9.2.0 sau mai mare pentru a crea o vizualizare materializată rapid reîmprospătabilă cu UNION ALL.

Nu vreau să jignesc fanii Oracle, dar judecând după lista lor de restricții, se pare că acest mecanism a fost scris nu în cazul general, folosind un fel de model, ci de mii de indieni, unde tuturor li s-a dat posibilitatea să scrie propria ramură și fiecare dintre ei a făcut ce a putut și a făcut. Folosirea acestui mecanism pentru o logică reală este ca și cum ai merge printr-un câmp minat. Puteți obține o mină în orice moment prin atingerea uneia dintre restricțiile care nu sunt evidente. Cum funcționează este, de asemenea, o întrebare separată, dar depășește scopul acestui articol.

Microsoft SQL Server

Cerințe suplimentare

Pe lângă opțiunile SET și cerințele funcției deterministe, trebuie îndeplinite următoarele cerințe:

  • Utilizatorul care execută CREATE INDEX trebuie să fie proprietarul vederii.
  • Când creați indexul, IGNORE_DUP_KEY opțiunea trebuie să fie setată la OFF (setarea implicită).
  • Tabelele trebuie să fie referite prin nume din două părți, schemă.tablename în definiția vederii.
  • Funcțiile definite de utilizator la care se face referire în vizualizare trebuie create utilizând WITH SCHEMABINDING opțiune.
  • Orice funcții definite de utilizator la care se face referire în vizualizare trebuie să fie referite prin nume din două părți, ..
  • Proprietatea de acces la date a unei funcții definite de utilizator trebuie să fie NO SQL, iar proprietatea de acces extern trebuie să fie NO.
  • Funcțiile Common Language Runtime (CLR) pot apărea în lista de selectare a vizualizării, dar nu pot face parte din definiția cheii de index în cluster. Funcțiile CLR nu pot apărea în clauza WHERE a vizualizării sau clauza ON a unei operațiuni JOIN în vizualizare.
  • Funcțiile și metodele CLR ale tipurilor definite de utilizator CLR utilizate în definiția vizualizării trebuie să aibă proprietățile setate așa cum se arată în tabelul următor.

    Proprietate
    notițe

    DETERMINIST = ADEVĂRAT
    Trebuie să fie declarat explicit ca atribut al metodei Microsoft .NET Framework.

    PRECIS = ADEVĂRAT
    Trebuie să fie declarat explicit ca atribut al metodei .NET Framework.

    ACCES DATE = FĂRĂ SQL
    Determinat prin setarea atributului DataAccess la DataAccessKind.None și a atributului SystemDataAccess la SystemDataAccessKind.None.

    ACCES EXTERN = NR
    Această proprietate este implicită la NO pentru rutinele CLR.

  • Vederea trebuie creată utilizând WITH SCHEMABINDING opțiune.
  • Vederea trebuie să facă referire numai la tabele de bază care se află în aceeași bază de date cu vizualizarea. Vederea nu poate face referire la alte vizualizări.
  • Instrucțiunea SELECT din definiția vizualizării nu trebuie să conțină următoarele elemente Transact-SQL:

    COUNT
    Funcții ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, ȘI OPENXML)
    OUTER se alătură (LEFT, RIGHT, Sau FULL)

    Tabel derivat (definit prin specificarea a SELECT declarație în FROM clauză)
    Auto-aderări
    Specificarea coloanelor utilizând SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, Sau AVG
    Expresie de tabel comună (CTE)

    pluti1, a) Sport and Nutrition Awareness Day in Manasia Around XNUMX people from the rural commune Manasia have participated in a sports and healthy nutrition oriented activity in one of the community’s sports ready yards. This activity was meant to gather, mainly, middle-aged people from a Romanian rural community and teach them about the benefits that sports have on both their mental and physical health and on how sporting activities can be used to bring people from a community closer together. Three trainers were made available for this event, so that the participants would get the best possible experience physically and so that they could have the best access possible to correct information and good sports/nutrition practices. b) Sports Awareness Day in Poiana Țapului A group of young participants have taken part in sporting activities meant to teach them about sporting conduct, fairplay, and safe physical activities. The day culminated with a football match. , ntext, imagine, XML, Sau flux de fișiere coloane
    Subinterogare
    OVER clauză, care include funcții de clasare sau de fereastră agregată

    Predicate full-text (CONTAINS, FREETEXT)
    SUM funcție care face referire la o expresie nulabilă
    ORDER BY

    Funcție de agregare CLR definită de utilizator
    TOP
    CUBE, ROLLUP, Sau GROUPING SETS Operatorii

    MIN, MAX
    UNION, EXCEPT, Sau INTERSECT Operatorii
    TABLESAMPLE

    Variabilele de tabel
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Seturi rare de coloane
    Funcții în linie (TVF) sau cu mai multe instrucțiuni cu valori de tabel (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 Vizualizarea indexată poate conține pluti coloane; totuși, astfel de coloane nu pot fi incluse în cheia de index grupată.

  • If GROUP BY este prezent, definiția VIEW trebuie să conțină COUNT_BIG(*) si nu trebuie sa contina HAVING. Acestea GROUP BY restricțiile sunt aplicabile numai definiției vizualizării indexate. O interogare poate folosi o vedere indexată în planul său de execuție chiar dacă nu le satisface GROUP BY restricții.
  • Dacă definiția vizualizării conține a GROUP BY clauza, cheia indexului unic grupat poate face referire numai la coloanele specificate în GROUP BY clauză.

Este clar aici că indienii nu au fost implicați, deoarece au decis să o facă conform schemei „vom face puțin, dar bine”. Adică au mai multe mine pe teren, dar locația lor este mai transparentă. Cel mai dezamăgitor lucru este această limitare:

Vederea trebuie să facă referire numai la tabele de bază care se află în aceeași bază de date cu vizualizarea. Vederea nu poate face referire la alte vizualizări.

În terminologia noastră, aceasta înseamnă că o funcție nu poate accesa o altă funcție materializată. Acest lucru reduce orice ideologie de la început.
De asemenea, această limitare (și mai departe în text) reduce foarte mult cazurile de utilizare:

Instrucțiunea SELECT din definiția vizualizării nu trebuie să conțină următoarele elemente Transact-SQL:

COUNT
Funcții ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, ȘI OPENXML)
OUTER se alătură (LEFT, RIGHT, Sau FULL)

Tabel derivat (definit prin specificarea a SELECT declarație în FROM clauză)
Auto-aderări
Specificarea coloanelor utilizând SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, Sau AVG
Expresie de tabel comună (CTE)

pluti1, a) Sport and Nutrition Awareness Day in Manasia Around XNUMX people from the rural commune Manasia have participated in a sports and healthy nutrition oriented activity in one of the community’s sports ready yards. This activity was meant to gather, mainly, middle-aged people from a Romanian rural community and teach them about the benefits that sports have on both their mental and physical health and on how sporting activities can be used to bring people from a community closer together. Three trainers were made available for this event, so that the participants would get the best possible experience physically and so that they could have the best access possible to correct information and good sports/nutrition practices. b) Sports Awareness Day in Poiana Țapului A group of young participants have taken part in sporting activities meant to teach them about sporting conduct, fairplay, and safe physical activities. The day culminated with a football match. , ntext, imagine, XML, Sau flux de fișiere coloane
Subinterogare
OVER clauză, care include funcții de clasare sau de fereastră agregată

Predicate full-text (CONTAINS, FREETEXT)
SUM funcție care face referire la o expresie nulabilă
ORDER BY

Funcție de agregare CLR definită de utilizator
TOP
CUBE, ROLLUP, Sau GROUPING SETS Operatorii

MIN, MAX
UNION, EXCEPT, Sau INTERSECT Operatorii
TABLESAMPLE

Variabilele de tabel
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Seturi rare de coloane
Funcții în linie (TVF) sau cu mai multe instrucțiuni cu valori de tabel (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY și altele sunt interzise. Ar fi fost mai ușor să specificați ce ar putea fi folosit, mai degrabă decât ce nu ar putea fi folosit. Lista ar fi probabil mult mai mică.

Pentru a rezuma: un set imens de restricții în fiecare (să remarcăm comercial) DBMS vs niciunul (cu excepția unuia logic, nu tehnic) în tehnologia LGPL. Cu toate acestea, trebuie remarcat faptul că implementarea acestui mecanism în logica relațională este ceva mai dificilă decât în ​​logica funcțională descrisă.

punerea în aplicare

Cum functioneaza? PostgreSQL este folosit ca o „mașină virtuală”. Există un algoritm complex în interior care creează interogări. Aici sursă. Și nu există doar un set mare de euristici cu o grămadă de if-uri. Deci, dacă aveți câteva luni de studiat, puteți încerca să înțelegeți arhitectura.

Funcționează eficient? Destul de eficient. Din păcate, acest lucru este greu de demonstrat. Pot spune doar că dacă iei în considerare miile de interogări care există în aplicațiile mari, atunci în medie sunt mai eficiente decât cele ale unui dezvoltator bun. Un programator SQL excelent poate scrie orice interogare mai eficient, dar cu o mie de interogări pur și simplu nu va avea motivația sau timpul să o facă. Singurul lucru pe care îl pot cita acum ca dovadă a eficienței este că mai multe proiecte lucrează pe platforma construită pe acest DBMS sisteme ERP, care au mii de funcții MATERIALIZATE diferite, cu mii de utilizatori și baze de date terabyte cu sute de milioane de înregistrări care rulează pe un server obișnuit cu două procesoare. Cu toate acestea, oricine poate verifica/infirma eficacitatea prin descărcare platformă și PostgreSQL, aprins înregistrarea interogărilor SQL și încercarea de a schimba logica și datele de acolo.

În următoarele articole, voi vorbi și despre modul în care puteți seta restricții asupra funcțiilor, puteți lucra cu sesiuni de modificare și multe altele.

Sursa: www.habr.com

Adauga un comentariu