it-swarm.com.de

PostgreSQL: Unveränderlich, flüchtig, stabil

Ich bin mir nicht sicher, welche Bedeutung die Definitionen für die Funktionen IMMUTABLE, VOLATILE und STABLE haben.

Ich habe die Dokumentation gelesen, insbesondere die Definitionen der einzelnen.

IMMUTABLE gibt an, dass die Funktion die Datenbank nicht ändern kann und immer das gleiche Ergebnis zurückgibt, wenn die gleichen Argumentwerte angegeben werden ; Das heißt, es werden keine Datenbanksuchen durchgeführt oder Informationen verwendet, die nicht direkt in der Argumentliste enthalten sind. Wenn diese Option angegeben ist, kann jeder Aufruf der Funktion mit allen Konstantenargumenten sofort durch den Funktionswert ersetzt werden.

STABLE gibt an, dass die Funktion die Datenbank nicht ändern kann und dass sie innerhalb eines einzelnen Tabellenscans konsistent dasselbe Ergebnis für dieselben Argumentwerte zurückgibt, aber das Das Ergebnis kann sich über SQL-Anweisungen hinweg ändern. Dies ist die geeignete Auswahl für Funktionen, deren Ergebnisse von Datenbanksuchen, Parametervariablen (z. B. der aktuellen Zeitzone) usw. abhängen. (Dies ist nicht für AFTER-Trigger geeignet, die vom aktuellen Befehl geänderte Zeilen abfragen möchten.) Beachten Sie außerdem, dass die Die Funktionsfamilie current_timestamp gilt als stabil, da sich ihre Werte innerhalb einer Transaktion nicht ändern.

VOLATILE gibt an, dass sich der Funktionswert auch innerhalb eines einzelnen Tabellenscans ändern kann, sodass keine Optimierungen vorgenommen werden können. Relativ wenige Datenbankfunktionen sind in diesem Sinne flüchtig; Einige Beispiele sind random (), currval (), timeofday (). Beachten Sie jedoch, dass jede Funktion mit Nebenwirkungen als volatil eingestuft werden muss, auch wenn das Ergebnis durchaus vorhersehbar ist, um zu verhindern, dass Anrufe wegoptimiert werden. Ein Beispiel ist setval ().

Meine Verwirrung kommt mit der Bedingung für IMMUTABLE und STABLE, dass die Funktion [~ # ~] immer [~ # ~] oder [~ # ~] konsistent [~ # ~] gibt das gleiche Ergebnis mit den gleichen Argumenten zurück.

Die IMMUTABLE-Definition besagt, dass die Funktion keine Datenbanksuchen durchführt oder Informationen verwendet, die nicht direkt in ihrer Argumentliste enthalten sind. Für mich bedeutet dies, dass solche Funktionen zum Manipulieren der vom Client bereitgestellten Daten verwendet werden und keine SELECT-Anweisungen enthalten sollten ... obwohl das für mich nur ein bisschen seltsam klingt.

Bei STABLE ist die Definition insofern ähnlich, als sie besagt, dass konsistent dasselbe Ergebnis zurückgegeben werden soll. Für mich bedeutet dies, dass die Funktion jedes Mal, wenn sie mit denselben Argumenten aufgerufen wird, dieselben Ergebnisse zurückgeben sollte (jedes Mal dieselben exakten Zeilen).

Für mich bedeutet dies, dass jede Funktion, die ein SELECT für eine Tabelle oder Tabellen ausführt, die aktualisiert werden können, nur flüchtig sein sollte.

Aber wieder ... das klingt für mich nicht richtig.

Um dies auf meinen Anwendungsfall zurückzuführen, schreibe ich Funktionen, die SELECT-Anweisungen mit mehreren JOINs für Tabellen ausführen, die ständig hinzugefügt werden. Daher wird erwartet, dass die Funktionsaufrufe bei jedem Aufruf unterschiedliche Ergebnisse zurückgeben, selbst mit denselben Argumenten .

Bedeutet das also, dass meine Funktionen VOLATIL sein sollten? Obwohl die Dokumentation angibt , sind relativ wenige Datenbankfunktionen in diesem Sinne flüchtig ?

Vielen Dank!

11
Brooks

IMMUTABLE muss eine reine Funktion sein, deren Ergebnisse nur von ihren Eingaben abhängen. Dies ist eine sehr strenge Anforderung; Sie können keine anderen nicht unveränderlichen Funktionen aufrufen, sie können nicht auf Tabellen zugreifen, sie können nicht auf den Wert von Konfigurationseigenschaften zugreifen usw.

STABLE kann alle Eingaben verwenden, die selbst STABLE sind: andere STABLE oder IMMUTABLE Funktionen und SELECT Abfragen von Tabellen. Das Abfragen von Tabellen ist sicher, da sich die Ansicht der Funktion dieser Tabellen im aktuellen Snapshot der Abfrage nicht ändert. Sie können auf GUC-Werte (current_setting(...)) zugreifen, sofern Sie wissen, dass sie nicht auch in der aktuellen Anweisung zugewiesen werden.

VOLATILE Funktionen sind alles, was nicht zu den oben genannten passt:

  • Alles mit Nebenwirkungen
  • Alles was schreibt
  • Alles, was externe Daten abfragt, die nicht vom PostgreSQL-Snapshot verwaltet werden
  • ...

Im Allgemeinen lassen Sie einfach alles VOLATILE, es sei denn, Sie haben einen guten Grund, dies nicht zu tun.

Der Hauptgrund für die Verwendung von IMMUTABLE ist das Schreiben von Funktionen, die als Teil von Indexausdrücken verwendet werden sollen.

15
Craig Ringer

Für STABLE ist der fett gedruckte Teil "Ergebnis kann sich über SQL-Anweisungen hinweg ändern".

IMMUTABLE Dinge sollen sich nie ändern. Auch wenn Sie Ihren Datenbankserver neu starten, führen Sie yum update (aber natürlich kann es Fehler geben!), ändern Sie Ihre Konfiguration (wie datestyle, timezone, default_text_search_config, extra_float_digits usw.) oder ersetzen Sie Ihre Serverhardware vollständig (mit derselben Architektur wie die alte Hardware, sodass die Binärdateien weiterhin kompatibel sind).

Die von Ihnen beschriebenen Funktionen klingen wie STABIL, da sie in einer einzelnen SQL-Anweisung ihre Abfragen mit demselben Snapshot wie die äußere Abfrage ausführen und daher alle gleichzeitigen Änderungen, die Sie an diesen anderen Tabellen vorgenommen haben, nicht sichtbar sind. Wenn Ihre Funktionen nun eine neue Verbindung zum Server öffnen und ihre Abfragen innerhalb dieser unabhängigen Verbindung ausführen, würde dies die Funktion flüchtig machen, da sie unterschiedliche Snapshots verwenden würden.

4
jjanes