Dans un
article précédent
, j'ai décrit le concept et l'implémentation d'une base de données construite sur la base de fonctions, pas de tables et de champs comme dans les bases de données relationnelles. Il a donné de nombreux exemples montrant les avantages de cette approche par rapport au classique. Beaucoup les ont trouvés pas assez convaincants.
Dans cet article, je montrerai comment ce concept vous permet d'équilibrer rapidement et commodément l'écriture et la lecture dans la base de données sans aucun changement dans la logique de travail. Ils ont essayé d'implémenter des fonctionnalités similaires dans des SGBD commerciaux modernes (en particulier, Oracle et Microsoft SQL Server). à la fin de l'article, je montrerai ce qui leur est arrivé, pour le dire légÚrement, pas trÚs.
La description
Comme précédemment, pour une meilleure compréhension, je vais commencer la description par des exemples. Supposons que nous ayons besoin d'implémenter une logique qui retournera une liste de départements avec le nombre d'employés en eux et leur salaire total.
Dans une base de données fonctionnelle, cela ressemblera à ceci:
La complexitĂ© de l'exĂ©cution de cette requĂȘte dans n'importe quel SGBD sera Ă©quivalente Ă
O (nombre d'employés) , car pour ce calcul, vous devez analyser l'intégralité du tableau des employés, puis les regrouper par service. Il y aura également quelques petits ajouts (nous pensons qu'il y a beaucoup plus d'employés que de départements) en fonction du plan choisi
O (nombre de salariés journaliers) ou
O (nombre de départements) pour le regroupement, etc.
Il est clair que la surcharge d'exĂ©cution peut ĂȘtre diffĂ©rente dans diffĂ©rents SGBD, mais la complexitĂ© ne changera en aucune façon.
Dans l'implĂ©mentation proposĂ©e, le SGBD fonctionnel formera une sous-requĂȘte, qui calculera les valeurs nĂ©cessaires pour le dĂ©partement, puis fera un JOIN avec la table department pour obtenir le nom. Cependant, pour chaque fonction, lors de la dĂ©claration, il est possible de spĂ©cifier un marqueur MATERIALIZED spĂ©cial. Le systĂšme crĂ©e automatiquement un champ appropriĂ© pour chacune de ces fonctions. Lorsqu'une valeur de fonction change, la valeur du champ change dans la mĂȘme transaction. Lors de l'accĂšs Ă cette fonction, un appel sera dĂ©jĂ fait au champ calculĂ©.
En particulier, si vous définissez MATERIALIZED pour les fonctions
countEmployees et
salaireSum , alors dans le tableau avec la liste des dĂ©partements, deux champs seront ajoutĂ©s dans lesquels le nombre d'employĂ©s et leur salaire total seront stockĂ©s. Avec tout changement d'employĂ©, de salaire ou d'affiliation avec les services, le systĂšme changera automatiquement les valeurs de ces champs. La requĂȘte ci-dessus commencera Ă accĂ©der directement Ă ces champs et sera exĂ©cutĂ©e pour
O (nombre de départements) .
Quelles sont les limitations? Une seule chose: une telle fonction doit avoir un nombre fini de valeurs d'entrée pour lesquelles sa valeur est définie. Sinon, il sera impossible de construire une table qui stocke toutes ses valeurs, car il ne peut pas y avoir de table avec un nombre infini de lignes.
Un exemple:
Cette fonction est dĂ©finie pour un nombre infini de valeurs du nombre N (par exemple, toute valeur nĂ©gative convient). Par consĂ©quent, il ne peut pas ĂȘtre mis MATĂRIALISĂ. Il s'agit donc d'une limitation logique et non technique (c'est-Ă -dire pas parce que nous n'avons pas pu l'implĂ©menter). Sinon, aucune restriction. Vous pouvez utiliser le regroupement, le tri, ET et OU, PARTITION, rĂ©cursivitĂ©, etc.
Par exemple, dans la tùche 2.2 de l'article précédent, vous pouvez mettre MATERIALIZED sur les deux fonctions:
Le systĂšme lui-mĂȘme crĂ©era une table avec des clĂ©s de types
Client ,
Produit et
INTEGER , y ajoutera deux champs et y mettra à jour les valeurs de champ avec toutes les modifications. Lors d'appels ultérieurs à ces fonctions, ils ne seront pas calculés, mais les valeurs des champs correspondants seront lues.
En utilisant ce mĂ©canisme, vous pouvez, par exemple, vous dĂ©barrasser de la rĂ©cursivitĂ© (CTE) dans les requĂȘtes. En particulier, considĂ©rez les groupes qui composent l'arbre en utilisant la relation enfant / parent (chaque groupe a un lien vers son parent):
Dans une base de donnĂ©es fonctionnelle, la logique de rĂ©cursivitĂ© peut ĂȘtre dĂ©finie comme suit:
Puisque MATERIALIZED est apposé pour la fonction
isParent , une table avec deux clés (groupes) sera créée pour elle, dans laquelle le champ
isParent ne sera vrai que si la premiÚre clé est un descendant de la seconde. Le nombre d'entrées dans ce tableau sera égal au nombre de groupes multiplié par la profondeur moyenne de l'arbre. S'il est nécessaire, par exemple, de calculer le nombre de descendants d'un certain groupe, vous pouvez accéder à cette fonction:
Il n'y aura pas de CTE dans la requĂȘte SQL. Au lieu de cela, il y aura un simple GROUP BY.
En utilisant ce mécanisme, vous pouvez également dénormaliser facilement la base de données si nécessaire:
Lorsque vous appelez la fonction
date pour la ligne de commande, la lecture se fera Ă partir de la table avec les lignes de commande du champ pour lequel il existe un index. Lors de la modification de la date de commande, le systĂšme lui-mĂȘme recalcule automatiquement la date dĂ©normalisĂ©e dans la ligne.
Les avantages
Pourquoi tout ce mĂ©canisme est-il nĂ©cessaire? Dans les SGBD classiques, sans réécrire les requĂȘtes, un dĂ©veloppeur ou un administrateur de base de donnĂ©es ne peut que modifier les index, dĂ©terminer les statistiques et indiquer au planificateur de requĂȘtes comment les exĂ©cuter (en outre, les HINT ne sont disponibles que dans les SGBD commerciaux). Peu importe leurs efforts, ils ne pourront pas rĂ©pondre Ă la premiĂšre demande de l'article pour
O (nombre de dĂ©partements) sans modifier les demandes et ajouter des dĂ©clencheurs. Dans le schĂ©ma proposĂ©, au stade du dĂ©veloppement, vous n'avez pas Ă penser Ă la structure du stockage des donnĂ©es et aux agrĂ©gations Ă utiliser. Tout cela peut ĂȘtre facilement modifiĂ© Ă la volĂ©e, directement en fonctionnement.
En pratique, ceci est le suivant. Certaines personnes dĂ©veloppent une logique directement basĂ©e sur la tĂąche. Ils ne connaissent ni les algorithmes ni leur complexitĂ©, ni les plans d'exĂ©cution, ni les types de join'ov, ni aucun autre composant technique. Ces personnes sont plus des analystes commerciaux que des dĂ©veloppeurs. Ensuite, tout est mis en test ou en fonctionnement. La journalisation des requĂȘtes longues est activĂ©e. Lorsqu'une longue demande est dĂ©tectĂ©e, d'autres personnes (plus techniques - en fait DBA) dĂ©cident d'inclure MATERIALIZED sur une fonction intermĂ©diaire. L'enregistrement est ainsi un peu ralenti (car la mise Ă jour d'un champ supplĂ©mentaire dans une transaction est nĂ©cessaire). Cependant, non seulement cette demande est considĂ©rablement accĂ©lĂ©rĂ©e, mais aussi toutes les autres qui utilisent cette fonction. Dans le mĂȘme temps, il est relativement simple de dĂ©cider de la fonction particuliĂšre Ă matĂ©rialiser. Deux paramĂštres principaux: le nombre de valeurs d'entrĂ©e possibles (exactement combien d'enregistrements seront dans le tableau correspondant) et la frĂ©quence Ă laquelle il est utilisĂ© dans d'autres fonctions.
Analogues
Les SGBD commerciaux modernes ont des mĂ©canismes similaires: MATERIALIZED VIEW avec FAST REFRESH (Oracle) et INDEXED VIEW (Microsoft SQL Server). Dans PostgreSQL, MATERIALIZED VIEW ne peut pas ĂȘtre mis Ă jour dans une transaction, mais uniquement sur demande (et mĂȘme avec des restrictions trĂšs strictes), nous ne le considĂ©rons donc pas. Mais ils ont plusieurs problĂšmes, ce qui limite grandement leur utilisation.
Tout d'abord, vous ne pouvez activer la matĂ©rialisation que si vous avez dĂ©jĂ créé une VUE rĂ©guliĂšre. Sinon, vous devrez réécrire les demandes restantes pour accĂ©der Ă la vue nouvellement créée afin d'utiliser cette matĂ©rialisation. Ou tout laisser tel quel, mais il sera au moins inefficace s'il existe certaines donnĂ©es dĂ©jĂ calculĂ©es, mais de nombreuses requĂȘtes ne les utilisent pas toujours, mais les calculent Ă nouveau.
DeuxiĂšmement, ils ont un grand nombre de restrictions:
Oracle5.3.8.4 Restrictions générales sur l'actualisation rapide
La requĂȘte de dĂ©finition de la vue matĂ©rialisĂ©e est limitĂ©e comme suit:
- La vue matérialisée ne doit pas contenir de références à des expressions non répétitives telles que
SYSDATE
et ROWNUM
. - La vue matérialisée ne doit pas contenir de références aux types de données
RAW
ou LONG
RAW
. - Il ne peut pas contenir de sous-requĂȘte de liste
SELECT
. - Il ne peut pas contenir de fonctions analytiques (par exemple,
RANK
) dans la clause SELECT
. - Il ne peut pas référencer une table sur laquelle un index
XMLIndex
est défini. - Il ne peut pas contenir de clause
MODEL
. - Il ne peut pas contenir de clause
HAVING
avec une sous-requĂȘte. - Il ne peut pas contenir de requĂȘtes imbriquĂ©es dont
ANY
, ALL
ou NOT
EXISTS
. - Il ne peut pas contenir de clause
[START WITH âŠ] CONNECT BY
. - Il ne peut pas contenir plusieurs tables de détail sur différents sites.
ON
vues matérialisées ON
COMMIT
ne peuvent pas avoir de tables de détail distantes.- Les vues matérialisées imbriquées doivent avoir une jointure ou un agrégat.
- Les vues de jointure matérialisées et les vues agrégées matérialisées avec une clause
GROUP
BY
ne peuvent pas sélectionner dans une table organisée par index.
5.3.8.5 Restrictions sur l'actualisation rapide des vues matérialisées avec jointures uniquement
La dĂ©finition de requĂȘtes pour des vues matĂ©rialisĂ©es avec des jointures uniquement et sans agrĂ©gats a les restrictions suivantes sur l'actualisation rapide:
- Toutes les restrictions de " Restrictions générales sur l'actualisation rapide ".
- Ils ne peuvent pas avoir de clauses
GROUP
BY
ou d'agrégats. - Les Rowids de toutes les tables de la liste
FROM
doivent apparaĂźtre dans la liste SELECT
de la requĂȘte. - Les journaux de vue matĂ©rialisĂ©e doivent exister avec des ID de ligne pour toutes les tables de base dans la liste
FROM
de la requĂȘte. - Vous ne pouvez pas crĂ©er une vue matĂ©rialisĂ©e actualisable rapidement Ă partir de plusieurs tables avec des jointures simples qui incluent une colonne de type d'objet dans l'
SELECT
.
De plus, la méthode de rafraßchissement que vous choisissez ne sera pas optimale de maniÚre optimale si:
- La requĂȘte de dĂ©finition utilise une jointure externe qui se comporte comme une jointure interne. Si la requĂȘte de dĂ©finition contient une telle jointure, envisagez de réécrire la requĂȘte de dĂ©finition pour qu'elle contienne une jointure interne.
- La liste
SELECT
de la vue matérialisée contient des expressions sur les colonnes de plusieurs tables.
5.3.8.6 Restrictions sur l'actualisation rapide des vues matérialisées avec agrégats
La dĂ©finition de requĂȘtes pour des vues matĂ©rialisĂ©es avec des agrĂ©gats ou des jointures a les restrictions suivantes pour une actualisation rapide:
L'actualisation rapide est prise en charge pour les vues matérialisées ON
COMMIT
et ON
DEMAND
, mais les restrictions suivantes s'appliquent:
- Toutes les tables de la vue matérialisée doivent avoir des journaux de vues matérialisées et les journaux de vues matérialisées doivent:
- Contient toutes les colonnes de la table référencée dans la vue matérialisée.
- Précisez avec
ROWID
et INCLUDING
ROWID
NEW
VALUES
. - Spécifiez la clause
SEQUENCE
si la table doit avoir un mélange d'insertions / charges directes, suppressions et mises à jour.
- Seuls
SUM
, COUNT
, AVG
, VARIANCE
, VARIANCE
, MIN
et MAX
sont pris en charge pour une actualisation rapide. COUNT(*)
doit ĂȘtre spĂ©cifiĂ©.- Les fonctions d'agrĂ©gation ne doivent apparaĂźtre que comme la partie la plus externe de l'expression. Autrement dit, les agrĂ©gats tels que
AVG(AVG(x))
ou AVG(x)
+ AVG(x)
ne sont pas autorisés. - Pour chaque agrégat tel que
AVG(expr)
, le COUNT(expr)
doit ĂȘtre prĂ©sent. Oracle recommande de spĂ©cifier SUM(expr)
. - Si
VARIANCE(expr)
ou STDDEV(expr
) est spécifié, COUNT(expr)
et SUM(expr)
doivent ĂȘtre spĂ©cifiĂ©s. Oracle recommande de spĂ©cifier SUM(expr *expr)
. - La colonne
SELECT
dans la requĂȘte de dĂ©finition ne peut pas ĂȘtre une expression complexe avec des colonnes de plusieurs tables de base. Une solution de contournement possible consiste Ă utiliser une vue matĂ©rialisĂ©e imbriquĂ©e. - La liste
SELECT
doit contenir toutes les colonnes GROUP
BY
. - La vue matérialisée n'est pas basée sur une ou plusieurs tables distantes.
- Si vous utilisez un type de données
CHAR
dans les colonnes de filtre d'un journal de vues matĂ©rialisĂ©es, les jeux de caractĂšres du site maĂźtre et de la vue matĂ©rialisĂ©e doivent ĂȘtre identiques. - Si la vue matĂ©rialisĂ©e prĂ©sente l'un des Ă©lĂ©ments suivants, l'actualisation rapide n'est prise en charge que sur les insertions DML conventionnelles et les charges directes.
- Vues matérialisées avec des agrégats
MIN
ou MAX
- Vues matérialisées qui ont
SUM(expr)
mais pas COUNT(expr)
- Vues matérialisées sans
COUNT(*)
Une telle vue matérialisée est appelée une vue matérialisée insérée uniquement. - Une vue matérialisée avec
MAX
ou MIN
est rapidement actualisable aprĂšs suppression ou instructions DML mixtes si elle n'a pas de clause WHERE
.
L'actualisation rapide max / min aprĂšs suppression ou DML mixte n'a pas le mĂȘme comportement que le cas d'insertion uniquement. Il supprime et recalcule les valeurs max / min pour les groupes concernĂ©s. Vous devez ĂȘtre conscient de son impact sur les performances. - Les vues matĂ©rialisĂ©es avec des vues ou sous-requĂȘtes nommĂ©es dans la clause
FROM
peuvent ĂȘtre actualisĂ©es rapidement Ă condition que les vues puissent ĂȘtre complĂštement fusionnĂ©es. Pour plus d'informations sur les vues Ă fusionner, reportez-vous Ă Oracle Database SQL Language Reference . - S'il n'y a pas de jointures externes, vous pouvez avoir des sĂ©lections et des jointures arbitraires dans la clause
WHERE
. - Les vues agrĂ©gĂ©es matĂ©rialisĂ©es avec jointures externes sont rapidement actualisables aprĂšs les charges DML conventionnelles et directes, Ă condition que seule la table externe ait Ă©tĂ© modifiĂ©e. En outre, des contraintes uniques doivent exister sur les colonnes de jointure de la table de jointure interne. S'il existe des jointures externes, toutes les jointures doivent ĂȘtre connectĂ©es par des
AND
et doivent utiliser l'opérateur d'égalité ( =
). - Pour les vues matérialisées avec
CUBE
, ROLLUP
, les ensembles de regroupement ou leur concaténation, les restrictions suivantes s'appliquent:
- La liste
SELECT
doit contenir un diffĂ©renciateur de regroupement qui peut ĂȘtre une fonction GROUPING_ID
sur toutes les expressions GROUP
BY
ou des fonctions GROUPING
une pour chaque expression GROUP
BY
. Par exemple, si la clause GROUP
BY
de la vue matérialisée est " GROUP
BY
CUBE(a, b)
", la liste SELECT
doit contenir soit " GROUPING_ID(a, b)
" ou " GROUPING(a)
AND
GROUPING(b)
"pour que la vue matérialisée soit rapidement actualisable. GROUP
BY
ne doit pas entraßner de doublons. Par exemple, « GROUP BY a, ROLLUP(a, b)
» n'est pas actualisable rapidement car il en résulte des regroupements en double « (a), (a, b), AND (a)
».
5.3.8.7 Restrictions sur l'actualisation rapide des vues matérialisées avec UNION ALL
Les vues matérialisées avec l'opérateur UNION
ALL
set prennent en charge l'option REFRESH
FAST
si les conditions suivantes sont remplies:
- La requĂȘte de dĂ©finition doit avoir l'opĂ©rateur
UNION
ALL
au niveau supérieur.
L'opérateur UNION
ALL
ne peut pas ĂȘtre incorporĂ© dans une sous-requĂȘte, Ă une exception prĂšs: L' UNION
ALL
peut ĂȘtre dans une sous-requĂȘte dans la clause FROM
condition que la requĂȘte de dĂ©finition soit de la forme SELECT * FROM
(afficher ou sous-requĂȘte avec UNION
ALL
) comme dans l'exemple suivant exemple:
CRĂER UNE VUE view_with_unionall AS
(SELECT c.rowid crid, c.cust_id, 2 umarker
DE la part des clients c OERE c.cust_last_name = 'Smith'
UNION ALL
SELECT c.rowid crid, c.cust_id, 3 umarker
DES clients c OERE c.cust_last_name = 'Jones');
CRĂER UNE VUE MATĂRIALISĂE unionall_inside_view_mv
RAFRAĂCHISSEMENT RAPIDE SUR DEMANDE
SELECT * FROM view_with_unionall;
Notez que la vue view_with_unionall
satisfait aux exigences de rafraĂźchissement rapide. - Chaque bloc de requĂȘte de la requĂȘte
UNION
ALL
doit satisfaire aux exigences d'une vue matérialisée à régénération rapide avec agrégats ou d'une vue matérialisée à régénération rapide avec jointures.
Les journaux de vue matĂ©rialisĂ©e appropriĂ©s doivent ĂȘtre créés sur les tables comme requis pour le type correspondant de vue matĂ©rialisĂ©e Ă rĂ©gĂ©nĂ©ration rapide.
Notez que la base de données Oracle autorise également le cas particulier d'une vue matérialisée à table unique avec jointures uniquement à condition que la colonne ROWID
ait été incluse dans la liste SELECT
et dans le journal des vues matĂ©rialisĂ©es. Ceci est illustrĂ© dans la requĂȘte de dĂ©finition de la vue view_with_unionall
. - La liste
SELECT
de chaque requĂȘte doit inclure un marqueur UNION
ALL
et la colonne UNION
ALL
doit avoir une valeur numérique ou chaßne constante distincte dans chaque branche UNION
ALL
. En outre, la colonne de marqueur doit apparaĂźtre dans la mĂȘme position ordinale dans la liste SELECT
de chaque bloc de requĂȘte. Reportez-vous Ă la section " Réécriture des marqueurs et requĂȘtes UNION ALL " pour plus d'informations sur les marqueurs UNION
ALL
. - Certaines fonctionnalitĂ©s telles que les jointures externes, les requĂȘtes de vue matĂ©rialisĂ©e agrĂ©gĂ©e par insertion uniquement et les tables distantes ne sont pas prises en charge pour les vues matĂ©rialisĂ©es avec
UNION
ALL
. Notez cependant que les vues matĂ©rialisĂ©es utilisĂ©es dans la rĂ©plication, qui ne contiennent pas de jointures ou d'agrĂ©gats, peuvent ĂȘtre actualisĂ©es rapidement lorsque UNION
ALL
ou des tables distantes sont utilisĂ©es. - Le paramĂštre d'initialisation de compatibilitĂ© doit ĂȘtre dĂ©fini sur 9.2.0 ou supĂ©rieur pour crĂ©er une vue matĂ©rialisĂ©e rapidement actualisable avec
UNION
ALL
.
Je ne veux pas offenser les fans d'Oracle, mais Ă en juger par leur liste de limitations, il semble que ce mĂ©canisme n'a pas Ă©tĂ© Ă©crit dans le cas gĂ©nĂ©ral en utilisant une sorte de modĂšle, mais des milliers d'Indiens, oĂč tout le monde Ă©tait autorisĂ© Ă Ă©crire leur propre fil, et chacun d'entre eux pouvait et l'a fait. Utiliser ce mĂ©canisme pour une vraie logique, c'est comme marcher dans un champ de mines. Ă tout moment, vous pouvez obtenir une mine, atteignant l'une des limitations non Ă©videntes. Comment cela fonctionne est Ă©galement un problĂšme distinct, mais il sort du cadre de cet article.
Microsoft SQL ServerExigences supplémentaires
Outre les options SET et les exigences des fonctions dĂ©terministes, les exigences suivantes doivent ĂȘtre remplies:
- L'utilisateur qui exécute
CREATE INDEX
doit ĂȘtre le propriĂ©taire de la vue. - Lorsque vous crĂ©ez l'index, l'option
IGNORE_DUP_KEY
doit ĂȘtre dĂ©finie sur OFF (le paramĂštre par dĂ©faut). - Les tables doivent ĂȘtre rĂ©fĂ©rencĂ©es par des noms en deux parties, schĂ©ma . nom_table dans la dĂ©finition de la vue.
- Les fonctions dĂ©finies par l'utilisateur rĂ©fĂ©rencĂ©es dans la vue doivent ĂȘtre créées Ă l'aide de l'option
WITH SCHEMABINDING
. - Toutes les fonctions dĂ©finies par l'utilisateur rĂ©fĂ©rencĂ©es dans la vue doivent ĂȘtre rĂ©fĂ©rencĂ©es par des noms en deux parties, <schĂ©ma> . <fonction> .
- La propriĂ©tĂ© d'accĂšs aux donnĂ©es d'une fonction dĂ©finie par l'utilisateur doit ĂȘtre
NO SQL
et la propriĂ©tĂ© d'accĂšs externe doit ĂȘtre NO
. - Les fonctions Common Language Runtime (CLR) peuvent apparaßtre dans la liste de sélection de la vue, mais ne peuvent pas faire partie de la définition de la clé d'index cluster. Les fonctions CLR ne peuvent pas apparaßtre dans la clause WHERE de la vue ou la clause ON d'une opération JOIN dans la vue.
- Les fonctions et méthodes CLR des types définis par l'utilisateur CLR utilisés dans la définition de la vue doivent avoir les propriétés définies comme indiqué dans le tableau suivant.
- La vue doit ĂȘtre créée Ă l'aide de l'option
WITH SCHEMABINDING
. - La vue doit rĂ©fĂ©rencer uniquement les tables de base qui se trouvent dans la mĂȘme base de donnĂ©es que la vue. La vue ne peut pas rĂ©fĂ©rencer d'autres vues.
- L'instruction SELECT dans la définition de la vue ne doit pas contenir les éléments Transact-SQL suivants:
1 La vue indexĂ©e peut contenir des colonnes flottantes ; toutefois, ces colonnes ne peuvent pas ĂȘtre incluses dans la clĂ© d'index cluster. - Si
GROUP BY
est présent, la définition VIEW doit contenir COUNT_BIG(*)
et ne doit pas contenir HAVING
. Ces restrictions GROUP BY
ne s'appliquent qu'Ă la dĂ©finition de vue indexĂ©e. Une requĂȘte peut utiliser une vue indexĂ©e dans son plan d'exĂ©cution mĂȘme si elle ne satisfait pas Ă ces restrictions GROUP BY
. - Si la définition de la vue contient une clause
GROUP BY
, la clé de l'index cluster unique peut référencer uniquement les colonnes spécifiées dans la clause GROUP BY
.
Ici, vous pouvez voir que les Indiens n'étaient pas attirés, comme ils ont décidé de le faire selon le schéma "nous ferons peu, mais bien". Autrement dit, ils ont plus de mines sur le terrain, mais leur emplacement est plus transparent. La chose la plus pénible est cette limitation:
La vue doit rĂ©fĂ©rencer uniquement les tables de base qui se trouvent dans la mĂȘme base de donnĂ©es que la vue. La vue ne peut pas rĂ©fĂ©rencer d'autres vues.
Dans notre terminologie, cela signifie qu'une fonction ne peut pas accĂ©der Ă une autre fonction matĂ©rialisĂ©e. Cela coupe toute l'idĂ©ologie dans l'Ćuf.
De plus, cette limitation (et plus loin dans le texte) réduit considérablement les cas d'utilisation:
L'instruction SELECT dans la définition de la vue ne doit pas contenir les éléments Transact-SQL suivants:
OUTER JOINS, UNION, ORDER BY et autres sont interdits. Il Ă©tait peut-ĂȘtre plus facile d'indiquer ce qui peut ĂȘtre utilisĂ© que ce qui ne l'est pas. La liste serait probablement beaucoup plus petite.
Pour rĂ©sumer: un Ă©norme ensemble de restrictions dans chaque (je note commercial) SGBD vs aucun (Ă l'exception d'un logique plutĂŽt que technique) dans la technologie LGPL. Cependant, il convient de noter que la mise en Ćuvre de ce mĂ©canisme dans la logique relationnelle est un peu plus compliquĂ©e que dans la fonctionnalitĂ© dĂ©crite.
Implémentation
Comment ça marche? PostgreSQL est utilisĂ© comme une «machine virtuelle». Ă l'intĂ©rieur, il y a un algorithme complexe qui construit des requĂȘtes. Voici le
code source . Et il n'y a pas seulement un grand ensemble d'heuristiques avec un tas d'if. Donc, si vous avez quelques mois pour étudier, vous pouvez essayer de comprendre l'architecture.
Fonctionne-t-il efficacement? Effectivement. Malheureusement, prouver cela est difficile. Je peux seulement dire que si vous considĂ©rez les milliers de demandes qui se trouvent dans de grandes applications, elles sont en moyenne plus efficaces qu'un bon dĂ©veloppeur. Un excellent programmeur SQL peut Ă©crire n'importe quelle requĂȘte plus efficacement, mais avec mille requĂȘtes, il n'aura tout simplement ni la motivation ni le temps de le faire. La seule chose que je peux maintenant donner comme preuve d'efficacitĂ© est que, sur la base de la plate-forme construite sur ce SGBD, plusieurs projets de
systĂšme ERP fonctionnent dans lesquels il existe des milliers de fonctions MATERIALISĂES diverses, avec des milliers d'utilisateurs et des bases de donnĂ©es terrabytes avec des centaines de millions d'enregistrements fonctionnant. sur un serveur ordinaire Ă double processeur. Cependant, n'importe qui peut tester / rĂ©futer l'efficacitĂ© en tĂ©lĂ©chargeant la
plate -
forme et PostgreSQL, en
activant la journalisation des requĂȘtes SQL et en essayant de modifier la logique et les donnĂ©es.
Dans les articles suivants, je parlerai également de la façon dont vous pouvez bloquer les restrictions sur les fonctions, travailler avec des sessions de modification et bien plus encore.