Equilibrate scrive è leghje in a basa di dati

Equilibrate scrive è leghje in a basa di dati
In u precedente articulu Aghju descrittu u cuncettu è l'implementazione di una basa di dati custruita nantu à a basa di funzioni, invece di tavule è campi cum'è in basa di dati relazionale. Hè furnitu parechji esempii chì mostranu i vantaghji di questu approcciu versu u classicu. Parechje truvaru micca abbastanza cunvince.

In questu articulu, vi mustrarà cumu questu cuncettu vi permette di equilibriu rapidamente è convenientemente scrive è leghje à a basa di dati senza alcunu cambiamentu in a logica operativa. Una funziunalità simili hè stata pruvata à esse implementata in DBMS cummirciali muderni (in particulare, Oracle è Microsoft SQL Server). À a fine di l'articulu vi dimustraraghju chì ciò chì anu fattu, per dì un pocu, ùn hà micca travagliatu assai bè.

discrizzione

Cum'è prima, per capisce megliu, principiaraghju a descrizzione cù esempi. Dicemu chì avemu bisognu di implementà a logica chì torna una lista di dipartimenti cù u numeru di l'impiegati in elli è u so salariu tutale.

In una basa di dati funziunale, avaristi cusì:

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

A cumplessità di eseguisce sta dumanda in ogni DBMS serà equivalente à O (numeru di impiegati)perchè stu calculu hè bisognu di scanning u tavulu tutale di l'impiegati è poi raggruppalli per dipartimentu. Ci sarà ancu un pocu supplementu (credemu chì ci sò assai più impiegati chè dipartimenti) secondu u pianu sceltu O (numeru di logu di l'impiegati) o O (numaru di dipartimenti) per raggruppamenti è cusì.

Hè chjaru chì l'esekzione overhead pò esse sfarente in diversi DBMS, ma a cumplessità ùn cambierà in ogni modu.

In l'implementazione pruposta, u DBMS funzionale generà una sottoquesta chì calculerà i valori richiesti per u dipartimentu, è poi fà un JOIN cù a tavola di u dipartimentu per ottene u nome. In ogni casu, per ogni funzione, quandu si dichjarà, hè pussibule stabilisce un marcatore speciale MATERIALIZED. U sistema crea automaticamente un campu currispundente per ogni funzione. Quandu cambia u valore di una funzione, u valore di u campu cambia ancu in a listessa transazzione. Quandu accede à sta funzione, u campu pre-calculatu serà accessu.

In particulare, s'è avete stabilitu MATERIALIZED per e funzioni count Impiegati и salarySum, dopu dui campi seranu aghjuntu à a tavula cù a lista di dipartimenti, chì guardà u numeru di l'impiegati è u so salariu tutale. Ogni volta chì ci hè un cambiamentu di l'impiegati, i so salarii o affiliazioni di u dipartimentu, u sistema cambierà automaticamente i valori di sti campi. A dumanda sopra accede direttamente à questi campi è serà eseguita in O (numaru di dipartimenti).

Chì sò e restrizioni? Solu una cosa: una tale funzione deve avè un numeru finitu di valori di input per quale u so valore hè definitu. Altrimenti, serà impussibile di custruisce una tavula chì guarda tutti i so valori, postu chì ùn pò micca esse una tavola cù un numeru infinitu di fila.

Esempiu:

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

Sta funzione hè definita per un numeru infinitu di valori di N (per esempiu, ogni valore negativu hè adattatu). Dunque, ùn pudete micca mette MATERIALIZED nantu à questu. Allora questu hè una limitazione logica, micca una tecnica (vale à dì, micca perchè ùn pudemu micca implementà). Altrimenti, ùn ci sò micca restrizioni. Pudete aduprà raggruppamenti, sorte, AND è OR, PARTITION, recursion, etc.

Per esempiu, in u prublema 2.2 di l'articulu precedente, pudete mette MATERIALIZED nantu à e duie funzioni:

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;

U sistema stessu creà una tavola cù e chjave di tipu Customer, pruduttu и INTEGRU, aghjunghje dui campi è aghjurnà i valori di u campu in elli cù qualsiasi cambiamenti. Quandu sò più chjamati à queste funzioni, ùn saranu micca calculati, ma i valori seranu letti da i campi currispondenti.

Aduprendu stu mekanismu, pudete, per esempiu, sbarazzà di ricursioni (CTE) in dumande. In particulare, cunzidira gruppi chì formanu un arbre cù a relazione di u zitellu / genitori (ogni gruppu hà un ligame cù u so parente):

parent = DATA Group (Group);

In una basa di dati funziunale, a logica di recursione pò esse specificata cum'è seguente:

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;

Dapoi per a funzione hè Parent hè marcatu MATERIALIZED, allura un tavulu cù dui chjave (gruppi) serà creatu per ellu, in quale u campu hè Parent serà vera solu s'è a prima chjave hè un zitellu di u sicondu. U numaru di entrate in sta tavula serà uguali à u numeru di gruppi multiplicate da a prufundità media di l'arbulu. Sè avete bisognu, per esempiu, di cuntà u numeru di discendenti di un certu gruppu, pudete aduprà sta funzione:

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

Ùn ci sarà micca CTE in a query SQL. Invece ci sarà un sèmplice GROUP BY.

Utilizendu stu mecanismu, pudete ancu facilmente denormalize a basa di dati se necessariu:

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

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

Quandu si chjama una funzione data per a linea di ordine, u campu per quale ci hè un indice serà lettu da a tavula cù e linee di ordine. Quandu a data di l'ordine cambia, u sistema stessu ricalcolerà automaticamente a data denormalizzata in a linea.

vantaghji

A cosa serve tuttu stu mecanismu? In i DBMS classici, senza riscrittura di e dumande, un sviluppatore o DBA pò solu cambià l'indici, determinà statistiche è dite à u pianificatore di query cumu eseguisce (è i HINT sò solu dispunibili in DBMS cummerciale). Ùn importa micca quantu pruvate, ùn puderanu micca cumplettà a prima dumanda in l'articulu in O (numaru di dipartimenti) senza cambià e dumande o aghjunghje triggers. In u schema prupostu, in u stadiu di sviluppu ùn avete micca bisognu di pensà à a struttura di almacenamiento di dati è chì aggregazioni aduprà. Tuttu chistu pò esse facilmente cambiatu nantu à a mosca, direttamente in funziunamentu.

In pratica, pare cusì. Certi pirsuni sviluppanu logica direttamente basatu nantu à u compitu in manu. Ùn capiscenu micca l'algoritmi è a so cumplessità, nè piani d'esekzione, nè tippi di unione, nè qualsiasi altru cumpunente tecnicu. Queste persone sò più analisti di cummerciale chè sviluppatori. Allora, tuttu questu passa in teste o operazione. Permette a registrazione di e dumande longu. Quandu una longa dumanda hè rilevata, allora altre persone (più tecniche - essenzialmente DBA) decide di attivà MATERIALIZED in qualchì funzione intermedia. Questu rallenta un pocu a registrazione (perchè hè bisognu di aghjurnà un campu supplementu in a transazzione). Tuttavia, micca solu sta dumanda hè significativamente accelerata, ma ancu tutti l'altri chì utilizanu sta funzione. À u listessu tempu, decide di quale funzione materializà hè relativamente faciule. Dui paràmetri principali: u numeru di pussibuli valori di input (questu hè quantu records seranu in a tavula currispundente), è quantu spessu si usa in altre funzioni.

Analogi

I DBMS cummirciali muderni anu meccanismi simili: VISTA MATERIALIZED cù FAST REFRESH (Oracle) è VISTA INDICE (Microsoft SQL Server). In PostgreSQL, MATERIALIZED VIEW ùn pò micca esse aghjurnatu in una transazzione, ma solu nantu à dumanda (è ancu cù restrizioni assai strette), perchè ùn avemu micca cunsideratu. Ma anu parechji prublemi chì limitanu significativamente u so usu.

Prima, pudete attivà a materializazione solu s'ellu avete digià creatu una VISTA regulare. Altrimenti, vi tuccherà à riscrive e richieste rimanenti per accede à a vista nova creata per aduprà sta materializazione. O lascià tuttu cum'è hè, ma serà almenu inefficace s'ellu ci sò certi dati digià pre-calculated, ma parechje dumande ùn l'utilizanu micca sempre, ma recalculate.

Siconda, anu un gran numaru di restrizioni:

oraculu

5.3.8.4 Restrizzione generale nantu à Fast Refresh

A dumanda di definizione di a vista materializzata hè limitata cum'è seguita:

  • A vista materializzata ùn deve micca cuntene riferimenti à espressioni chì ùn si ripetiscenu cum'è SYSDATE e ROWNUM.
  • A vista materializzata ùn deve micca cuntene riferimenti à RAW or LONG RAW tippi di dati.
  • Ùn pò micca cuntene a SELECT lista subquery.
  • Ùn pò micca cuntene funzioni analitiche (per esempiu, RANK) in u SELECT clause.
  • Ùn pò micca riferite una tavola nantu à quale un XMLIndex l'indice hè definitu.
  • Ùn pò micca cuntene a MODEL clause.
  • Ùn pò micca cuntene a HAVING clause cù una subquery.
  • Ùn pò micca cuntene dumande nidificate chì anu ANY, ALL, o NOT EXISTS.
  • Ùn pò micca cuntene a [START WITH …] CONNECT BY clause.
  • Ùn pò micca cuntene parechje tavule di dettagli in siti differenti.
  • ON COMMIT viste materializzate ùn pò micca avè tavule di dettagli remoti.
  • I viste materializzate nidificate devenu avè un join o aggregate.
  • Viste unite materializzate è viste aggregate materializzate cù a GROUP BY a clause ùn pò micca selezziunate da una tavola organizata in l'indici.

5.3.8.5 Restrictions on Fast Refresh nantu à Viste Materializzate cù Joins solu

A definizione di e dumande per viste materializzate cù unisce solu è senza aggregati anu e seguenti restrizioni nantu à l'aghjurnamentu veloce:

  • Tutte e restrizioni da «Restrizioni Generali nantu à u Refresh Rapidu".
  • Ùn ponu micca avè GROUP BY clause o aggregati.
  • File di tutti i tavulini in u FROM a lista deve apparisce in u SELECT lista di a dumanda.
  • I logs di vista materializati devenu esistenu cù rowids per tutte e tabelle di basa in u FROM lista di a dumanda.
  • Ùn pudete micca creà una vista materializzata rapida rinfrescante da parechje tavule cù unimi simplici chì includenu una colonna di tipu d'ughjettu in u SELECT affirmazioni.

Inoltre, u metudu di rinfrescante chì sceglite ùn serà micca ottimamente efficace se:

  • A dumanda di definizione usa una unione esterna chì si comporta cum'è una unione interna. Se a query di definizione cuntene una tale unione, cunsidereghja a riscrittura di a dumanda di definizione per cuntene una unione interna.
  • lu SELECT A lista di a vista materializzata cuntene espressioni nantu à e colonne da parechje tavule.

5.3.8.6 Restrictions on Fast Refresh nantu à Viste Materialized with Aggregates

A definizione di e dumande per viste materializzate cù aggregati o unisce anu e seguenti restrizioni nantu à l'aghjurnamentu veloce:

L'aghjurnamentu rapidu hè supportatu per i dui ON COMMIT e ON DEMAND viste materializzate, però si applicanu e seguenti restrizioni:

  • Tutte e tavule in a vista materializzata deve avè logs di vista materializzati, è i logs di vista materializzati devenu:
    • Cuntene tutte e colonne da a tavula riferita in a vista materializzata.
    • Specificà cù ROWID e INCLUDING NEW VALUES.
    • Specifique u SEQUENCE clause se a tavula hè prevista per avè un mischju di inseriti / carichi diretti, sguassate è aghjurnamenti.

  • solu SUM, COUNT, AVG, STDDEV, VARIANCE, MIN e MAX sò supportati per un rinfrescante veloce.
  • COUNT(*) deve esse specificatu.
  • E funzioni aggregate devenu esse solu cum'è a parte più esterna di l'espressione. Questu hè, aggregati cum'è AVG(AVG(x)) or AVG(x)+ AVG(x) ùn sò micca permessi.
  • Per ogni aggregatu cum'è AVG(expr), u currispundente COUNT(expr) deve esse presente. Oracle ricumanda chì SUM(expr) esse specificatu.
  • If VARIANCE(expr) or STDDEV(expr) hè specificatu, COUNT(expr) e SUM(expr) deve esse specificatu. Oracle ricumanda chì SUM(expr *expr) esse specificatu.
  • lu SELECT A colonna in a query di definizione ùn pò micca esse una espressione cumplessa cù colonne da parechje tabelle di basa. Una soluzione pussibule à questu hè di utilizà una vista materializzata nidificata.
  • lu SELECT lista deve cuntene tuttu GROUP BY culonne.
  • A vista materializzata ùn hè micca basatu annantu à una o più tavule remoti.
  • Se utilizate un CHAR tipu di dati in i culonni di filtru di un logu di vista materializatu, i setti di caratteri di u situ maestru è a vista materializata deve esse listessi.
  • Se a vista materializzata hà unu di i seguenti, allora u rinfrescante veloce hè supportatu solu nantu à inserti DML cunvinziunali è carichi diretti.
    • Viste materializzate cù MIN or MAX aggregati
    • Viste materializzate chì anu SUM(expr) ma nò COUNT(expr)
    • Visti materializzati senza COUNT(*)

    Una tale vista materializzata hè chjamata una vista materializzata solu di inserimentu.

  • Una vista materializzata cù MAX or MIN hè rapidu rinfrescante dopu sguassate o dichjarazioni DML mischiate s'ellu ùn hà micca a WHERE clause.
    U max / min fast refresh dopu sguassate o DML mistu ùn hà micca u stessu cumpurtamentu cum'è u casu di inserimentu solu. Elimina è ricalcula i valori max / min per i gruppi affettati. Avete bisognu à esse cuscenti di u so impattu di rendiment.
  • Viste materializzate cù vedute chjamate o sottoquestioni in u FROM a clausula pò esse rinfrescata rapidamente sempre chì e viste ponu esse unificate cumpletamente. Per infurmazione nantu à quali viste si unisceranu, vede Oracle Database SQL Language Reference.
  • Se ùn ci sò micca unimenti esterni, pudete avè selezioni arbitrarie è unisce in u WHERE clause.
  • Viste aggregate materializzate cù unioni esterni sò rapidamente rinfrescante dopu DML cunvinziunali è carichi diretti, basta chì solu a tavola esterna hè stata mudificata. Inoltre, e restrizioni uniche deve esse esistenu nantu à e culonne di unisce di a tavola interna di cunghjunzione. Se ci sò unimenti esterni, tutti i cunghjunghjini devenu esse cunnessi da ANDs è deve aduprà l'ugualità (=) operatore.
  • Per viste materializzate cù CUBE, ROLLUP, gruppi di raggruppamenti, o cuncatenazione di elli, si applicanu e seguenti restrizioni:
    • lu SELECT a lista deve cuntene un distintiu di raggruppamentu chì pò esse sia a GROUPING_ID funzione nantu à tutti GROUP BY espressioni o GROUPING funzioni una per ognunu GROUP BY spressione. Per esempiu, se u GROUP BY clause di a vista materializzata hè "GROUP BY CUBE(a, b)", allora u SELECT a lista deve cuntene sia "GROUPING_ID(a, b)» o «GROUPING(a) AND GROUPING(b)» per a vista materializzata per esse rinfrescante rapidamente.
    • GROUP BY ùn deve micca risultatu in gruppi duplicati. Per esempiu, "GROUP BY a, ROLLUP(a, b)"ùn hè micca rinfrescante veloce perchè dà risultati in gruppi duplicati"(a), (a, b), AND (a)".

5.3.8.7 Restrictions on Fast Refresh on Materialized Views with UNION ALL

Viste materializzate cù u UNION ALL stabilisce u supportu di l'operatore REFRESH FAST opzione se e seguenti cundizioni sò soddisfatte:

  • A dumanda di definizione deve avè u UNION ALL operatore à u livellu più altu.

    lu UNION ALL L'operatore ùn pò micca esse incrustatu in una subquery, cù una eccezzioni: The UNION ALL pò esse in una subquery in u FROM clause furnite chì a dumanda di definizione hè di a forma SELECT * FROM (Vede o sottoquestione cù UNION ALL) cum'è in l'esempiu seguente:

    CREATE VIEW view_with_unionall AS (SELECT c.rowid crid, c.cust_id, 2 umarker FROM clienti c WHERE c.cust_last_name = 'Smith' UNION ALL SELECT c.rowid crid, c.cust_id, 3 umarker FROM clienti c WHERE c.cust_last_name "Jones"); CREATE VISUALIZZA MATERIALIZZATA unionall_inside_view_mv REFRESH FAST ON DEMAND AS SELECT * FROM view_with_unionall;
    

    Nota chì a vista view_with_unionall soddisfa i requisiti per un rinfrescante veloce.

  • Ogni bloccu di quistione in u UNION ALL a dumanda deve soddisfà i requisiti di una vista materializzata veloce rinfrescante cù aggregati o una vista materializzata veloce rinfrescante cù unione.

    I logs di vista materializatu appropritatu devenu esse creati nantu à e tavule cum'è necessariu per u tipu currispundente di vista materializzata veloce refrescante.
    Innota chì a basa di dati Oracle permette ancu u casu speciale di una vista materializzata di una sola tabella cù unisce solu furnite ROWID a colonna hè stata inclusa in u SELECT lista è in u logu di vista materializatu. Questu hè mostratu in a dumanda di definizione di a vista view_with_unionall.

  • lu SELECT a lista di ogni dumanda deve include a UNION ALL marcatore, è u UNION ALL A colonna deve avè un valore numericu o stringu constante distintu in ognunu UNION ALL ramu. Inoltre, a colonna di marcatura deve apparisce in a listessa pusizione ordinale in u SELECT lista di ogni bloccu di dumanda. Vede "UNION ALL Marker è Query Rewrite» per più infurmazione nantu à UNION ALL marcatori.
  • Alcune funzioni, cum'è e unione esterne, e dumande di vista materializzate aggregate solu inserite è e tabelle remoti ùn sò micca supportate per viste materializzate cù UNION ALL. Nota, però, chì e vedute materializzate utilizzate in a replicazione, chì ùn cuntenenu micca unione o aggregati, ponu esse rinfrescate rapidamente quandu UNION ALL o tavule remoti sò usati.
  • U paràmetru d'inizializazione di cumpatibilità deve esse stabilitu à 9.2.0 o più altu per creà una vista materializzata rapida rinfrescante cù UNION ALL.

Ùn vogliu micca offensà i fan di l'Oracle, ma à ghjudicà da a so lista di restrizioni, pare chì stu miccanisimu hè statu scrittu micca in u casu generale, cù qualchì tipu di mudellu, ma da millaie di indiani, induve ognunu hè stata data l'uppurtunità di scrivite u so ramu, è ognunu hà fattu ciò chì pudia. Utilizà stu mecanismu per a logica vera hè cum'è caminari per un campu minatu. Pudete ottene una minera in ogni mumentu chjappà una di e restrizioni micca evidenti. Cumu funziona hè ancu una quistione separata, ma hè fora di u scopu di stu articulu.

Microsoft SQLServer

Requisiti Ulteriori

In più di l'opzioni SET è i requisiti di funzioni deterministiche, i seguenti requisiti devenu esse soddisfatti:

  • L'utilizatore chì eseguisce CREATE INDEX deve esse u pruprietariu di a vista.
  • Quandu crea l'indici, u IGNORE_DUP_KEY L'opzione deve esse disattivata (impostazione predefinita).
  • I tavulini devenu esse riferiti da nomi in dui parti, schema.nome di tabella in a definizione di vista.
  • E funzioni definite da l'utilizatori riferite in a vista devenu esse create usendu u WITH SCHEMABINDING funziunalità.
  • Ogni funzione definita da l'utilizatori riferita in a vista deve esse riferita da nomi in dui parti, ..
  • A pruprietà d'accessu à i dati di una funzione definita da l'utilizatori deve esse NO SQL, è a pruprietà d'accessu esternu deve esse NO.
  • E funzioni di runtime di lingua cumuna (CLR) ponu apparisce in a lista di selezzione di a vista, ma ùn pò micca esse parti di a definizione di a chjave d'indici clustered. E funzioni CLR ùn ponu micca apparisce in a clause WHERE di a vista o in a clause ON di una operazione JOIN in a vista.
  • E funzioni CLR è i metudi di tippi definiti da l'utilizatori CLR utilizati in a definizione di vista deve avè e proprietà stabilite cum'è mostra in a tabella seguente.

    Property
    Ppi

    DETERMINISTICU = VERA
    Deve esse dichjaratu esplicitamente cum'è un attributu di u metudu Microsoft .NET Framework.

    PRECISU = VERA
    Deve esse dichjaratu esplicitamente cum'è un attributu di u metudu .NET Framework.

    DATA ACCESSO = NO SQL
    Determinatu da stabilisce l'attributu DataAccess à DataAccessKind.None è l'attributu SystemDataAccess à SystemDataAccessKind.None.

    ACCESSU ESTERNI = NO
    Questa pruprietà predeterminata à NO per e routine CLR.

  • A vista deve esse creata usendu u WITH SCHEMABINDING funziunalità.
  • A vista deve riferite solu e tabelle di basa chì sò in a stessa basa di dati cum'è a vista. A vista ùn pò micca riferite altre vedute.
  • A dichjarazione SELECT in a definizione di vista ùn deve micca cuntene i seguenti elementi Transact-SQL:

    COUNT
    funzioni ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, È OPENXML)
    OUTER unisce (LEFT, RIGHT, o FULL)

    Tabella derivata (definita da a specificazione di a SELECT dichjarazione in u FROM clause)
    Auto-unisce
    Specificà e colonne utilizendu SELECT * or SELECT <table_name>.*

    DISTINCT
    STDEV, STDEVP, VAR, VARP, o AVG
    Espressione di tabella cumuni (CTE)

    float1, u testu, ntext, imaghjini, XML, o filestream colonne
    Subquestione
    OVER clause, chì include classifiche o funzioni di finestra aggregate

    Predicati full-text (CONTAINS, FREETEXT)
    SUM funzione chì riferisce una espressione nullable
    ORDER BY

    Funzione aggregata definita da l'utilizatore CLR
    TOP
    CUBE, ROLLUP, o GROUPING SETS operatori

    MIN, MAX
    UNION, EXCEPT, o INTERSECT operatori
    TABLESAMPLE

    Variabili di tabella
    OUTER APPLY or CROSS APPLY
    PIVOT, UNPIVOT

    Insiemi di colonne sparse
    Funzioni in linea (TVF) o multi-statement table-valued functions (MSTVF)
    OFFSET

    CHECKSUM_AGG

    1 A vista indexata pò cuntene float culonni; in ogni modu, tali culonni ùn ponu esse inclusi in a chjave d'indici clustered.

  • If GROUP BY hè presente, a definizione VIEW deve cuntene COUNT_BIG(*) è ùn deve micca cuntene HAVING. Eccu GROUP BY e restrizioni sò applicabili solu à a definizione di vista indexata. Una dumanda pò utilizà una vista indexata in u so pianu d'esekzione ancu s'ellu ùn soddisfa micca questi GROUP BY restrizioni.
  • Se a definizione di vista cuntene a GROUP BY clause, a chjave di l'indici clustered unicu pò riferite solu e colonne specificate in u GROUP BY clause.

Hè chjaru quì chì l'Indiani ùn eranu micca implicati, postu chì anu decisu di fà secondu u schema "faremu pocu, ma bè". Questu hè, anu più mine nantu à u campu, ma u so locu hè più trasparente. A cosa più deludente hè questa limitazione:

A vista deve riferite solu e tabelle di basa chì sò in a stessa basa di dati cum'è a vista. A vista ùn pò micca riferite altre vedute.

In a nostra terminologia, questu significa chì una funzione ùn pò micca accede à una altra funzione materializzata. Questu taglia tutte l'ideulugia in u buddu.
Inoltre, sta limitazione (è più in u testu) riduce assai i casi d'usu:

A dichjarazione SELECT in a definizione di vista ùn deve micca cuntene i seguenti elementi Transact-SQL:

COUNT
funzioni ROWSET (OPENDATASOURCE, OPENQUERY, OPENROWSET, È OPENXML)
OUTER unisce (LEFT, RIGHT, o FULL)

Tabella derivata (definita da a specificazione di a SELECT dichjarazione in u FROM clause)
Auto-unisce
Specificà e colonne utilizendu SELECT * or SELECT <table_name>.*

DISTINCT
STDEV, STDEVP, VAR, VARP, o AVG
Espressione di tabella cumuni (CTE)

float1, u testu, ntext, imaghjini, XML, o filestream colonne
Subquestione
OVER clause, chì include classifiche o funzioni di finestra aggregate

Predicati full-text (CONTAINS, FREETEXT)
SUM funzione chì riferisce una espressione nullable
ORDER BY

Funzione aggregata definita da l'utilizatore CLR
TOP
CUBE, ROLLUP, o GROUPING SETS operatori

MIN, MAX
UNION, EXCEPT, o INTERSECT operatori
TABLESAMPLE

Variabili di tabella
OUTER APPLY or CROSS APPLY
PIVOT, UNPIVOT

Insiemi di colonne sparse
Funzioni in linea (TVF) o multi-statement table-valued functions (MSTVF)
OFFSET

CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY è altri sò pruibiti. Puderia esse più faciule per specificà ciò chì puderia esse usatu piuttostu cà ciò chì ùn pudia micca esse usatu. A lista seria probabilmente assai più corta.

Per sintetizà: un grande inseme di restrizioni in ogni (notemu cummerciali) DBMS vs nimu (cù l'eccezzioni di una logica, micca tecnica) in a tecnulugia LGPL. Tuttavia, deve esse nutatu chì l'implementazione di stu mecanismu in a logica relazionale hè un pocu più difficiule chè in a logica funziunale descritta.

Реализация

Cumu funziona? PostgreSQL hè adupratu cum'è una "macchina virtuale". Ci hè un algoritmu cumplessu à l'internu chì custruisce e dumande. Quì surghjente. È ùn ci hè micca solu un grande settore di heuristiche cù una mansa di ifs. Allora, se avete un paru di mesi per studià, pudete pruvà à capisce l'architettura.

Funziona in modu efficace? Piuttostu efficace. Sfurtunatamente, questu hè difficiule di pruvà. Puderaghju solu dì chì si cunsiderà i millaie di dumande chì esistenu in grandi applicazioni, in media sò più efficaci di quelli di un bonu sviluppatore. Un eccellente programatore SQL pò scrive ogni dumanda in modu più efficau, ma cù mille dumande ùn hà micca solu a motivazione o u tempu per fà. L'unicu ciò chì possu avà citatu cum'è prova di efficacità hè chì parechji prughjetti travaglianu nantu à a piattaforma custruita nantu à questu DBMS. Sistemi ERP, chì anu millaie di funzioni MATERIALIZZATE diverse, cù millaie d'utilizatori è basa di dati di terabyte cù centinaie di milioni di dischi in esecuzione nantu à un servitore regulare di dui prucessori. Tuttavia, qualcunu pò verificà / rinfurzà l'efficacità da u scaricamentu piattaforma è PostgreSQL, accendendu loging queries SQL è pruvà à cambià a logica è i dati quì.

In l'articuli seguenti, parleraghju ancu di cumu pudete stabilisce restrizioni à e funzioni, travaglià cù sessioni di cambiamentu, è assai di più.

Source: www.habr.com

Add a comment