| PostgreSQL: Das Offizielle Handbuch | ||||
|---|---|---|---|---|
| Zurück | Schnell zurück | Schnell nach vorne | Nach vorne | |
Dieses Kapitel bespricht das Regelnsystem von PostgreSQL. Produktionsregelnsysteme sind im Prinzip ganz einfach, aber es gibt einige kleine Details, die man bei der Verwendung beachten muss.
Einige andere Datenbanksysteme definieren aktive Datenbankregeln, die meistens gespeicherte Prozeduren und Trigger sind. Diese kann man in PostgreSQL auch mit Funktionen und Triggern implementieren.
Das Regelnsystem (genauer gesagt das Anfrageumschreiberegelnsystem) unterscheidet sich vollkommen von gespeicherten Prozeduren und Triggern. Es verändert Anfragen anhand der Regeln und übergibt die veränderte Anfrage an den Planer und Executor zur Ausführung. Es ist sehr leistungsfähig und kann für viele Anwendungen, wie SQL-Prozeduren, Sichten und Versionen, verwendet werden. Die theoretischen Grundlagen und die Möglichkeiten dieses Regelnsystems werden in auch Stonebraker, Jhingran, Goh 1990 und in Ong & Goh 1990 besprochen.
Um zu verstehen, wie das Regelnsystem funktioniert, muss man wissen, wann es aufgerufen wird und was seine Eingabe- und Ausgabewerte sind.
Das Regelnsystem befindet sich zwischen Parser und Planer. Es nimmt die Ausgabe des Parsers, einen Anfragebaum, und die benutzerdefinierten Umschreiberegeln, die ebenfalls Anfragebäume mit einigen zusätzlichen Informationen sind, und erzeugt daraus null oder mehr Anfragebäume als Ergebnis. Die Eingaben und Ausgaben des Regelnsystems sind also immer Strukturen, die der Parser selbst hätte erzeugen können, und sind daher im Prinzip alle als SQL-Befehl darstellbar.
Was ist also ein solcher Anfragebaum? Er ist eine interne Darstellung eines SQL-Befehls, in der die einzelnen Teil getrennt gespeichert sind. Diese Anfragebäume können Sie im Serverlog anzeigen lassen, indem Sie die Konfigurationsparameter debug_print_parse, debug_print_rewritten oder debug_print_plan setzen. Die Regelaktionen werden auch als Anfragebaum gespeichert, und zwar im Systemkatalog pg_rewrite. Sie sind nicht wie die Logausgabe formatiert, aber sie enthalten genau die gleichen Informationen.
Das Lesen eines Anfragebaums erfordert einige Erfahrung. Aber da die SQL-Darstellung eines Anfragebaums zum Verstehen des Regelnsystems ausreicht, wird dieses Kapitel Ihnen nicht zeigen, wie sie zu lesen sind.
Wenn Sie die SQL-Darstellung eines Anfragebaums in diesem Kapitel lesen, dann ist es nötig, die Teile zu identifizieren, in die ein Befehl in der Anfragebaumstruktur aufgespalten wird. Die Teile des Anfragebaums sind:
Dies ist ein einfacher Wert, der anzeigt, welcher Befehl (SELECT, INSERT, UPDATE, DELETE) den Anfragebaum erzeugt hat.
Die Range-Tabelle ist eine Liste der Relationen, die in der Anfrage verwendet werden. Bei einem SELECT-Befehl sind das die nach dem Schlüsselwort FROM angegebenen Relationen.
Jeder Eintrag in der Range-Tabelle identifiziert eine Tabelle oder eine Sicht und zeigt an, unter welchem Namen sie in anderen Teilen der Anfrage verwendet wird. Im Anfragebaum wird auf die Einträge der Range-Tabelle mit Nummern verwiesen, so dass es hier egal ist, ob es Namen doppelt gibt, im Gegensatz zu SQL-Befehlen. Das kann vorkommen, wenn die Range-Tabelle mit den Range-Tabellen der Regeln verschmolzen wird. In den Beispielen in diesem Kapitel wird das aber nicht vorkommen.
Das ist ein Index in die Range-Tabelle, der anzeigt, in welcher Relation das Ergebnis der Anfrage gespeichert werden soll.
SELECT-Anfragen haben normalerweise keine Ergebnisrelation. Der Sonderfall SELECT INTO ist im Großen und Ganzen identisch mit einem CREATE TABLE gefolgt von einem INSERT ... SELECT und wird hier nicht gesondert besprochen.
Bei den Befehlen INSERT, UPDATE und DELETE ist die Ergebnisrelation die Tabelle (oder die Sicht!), auf die der Befehl sich auswirkt.
Die Target-Liste ist eine Liste von Ausdrücken, die das Ergebnis der Anfrage definieren. Bei einem SELECT-Befehl sind dies die Ausdrücke, die das Endergebnis der Anfrage erzeugen. Sie entsprechen den Ausdrücken zwischen den Schlüsselwörtern SELECT und FROM. (* ist nur eine Abkürzung für alle Spalten einer Relation. Sie wird vom Parser in die einzelnen Spalten aufgelöst, so dass das Regelnsystem nichts davon mitbekommt.)
DELETE-Befehle benötigen keine Target-Liste, weil sie kein Ergebnis erzeugen. Der Planer fügt in die leere Target-Liste einen speziellen CTID-Eintrag ein, aber das passiert nach dem Regelnsystem und wird später besprochen; für das Regelnsystem ist die Target-Liste leer.
Bei INSERT-Befehlen beschreibt die Target-Liste die neuen Zeilen, die in die Ergebnisrelation eingefügt werden sollen. Sie besteht aus den Ausdrücken in der VALUES-Klausel oder aus denen in der SELECT-Klausel, wenn es sich um einen INSERT ... SELECT-Befehl handelt. Der erste Schritt des Umschreibevorgangs fügt in die Target-Liste Einträge für alle Spalten ein, die im ursprünglichen Befehl nicht angegeben wurden, aber Vorgabewerte haben. Alle übrigen Spalten (ohne angegebenen Wert und ohne Vorgabewert) werden vom Planer mit NULL-Werten aufgefüllt.
Bei UPDATE-Befehlen beschreibt die Target-Liste die neuen Zeilen, die die alten ersetzen sollen. Im Regelnsystem enthält es einfach die Ausdrücke aus den SET spalte = ausdruck Teilen des Befehls. Der Planer fügt für die nicht angegebenen Spalten Ausdrücke ein, die die Werte aus der alten Zeile in die neue kopieren. Und wie bei DELETE wird hier auch ein spezieller CTID-Eintrag eingefügt.
Jeder Eintrag in der Target-Liste enthält einen Ausdruck, der ein konstanter Wert, eine Variable, die auf eine Relation in der Range-Tabelle verweist, ein Parameter oder ein Ausdrucksbaum aus Funktionsaufrufen, Konstanten, Variablen, Operatoren usw. sein kann.
Die Bedingung einer Anfrage ist ein Ausdruck ähnlich derer in den Einträgen der Target-Liste. Das Ergebnis dieses Ausdrucks ist ein Boole'scher Wert, der anzeigt, ob die Operation (INSERT, UPDATE, DELETE oder SELECT) für die endgültige Ergebniszeile ausgeführt werden soll oder nicht. Sie entspricht der WHERE-Klausel in einem SQL-Befehl.
Der Verbundbaum einer Anfrage zeigt die Struktur der FROM-Klausel. Bei einer einfachen Anfrage wie SELECT ... FROM a, b, c ist der Verbundbaum einfach die Liste der Elemente in der FROM-Klausel, weil diese in jeder beliebigen Reihenfolge verbunden werden können. Aber wenn JOIN-Ausdrücke, insbesondere äußere Verbunde, verwendet werden, dann müssen die Relationen in der angegebenen Reihenfolge verbunden werden. In diesem Fall zeigt der Verbundbaum die Struktur der JOIN-Ausdrücke. Die Verbundbedingungen der jeweiligen JOIN-Ausdrücke (aus den Klauseln ON oder USING) werden als Bedingungsausdrücke in den Verbundbaum-Knoten gespeichert. Es hat sich als praktisch ergeben, den obersten Ausdruck aus der WHERE-Klausel auch als Bedingung im obersten Verbundbaum-Element zu speichern. Also enthält der Verbundbaum in Wirklichkeit sowohl die FROM- als auch die WHERE-Klausel eines SELECT-Befehls.
Die anderen Teile eines Anfragebaums, wie die ORDER BY-Klausel, sind hier nicht von Interesse. Das Regelnsystem wird dort bei der Anwendung der Regeln einige Einträge ersetzen, aber das hat mit den Grundlagen des Regelnsystems nicht viel zu tun.
| Zurück | Zum Anfang | Nach vorne |
| Ein vollständiges Beispiel | Nach oben | Sichten und das Regelnsystem |