In einem früheren
Artikel habe ich das Konzept und die Implementierung einer Datenbank beschrieben, die auf Funktionen basiert und nicht auf Tabellen und Feldern wie in relationalen Datenbanken. Es gab viele Beispiele, die die Vorteile dieses Ansatzes gegenüber dem Klassiker zeigten. Viele fanden sie nicht überzeugend genug.
In diesem Artikel werde ich zeigen, wie Sie mit diesem Konzept das Schreiben und Lesen in der Datenbank schnell und bequem ausgleichen können, ohne die Arbeitslogik zu ändern. Sie versuchten, ähnliche Funktionen in modernen kommerziellen DBMS (insbesondere Oracle und Microsoft SQL Server) zu implementieren. Am Ende des Artikels werde ich zeigen, was mit ihnen passiert ist, um es milde auszudrücken, nicht sehr.
Beschreibung
Zum besseren Verständnis beginne ich die Beschreibung nach wie vor mit Beispielen. Angenommen, wir müssen eine Logik implementieren, die eine Liste der Abteilungen mit der Anzahl der Mitarbeiter und ihrem Gesamtgehalt zurückgibt.
In einer funktionalen Datenbank sieht es folgendermaßen aus:
Die Komplexität der Ausführung dieser Abfrage in einem DBMS entspricht
O (Anzahl der Mitarbeiter) , da Sie für diese Berechnung die gesamte Tabelle der Mitarbeiter scannen und sie dann nach Abteilungen gruppieren müssen. Abhängig vom gewählten Plan
O (Protokollanzahl der Mitarbeiter) oder
O (Anzahl der Abteilungen) für die Gruppierung usw. wird es auch einige kleine (wir glauben, dass es viel mehr Mitarbeiter als Abteilungen gibt) Ergänzungen geben.
Es ist klar, dass der Aufwand für die Ausführung in verschiedenen DBMS unterschiedlich sein kann, aber die Komplexität wird sich in keiner Weise ändern.
In der vorgeschlagenen Implementierung bildet das funktionale DBMS eine Unterabfrage, die die erforderlichen Werte für die Abteilung berechnet und dann eine Verknüpfung mit der Abteilungstabelle erstellt, um den Namen zu erhalten. Bei der Deklaration kann jedoch für jede Funktion ein spezieller MATERIALISIERTER Marker angegeben werden. Das System erstellt automatisch ein geeignetes Feld für jede dieser Funktionen. Wenn sich ein Funktionswert ändert, ändert sich der Feldwert in derselben Transaktion. Beim Zugriff auf diese Funktion wird bereits ein Rechtsbehelf gegen das berechnete Feld eingelegt.
Insbesondere wenn Sie MATERIALISIERT für die Funktionen
countEmployees und
SalarySum eingeben , werden in der Tabelle mit der Liste der Abteilungen zwei Felder hinzugefügt, in denen die Anzahl der Mitarbeiter und ihr Gesamtgehalt gespeichert werden. Bei jeder Änderung der Mitarbeiter, ihrer Gehälter oder der Zugehörigkeit zu Abteilungen ändert das System automatisch die Werte dieser Felder. Die obige Abfrage beginnt direkt mit dem Zugriff auf diese Felder und wird für
O (Anzahl der Abteilungen) ausgeführt .
Was sind die Einschränkungen? Nur eines: Eine solche Funktion muss eine endliche Anzahl von Eingabewerten haben, für die ihr Wert definiert ist. Andernfalls ist es unmöglich, eine Tabelle zu erstellen, in der alle Werte gespeichert sind, da es keine Tabelle mit einer unendlichen Anzahl von Zeilen geben kann.
Ein Beispiel:
Diese Funktion ist für eine unendliche Anzahl von Werten der Zahl N definiert (zum Beispiel ist jeder negative Wert geeignet). Daher kann es nicht MATERIALISIERT werden. Dies ist also eine logische und keine technische Einschränkung (dh nicht, weil wir dies nicht implementieren konnten). Ansonsten keine Einschränkungen. Sie können Gruppierung, Sortierung, UND und ODER, PARTITION, Rekursion usw. verwenden.
In Aufgabe 2.2 des vorherigen Artikels können Sie beispielsweise MATERIALISIERT für beide Funktionen festlegen:
Das System selbst erstellt eine Tabelle mit Schlüsseln der Typen
Customer ,
Product und
INTEGER , fügt zwei Felder hinzu und aktualisiert die darin enthaltenen Feldwerte bei Änderungen. Bei weiteren Aufrufen dieser Funktionen werden diese nicht berechnet, sondern Werte aus den entsprechenden Feldern gelesen.
Mit diesem Mechanismus können Sie beispielsweise die Rekursion (CTE) in Abfragen entfernen. Berücksichtigen Sie insbesondere die Gruppen, aus denen der Baum besteht, unter Verwendung der Kind / Eltern-Beziehung (jede Gruppe hat einen Link zu ihrem Elternteil):
In einer funktionalen Datenbank kann die Rekursionslogik wie folgt definiert werden:
Da MATERIALIZED für die Funktion
isParent angehängt ist, wird für sie eine Tabelle mit zwei Schlüsseln (Gruppen) erstellt, in der das Feld
isParent nur dann wahr ist, wenn der erste Schlüssel ein Nachkomme des zweiten Schlüssels ist. Die Anzahl der Einträge in dieser Tabelle entspricht der Anzahl der Gruppen multipliziert mit der durchschnittlichen Tiefe des Baums. Wenn beispielsweise die Anzahl der Nachkommen einer bestimmten Gruppe berechnet werden muss, können Sie auf diese Funktion zugreifen:
Die SQL-Abfrage enthält keinen CTE. Stattdessen wird es eine einfache GROUP BY geben.
Mit diesem Mechanismus können Sie die Datenbank bei Bedarf auch problemlos denormalisieren:
Wenn Sie die
Datumsfunktion für die Bestellposition aufrufen, erfolgt das Lesen aus der Tabelle mit den Bestellpositionen des Felds, für das es einen Index gibt. Beim Ändern des Bestelldatums berechnet das System selbst das denormalisierte Datum in der Zeile automatisch neu.
Die Vorteile
Warum wird dieser ganze Mechanismus benötigt? In klassischen DBMS kann ein Entwickler oder DBA ohne Umschreiben von Abfragen nur Indizes ändern, Statistiken ermitteln und dem Abfrageplaner mitteilen, wie sie ausgeführt werden sollen (außerdem sind HINTs nur in kommerziellen DBMS verfügbar). Unabhängig davon, wie sehr sie sich bemühen, können sie die erste Anforderung im Artikel für
O (Anzahl der Abteilungen) nicht erfüllen, ohne die Anforderungen zu ändern und Auslöser hinzuzufügen. In dem vorgeschlagenen Schema müssen Sie in der Entwicklungsphase nicht über die Struktur der Datenspeicherung und die zu verwendenden Aggregationen nachdenken. All dies kann einfach im laufenden Betrieb direkt im Betrieb geändert werden.
In der Praxis ist dies wie folgt. Einige Leute entwickeln Logik direkt basierend auf der Aufgabe. Sie kennen sich weder mit Algorithmen und ihrer Komplexität noch mit Ausführungsplänen, mit Join'ov-Typen oder mit anderen technischen Komponenten aus. Diese Leute sind mehr Geschäftsanalysten als Entwickler. Dann geht alles in den Test oder Betrieb. Die Protokollierung langer Abfragen ist aktiviert. Wenn eine lange Anforderung erkannt wird, entscheiden sich andere Personen (eher technisch - tatsächlich DBA) dafür, MATERIALISIERT in eine Zwischenfunktion aufzunehmen. Dadurch wird die Aufzeichnung etwas verlangsamt (da ein zusätzliches Feld in einer Transaktion aktualisiert werden muss). Dies wird jedoch nicht nur erheblich beschleunigt, sondern auch alle anderen, die diese Funktion verwenden. Gleichzeitig ist es relativ einfach, eine Entscheidung darüber zu treffen, welche bestimmte Funktion verwirklicht werden soll. Zwei Hauptparameter: Die Anzahl der möglichen Eingabewerte (genau wie viele Datensätze in der entsprechenden Tabelle enthalten sind) und wie oft sie in anderen Funktionen verwendet werden.
Analoga
Moderne kommerzielle DBMS verfügen über ähnliche Mechanismen: MATERIALISIERTE ANSICHT mit FAST REFRESH (Oracle) und INDEXED VIEW (Microsoft SQL Server). In PostgreSQL kann MATERIALIZED VIEW nicht in einer Transaktion aktualisiert werden, sondern nur auf Anfrage (und sogar mit sehr strengen Einschränkungen), daher berücksichtigen wir dies nicht. Sie haben jedoch mehrere Probleme, die ihre Verwendung stark einschränken.
Erstens können Sie die Materialisierung nur aktivieren, wenn Sie bereits eine reguläre ANSICHT erstellt haben. Andernfalls müssen Sie die verbleibenden Anforderungen für den Zugriff auf die neu erstellte Ansicht neu schreiben, um diese Materialisierung verwenden zu können. Oder lassen Sie alles so, wie es ist, aber es ist zumindest unwirksam, wenn bestimmte Daten bereits berechnet wurden, aber viele Abfragen verwenden sie nicht immer, sondern berechnen sie erneut.
Zweitens haben sie eine Vielzahl von Einschränkungen:
Oracle5.3.8.4 Allgemeine Einschränkungen für die schnelle Aktualisierung
Die definierende Abfrage der materialisierten Ansicht ist wie folgt eingeschränkt:
- Die materialisierte Ansicht darf keine Verweise auf sich nicht wiederholende Ausdrücke wie
SYSDATE
und ROWNUM
. - Die materialisierte Ansicht darf keine Verweise auf
RAW
oder LONG
RAW
-Datentypen enthalten. - Es darf keine
SELECT
Listenunterabfrage enthalten. - Die
SELECT
Klausel darf keine Analysefunktionen (z. B. RANK
) enthalten. - Es kann nicht auf eine Tabelle verweisen, für die ein
XMLIndex
Index definiert ist. - Es darf keine
MODEL
Klausel enthalten. - Es darf keine
HAVING
Klausel mit einer Unterabfrage enthalten. - Es darf keine verschachtelten Abfragen enthalten, die
ANY
, ALL
oder NOT
EXISTS
. - Es darf keine
[START WITH …] CONNECT BY
Klausel [START WITH …] CONNECT BY
enthalten. - Es kann nicht mehrere Detailtabellen an verschiedenen Standorten enthalten.
ON
COMMIT
materialisierte Ansichten können keine Remote-Detailtabellen enthalten.- Verschachtelte materialisierte Ansichten müssen einen Join oder ein Aggregat haben.
- Materialisierte Join-Ansichten und materialisierte Aggregatansichten mit einer
GROUP
BY
Klausel können nicht aus einer indexorganisierten Tabelle ausgewählt werden.
5.3.8.5 Einschränkungen bei der schnellen Aktualisierung von materialisierten Ansichten nur mit Verknüpfungen
Das Definieren von Abfragen für materialisierte Ansichten nur mit Verknüpfungen und ohne Aggregate unterliegt den folgenden Einschränkungen für die schnelle Aktualisierung:
- Alle Einschränkungen aus " Allgemeine Einschränkungen für die schnelle Aktualisierung ".
- Sie dürfen keine
GROUP
BY
Klauseln oder -Aggregate haben. - Rowids aller Tabellen in der
FROM
Liste müssen in der SELECT
Liste der Abfrage angezeigt werden. - Materialisierte Ansichtsprotokolle müssen mit Zeilen-IDs für alle Basistabellen in der
FROM
Liste der Abfrage vorhanden sein. - Sie können keine schnell aktualisierbare materialisierte Ansicht aus mehreren Tabellen mit einfachen Verknüpfungen erstellen, die eine Objekttypspalte in der
SELECT
Anweisung enthalten.
Außerdem ist die von Ihnen gewählte Aktualisierungsmethode nicht optimal, wenn:
- Die definierende Abfrage verwendet einen äußeren Join, der sich wie ein innerer Join verhält. Wenn die definierende Abfrage einen solchen Join enthält, sollten Sie die definierende Abfrage so umschreiben, dass sie einen inneren Join enthält.
- Die
SELECT
Liste der materialisierten Ansicht enthält Ausdrücke für Spalten aus mehreren Tabellen.
5.3.8.6 Einschränkungen bei der schnellen Aktualisierung materialisierter Ansichten mit Aggregaten
Das Definieren von Abfragen für materialisierte Ansichten mit Aggregaten oder Verknüpfungen unterliegt den folgenden Einschränkungen für die schnelle Aktualisierung:
Die schnelle Aktualisierung wird sowohl für materialisierte ON
COMMIT
als auch für ON
DEMAND
Ansichten unterstützt. Es gelten jedoch die folgenden Einschränkungen:
- Alle Tabellen in der materialisierten Ansicht müssen materialisierte Ansichtsprotokolle haben, und die materialisierten Ansichtsprotokolle müssen:
- Enthalten alle Spalten aus der Tabelle, auf die in der materialisierten Ansicht verwiesen wird.
ROWID
INCLUDING
mit ROWID
und INCLUDING
VALUES
.- Geben Sie die
SEQUENCE
Klausel an, wenn für die Tabelle eine Mischung aus Einfügungen / direkten Ladevorgängen, Löschvorgängen und Aktualisierungen erwartet wird.
- Für eine schnelle Aktualisierung werden nur
SUM
, COUNT
, AVG
, VARIANCE
, VARIANCE
, MIN
und MAX
unterstützt. COUNT(*)
muss angegeben werden.- Aggregatfunktionen dürfen nur als äußerster Teil des Ausdrucks auftreten. Das heißt, Aggregate wie
AVG(AVG(x))
oder AVG(x)
+ AVG(x)
sind nicht zulässig. - Für jedes Aggregat wie
AVG(expr)
muss der entsprechende COUNT(expr)
vorhanden sein. Oracle empfiehlt die SUM(expr)
. - Wenn
VARIANCE(expr)
oder STDDEV(expr
) angegeben ist, müssen COUNT(expr)
und SUM(expr)
angegeben werden. Oracle empfiehlt die SUM(expr *expr)
. - Die
SELECT
Spalte in der definierenden Abfrage kann kein komplexer Ausdruck mit Spalten aus mehreren Basistabellen sein. Eine mögliche Problemumgehung besteht darin, eine verschachtelte materialisierte Ansicht zu verwenden. - Die
SELECT
Liste muss alle GROUP
BY
Spalten enthalten. - Die materialisierte Ansicht basiert nicht auf einer oder mehreren entfernten Tabellen.
- Wenn Sie in den Filterspalten eines materialisierten Ansichtsprotokolls einen
CHAR
Datentyp verwenden, müssen die Zeichensätze der Master-Site und der materialisierten Ansicht identisch sein. - Wenn die materialisierte Ansicht eine der folgenden Optionen aufweist, wird die schnelle Aktualisierung nur bei herkömmlichen DML-Einfügungen und direkten Lasten unterstützt.
- Materialisierte Ansichten mit
MIN
oder MAX
Aggregaten - Materialisierte Ansichten, die
SUM(expr)
aber keinen COUNT(expr)
- Materialisierte Ansichten ohne
COUNT(*)
Eine solche materialisierte Ansicht wird als materialisierte Ansicht nur zum Einfügen bezeichnet. - Eine materialisierte Ansicht mit
MAX
oder MIN
kann nach Lösch- oder gemischten DML-Anweisungen schnell aktualisiert werden, wenn sie keine WHERE
Klausel enthält.
Die maximale Aktualisierung von max / min nach dem Löschen oder der gemischten DML hat nicht das gleiche Verhalten wie der Nur-Einfügen-Fall. Es löscht und berechnet die Max / Min-Werte für die betroffenen Gruppen neu. Sie müssen sich der Auswirkungen auf die Leistung bewusst sein. - Materialisierte Ansichten mit benannten Ansichten oder Unterabfragen in der
FROM
Klausel können schnell aktualisiert werden, sofern die Ansichten vollständig zusammengeführt werden können. Informationen dazu, welche Ansichten zusammengeführt werden, finden Sie in der Oracle Database SQL-Sprachreferenz . - Wenn keine äußeren Verknüpfungen vorhanden sind, haben Sie möglicherweise eine beliebige Auswahl und Verknüpfungen in der
WHERE
Klausel. - Materialisierte Aggregatansichten mit äußeren Verknüpfungen können nach herkömmlicher DML und direktem Laden schnell aktualisiert werden, sofern nur die äußere Tabelle geändert wurde. Außerdem müssen eindeutige Einschränkungen für die Verknüpfungsspalten der inneren Verknüpfungstabelle vorhanden sein. Wenn es äußere
AND
gibt, müssen alle AND
durch AND
und den Gleichheitsoperator ( =
) verwenden. - Für materialisierte Ansichten mit
CUBE
, ROLLUP
, Gruppierungssätzen oder deren Verkettung gelten die folgenden Einschränkungen:
- Die
SELECT
Liste sollte einen Gruppierungsunterscheidungsmerkmal enthalten, der entweder eine GROUPING_ID
Funktion für alle GROUP
BY
Ausdrücke oder eine GROUPING
Funktion für jeden GROUP
BY
Ausdruck sein kann. Wenn die GROUP
BY
Klausel der materialisierten Ansicht beispielsweise " GROUP
BY
CUBE(a, b)
" GROUPING_ID(a, b)
sollte die SELECT
Liste entweder " GROUPING_ID(a, b)
" oder " GROUPING(a)
AND
GROUPING(b)
"damit die materialisierte Ansicht schnell aktualisiert werden kann. GROUP
BY
sollte nicht zu doppelten Gruppierungen führen. Beispielsweise kann " GROUP BY a, ROLLUP(a, b)
" nicht schnell aktualisiert werden, da dies zu doppelten Gruppierungen " (a), (a, b), AND (a)
" führt.
5.3.8.7 Einschränkungen bei der schnellen Aktualisierung materialisierter Ansichten mit UNION ALL
Materialisierte Ansichten mit dem Set-Operator UNION
ALL
unterstützen die Option REFRESH
FAST
wenn die folgenden Bedingungen erfüllt sind:
- Die definierende Abfrage muss den Operator
UNION
ALL
auf der obersten Ebene haben.
Der UNION
ALL
Operator kann nicht in eine Unterabfrage eingebettet werden, mit einer Ausnahme: Der UNION
ALL
kann sich in einer Unterabfrage in der FROM
Klausel befinden, vorausgesetzt, die definierende Abfrage hat die Form SELECT * FROM
(Ansicht oder Unterabfrage mit UNION
ALL
) wie im Folgenden Beispiel:
CREATE VIEW view_with_unionall AS
(SELECT c.rowid crid, c.cust_id, 2 umarker
VON Kunden c WHERE c.cust_last_name = 'Smith'
UNION ALL
SELECT c.rowid crid, c.cust_id, 3 umarker
VON Kunden c WHERE c.cust_last_name = 'Jones');
MATERIALISIERTE ANSICHT ERSTELLEN unionall_inside_view_mv
SCHNELL AUF NACHFRAGE WIEDERAUFNEHMEN
SELECT * FROM view_with_unionall;
Beachten Sie, dass die Ansicht view_with_unionall
die Anforderungen für eine schnelle Aktualisierung erfüllt. - Jeder Abfrageblock in der
UNION
ALL
Abfrage muss die Anforderungen einer schnell aktualisierbaren materialisierten Ansicht mit Aggregaten oder einer schnell aktualisierbaren materialisierten Ansicht mit Verknüpfungen erfüllen.
Die entsprechenden Protokolle für materialisierte Ansichten müssen in den Tabellen erstellt werden, wie dies für den entsprechenden Typ der schnell aktualisierbaren materialisierten Ansicht erforderlich ist.
Beachten Sie, dass die Oracle-Datenbank auch den Sonderfall einer materialisierten Ansicht einer einzelnen Tabelle mit ROWID
sofern die Spalte ROWID
in der Liste SELECT
und im Protokoll der materialisierten Ansicht enthalten ist. Dies wird in der definierenden Abfrage der Ansicht view_with_unionall
. - Die
SELECT
Liste jeder Abfrage muss einen UNION
ALL
Marker enthalten, und die UNION
ALL
Spalte muss in jedem UNION
ALL
Zweig einen eindeutigen konstanten numerischen Wert oder Zeichenfolgenwert haben. Außerdem muss die Markierungsspalte in der SELECT
Liste jedes Abfrageblocks an derselben Ordnungsposition erscheinen. Weitere Informationen zu UNION
ALL
Markern finden Sie unter " UNION ALL-Marker und Umschreiben von Abfragen ". - Einige Funktionen wie äußere Verknüpfungen, Abfragen von materialisierten Ansichten mit nur Einfügung und Remote-Tabellen werden für materialisierte Ansichten mit
UNION
ALL
nicht unterstützt. Beachten Sie jedoch, dass bei der Replikation verwendete materialisierte Ansichten, die keine Verknüpfungen oder Aggregate enthalten, schnell aktualisiert werden können, wenn UNION
ALL
oder Remote-Tabellen verwendet werden. - Der Kompatibilitätsinitialisierungsparameter muss auf 9.2.0 oder höher eingestellt sein, um mit
UNION
ALL
eine schnell aktualisierbare materialisierte Ansicht zu erstellen.
Ich möchte Oracle-Fans nicht beleidigen, aber nach ihrer Liste von Einschränkungen zu urteilen, scheint es, dass dieser Mechanismus im allgemeinen Fall nicht mit einem Modell geschrieben wurde, sondern mit Tausenden von Indern, bei denen jeder seinen eigenen Thread schreiben durfte und jeder von ihnen konnte und tat. Die Verwendung dieses Mechanismus für echte Logik ist wie das Gehen in einem Minenfeld. Sie können jederzeit eine Mine erwerben, die auf eine der nicht offensichtlichen Einschränkungen stößt. Wie dies funktioniert, ist ebenfalls ein separates Thema, das jedoch nicht in den Geltungsbereich dieses Artikels fällt.
Microsoft SQL ServerZusätzliche Anforderungen
Zusätzlich zu den SET-Optionen und den deterministischen Funktionsanforderungen müssen die folgenden Anforderungen erfüllt sein:
- Der Benutzer, der
CREATE INDEX
ausführt, muss der Eigentümer der Ansicht sein. - Wenn Sie den Index erstellen, muss die Option
IGNORE_DUP_KEY
auf OFF (Standardeinstellung) gesetzt sein. - Tabellen müssen durch zweiteilige Namen, Schema , referenziert werden . Tabellenname in der Ansichtsdefinition.
- Benutzerdefinierte Funktionen, auf die in der Ansicht verwiesen wird, müssen mit der Option
WITH SCHEMABINDING
. - Auf benutzerdefinierte Funktionen, auf die in der Ansicht verwiesen wird, muss durch den zweiteiligen Namen <Schema> verwiesen werden . <Funktion> .
- Die Datenzugriffseigenschaft einer benutzerdefinierten Funktion muss
NO SQL
, und die externe Zugriffseigenschaft muss NO
. - Common Language Runtime (CLR) -Funktionen können in der Auswahlliste der Ansicht angezeigt werden, können jedoch nicht Teil der Definition des Clustered-Indexschlüssels sein. CLR-Funktionen können nicht in der WHERE-Klausel der Ansicht oder der ON-Klausel einer JOIN-Operation in der Ansicht angezeigt werden.
- Für CLR-Funktionen und -Methoden von benutzerdefinierten CLR-Typen, die in der Ansichtsdefinition verwendet werden, müssen die Eigenschaften wie in der folgenden Tabelle angegeben festgelegt sein.
- Die Ansicht muss mit der Option
WITH SCHEMABINDING
. - Die Ansicht darf nur auf Basistabellen verweisen, die sich in derselben Datenbank wie die Ansicht befinden. Die Ansicht kann nicht auf andere Ansichten verweisen.
- Die SELECT-Anweisung in der Ansichtsdefinition darf die folgenden Transact-SQL-Elemente nicht enthalten:
1 Die indizierte Ansicht kann Float- Spalten enthalten. Solche Spalten können jedoch nicht in den Clustered-Indexschlüssel aufgenommen werden. - Wenn
GROUP BY
vorhanden ist, muss die VIEW-Definition COUNT_BIG(*)
und darf HAVING
nicht enthalten. Diese GROUP BY
Einschränkungen gelten nur für die Definition der indizierten Ansicht. Eine Abfrage kann eine indizierte Ansicht in ihrem Ausführungsplan verwenden, auch wenn diese GROUP BY
Einschränkungen nicht erfüllt sind. - Wenn die Ansichtsdefinition eine
GROUP BY
Klausel enthält, kann der Schlüssel des eindeutigen Clustered-Index nur auf die in der GROUP BY
Klausel angegebenen Spalten verweisen.
Hier können Sie sehen, dass die Indianer nicht angezogen wurden, da sie beschlossen, nach dem Schema „Wir werden wenig, aber gut tun“ zu tun. Das heißt, sie haben mehr Minen auf dem Feld, aber ihr Standort ist transparenter. Das Beunruhigendste ist diese Einschränkung:
Die Ansicht darf nur auf Basistabellen verweisen, die sich in derselben Datenbank wie die Ansicht befinden. Die Ansicht kann nicht auf andere Ansichten verweisen.
In unserer Terminologie bedeutet dies, dass eine Funktion nicht auf eine andere materialisierte Funktion zugreifen kann. Es schneidet die ganze Ideologie im Keim.
Diese Einschränkung (und weiter im Text) reduziert auch die Anwendungsfälle erheblich:
Die SELECT-Anweisung in der Ansichtsdefinition darf die folgenden Transact-SQL-Elemente nicht enthalten:
OUTER JOINS, UNION, ORDER BY und andere sind verboten. Vielleicht war es einfacher anzugeben, was verwendet werden kann als was nicht. Die Liste wäre wahrscheinlich viel kleiner.
Zusammenfassend lässt sich sagen, dass in jedem (ich stelle fest, kommerziellen) DBMS eine Vielzahl von Einschränkungen gegenüber keinem (mit Ausnahme eines logischen und nicht eines technischen) in der LGPL-Technologie bestehen. Es ist jedoch zu beachten, dass die Implementierung dieses Mechanismus in der relationalen Logik etwas komplizierter ist als in der beschriebenen Funktion.
Implementierung
Wie funktioniert es PostgreSQL wird als "virtuelle Maschine" verwendet. Im Inneren befindet sich ein komplexer Algorithmus, der Abfragen erstellt. Hier ist der
Quellcode . Und es gibt nicht nur eine große Anzahl von Heuristiken mit einer Reihe von Wenns. Wenn Sie also ein paar Monate Zeit haben, um zu studieren, können Sie versuchen, die Architektur zu verstehen.
Funktioniert es effizient? Effektiv genug. Leider ist es schwierig, dies zu beweisen. Ich kann nur sagen, dass wenn Sie die Tausenden von Anfragen in großen Anwendungen berücksichtigen, diese im Durchschnitt effektiver sind als ein guter Entwickler. Ein ausgezeichneter SQL-Programmierer kann jede Abfrage effizienter schreiben, aber mit tausend Abfragen hat er einfach weder Motivation noch Zeit, dies zu tun. Das einzige, was ich jetzt als Beweis für die Wirksamkeit geben kann, ist, dass auf der Grundlage der auf diesem DBMS basierenden Plattform mehrere
ERP-Systemprojekte funktionieren, in denen Tausende verschiedener MATERIALISIERTER Funktionen mit Tausenden von Benutzern und Terrabyte-Datenbanken mit Hunderten von Millionen von Datensätzen arbeiten auf einem normalen Dual-Prozessor-Server. Jeder kann jedoch die Effektivität testen / widerlegen, indem er die
Plattform und PostgreSQL herunterlädt,
die SQL-Abfrageprotokollierung
aktiviert und versucht, die Logik und die Daten dort zu ändern.
In den folgenden Artikeln werde ich auch darüber sprechen, wie Sie Einschränkungen für Funktionen aufhängen, mit Änderungssitzungen arbeiten und vieles mehr können.