Fragen Sie sich, was Postgresql-Schemas sind und warum sie wichtig sind und wie Sie Schemas verwenden können, um Ihre Datenbankimplementierungen robuster und wartbarer zu machen? Dieser Artikel stellt die Grundlagen von Schemas in Postgresql vor und zeigt Ihnen anhand einiger grundlegender Beispiele, wie Sie sie erstellen. Zukünftige Artikel werden sich mit Beispielen befassen, wie Schemas für echte Anwendungen gesichert und verwendet werden können.
Um mögliche Terminologieverwirrungen zu beseitigen, lassen Sie uns zunächst verstehen, dass der Begriff „Schema“ in der Postgresql-Welt möglicherweise etwas unglücklicherweise überladen ist. Im breiteren Kontext relationaler Datenbankverwaltungssysteme (RDBMS) könnte der Begriff „Schema“ so verstanden werden, dass er sich auf das gesamte logische oder physische Design der Datenbank bezieht, d. h. die Definition aller Tabellen, Spalten, Ansichten und anderer Objekte die die Datenbankdefinition bilden. In diesem breiteren Kontext kann ein Schema in einem Entity-Relationship-Diagramm (ER) oder einem Skript von DDL-Anweisungen (Data Definition Language) ausgedrückt werden, die zum Instanziieren der Anwendungsdatenbank verwendet werden.
In der Postgresql-Welt könnte der Begriff „Schema“ besser als „Namespace“ verstanden werden. Tatsächlich werden Schemas in den Postgresql-Systemtabellen in Tabellenspalten namens „Namespace“ aufgezeichnet, was meiner Meinung nach eine genauere Terminologie ist. Aus praktischen Gründen interpretiere ich jedes Mal, wenn ich „Schema“ im Kontext von Postgresql sehe, es stillschweigend als „Namensraum“ um.
Aber Sie fragen sich vielleicht:„Was ist ein Namensraum?“ Im Allgemeinen ist ein Namensraum ein ziemlich flexibles Mittel zum Organisieren und Identifizieren von Informationen nach Namen. Stellen Sie sich zum Beispiel zwei benachbarte Haushalte vor, die Smiths, Alice und Bob, und die Jones, Bob und Cathy (vgl. Abbildung 1). Wenn wir nur Vornamen verwenden, könnte es verwirrend werden, welche Person wir meinen, wenn wir über Bob sprechen. Aber durch das Hinzufügen des Nachnamens, Smith oder Jones, identifizieren wir eindeutig, welche Person wir meinen.
Namensräume sind häufig in einer verschachtelten Hierarchie organisiert. Dies ermöglicht eine effiziente Klassifizierung von riesigen Informationsmengen in sehr feinkörnige Strukturen, wie zum Beispiel das Internet-Domain-Name-System. Auf der obersten Ebene definieren „.com“, „.net“, „.org“, „.edu“ usw. breite Namensräume, in denen registrierte Namen für bestimmte Entitäten eingetragen sind, z. B. „severalnines.com“. und „postgresql.org“ sind eindeutig definiert. Aber unter jeder von ihnen gibt es eine Reihe gemeinsamer Subdomains wie zum Beispiel „www“, „mail“ und „ftp“, die allein duplikativ sind, aber innerhalb der jeweiligen Namensräume eindeutig sind.
Postgresql-Schemas dienen demselben Zweck der Organisation und Identifizierung, jedoch können Postgresql-Schemas im Gegensatz zum zweiten Beispiel oben nicht in einer Hierarchie verschachtelt werden. Während eine Datenbank viele Schemas enthalten kann, gibt es immer nur eine Ebene, und daher müssen Schemanamen innerhalb einer Datenbank eindeutig sein. Außerdem muss jede Datenbank mindestens ein Schema enthalten. Immer wenn eine neue Datenbank instanziiert wird, wird ein Standardschema namens „public“ erstellt. Der Inhalt eines Schemas umfasst alle anderen Datenbankobjekte wie Tabellen, Ansichten, gespeicherte Prozeduren, Trigger usw. Zur Veranschaulichung siehe Abbildung 2, die eine matrjoschka-puppenartige Verschachtelung darstellt, die zeigt, wo Schemas in die Struktur von a passen Postgresql-Datenbank.
Neben der einfachen Organisation von Datenbankobjekten in logischen Gruppen, um sie besser handhabbar zu machen, dienen Schemas dem praktischen Zweck, Namenskollisionen zu vermeiden. Ein Betriebsparadigma beinhaltet das Definieren eines Schemas für jeden Datenbankbenutzer, um ein gewisses Maß an Isolation bereitzustellen, einen Raum, in dem Benutzer ihre eigenen Tabellen und Ansichten definieren können, ohne sich gegenseitig zu stören. Ein anderer Ansatz besteht darin, Tools von Drittanbietern oder Datenbankerweiterungen in einzelne Schemas zu installieren, um alle zugehörigen Komponenten logisch zusammenzuhalten. Ein späterer Artikel in dieser Serie wird einen neuartigen Ansatz für robustes Anwendungsdesign beschreiben, der Schemas als indirektes Mittel verwendet, um die Offenlegung des physischen Datenbankdesigns zu begrenzen, und stattdessen eine Benutzeroberfläche präsentiert, die synthetische Schlüssel auflöst und die langfristige Wartung und das Konfigurationsmanagement erleichtert wenn sich die Systemanforderungen weiterentwickeln.
Lass uns Code schreiben!
Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunterDer einfachste Befehl zum Erstellen eines Schemas innerhalb einer Datenbank ist
CREATE SCHEMA hollywood;
Dieser Befehl erfordert Erstellungsrechte in der Datenbank, und das neu erstellte Schema „hollywood“ gehört dem Benutzer, der den Befehl aufruft. Ein komplexerer Aufruf kann optionale Elemente enthalten, die einen anderen Eigentümer angeben, und kann sogar DDL-Anweisungen enthalten, die Datenbankobjekte innerhalb des Schemas in einem einzigen Befehl instanziieren!
Das allgemeine Format ist
CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]
wobei „Benutzername“ der Besitzer des Schemas ist und „Schema_Element“ einer von bestimmten DDL-Befehlen sein kann (Einzelheiten finden Sie in der Postgresql-Dokumentation). Superuser-Privilegien sind erforderlich, um die Option AUTHORIZATION zu verwenden.
Um beispielsweise ein Schema mit dem Namen „Hollywood“ zu erstellen, das eine Tabelle mit dem Namen „Filme“ enthält, und den Namen „Winners“ in einem Befehl anzuzeigen, könnten Sie Folgendes tun
CREATE SCHEMA hollywood
CREATE TABLE films (title text, release date, awards text[])
CREATE VIEW winners AS
SELECT title, release FROM films WHERE awards IS NOT NULL;
Weitere Datenbankobjekte können nachträglich direkt erstellt werden, beispielsweise würde mit
eine zusätzliche Tabelle zum Schema hinzugefügtCREATE TABLE hollywood.actors (name text, dob date, gender text);
Beachten Sie im obigen Beispiel das Präfix des Tabellennamens mit dem Schemanamen. Dies ist erforderlich, da standardmäßig, dh ohne explizite Schemaspezifikation, neue Datenbankobjekte innerhalb des aktuellen Schemas erstellt werden, das wir als nächstes behandeln werden.
Erinnern Sie sich daran, dass wir im obigen Beispiel für den ersten Namensraum zwei Personen mit dem Namen Bob hatten, und wir beschrieben haben, wie man sie durch Einbeziehung des Nachnamens auflöst oder unterscheidet. Aber innerhalb jedes der Haushalte von Smith und Jones versteht jede Familie „Bob“, um sich auf denjenigen zu beziehen, der zu diesem bestimmten Haushalt gehört. So muss beispielsweise Alice ihren Ehemann im Kontext des jeweiligen Haushalts nicht mit Bob Jones ansprechen, und Cathy muss ihren Ehemann nicht mit Bob Smith bezeichnen:Sie können beide einfach „Bob“ sagen.
Das aktuelle Postgresql-Schema ähnelt dem Haushalt im obigen Beispiel. Auf Objekte im aktuellen Schema kann ohne Qualifizierung verwiesen werden, aber um auf ähnlich benannte Objekte in anderen Schemas zu verweisen, muss der Name qualifiziert werden, indem dem Schemanamen wie oben vorangestellt wird.
Das aktuelle Schema wird aus dem Konfigurationsparameter „search_path“ abgeleitet. Dieser Parameter speichert eine durch Kommas getrennte Liste von Schemanamen und kann mit dem Befehl
untersucht werdenSHOW search_path;
oder mit
auf einen neuen Wert setzenSET search_path TO schema [, schema, ...];
Der erste Schemaname in der Liste ist das „aktuelle Schema“ und dort werden neue Objekte erstellt, wenn er ohne Schemanamenqualifizierung angegeben wird.
Die durch Kommas getrennte Liste von Schemanamen dient auch dazu, die Suchreihenfolge zu bestimmen, in der das System vorhandene nicht qualifizierte benannte Objekte findet. Zurück in der Nachbarschaft von Smith und Jones würde beispielsweise eine Paketlieferung, die nur an „Bob“ adressiert ist, einen Besuch in jedem Haushalt erfordern, bis der erste Bewohner namens „Bob“ gefunden wird. Beachten Sie, dass dies möglicherweise nicht der beabsichtigte Empfänger ist. Die gleiche Logik gilt für Postgresql. Das System sucht nach Tabellen, Ansichten und anderen Objekten innerhalb von Schemas in der Reihenfolge des Suchpfads, und dann wird das erste gefundene Namensübereinstimmungsobjekt verwendet. Schemaqualifizierte benannte Objekte werden direkt ohne Bezugnahme auf den Suchpfad verwendet.
In der Standardkonfiguration ergibt die Abfrage der Konfigurationsvariablen search_path diesen Wert
SHOW search_path;
Search_path
--------------
"$user", public
Das System interpretiert den ersten oben angezeigten Wert als den aktuell angemeldeten Benutzernamen und berücksichtigt den zuvor erwähnten Anwendungsfall, bei dem jedem Benutzer ein benutzerbenanntes Schema für einen Arbeitsbereich zugewiesen wird, der von anderen Benutzern getrennt ist. Wenn kein solches benutzerbenanntes Schema erstellt wurde, wird dieser Eintrag ignoriert und das „öffentliche“ Schema wird zum aktuellen Schema, in dem neue Objekte erstellt werden.
Zurück zu unserem früheren Beispiel zum Erstellen der Tabelle „hollywood.actors“:Wenn wir den Tabellennamen nicht mit dem Schemanamen qualifiziert hätten, wäre die Tabelle im öffentlichen Schema erstellt worden. Wenn wir davon ausgegangen sind, alle Objekte innerhalb eines bestimmten Schemas zu erstellen, könnte es praktisch sein, die search_path-Variable wie
zu setzenSET search_path TO hollywood,public;
Erleichterung der Kurzschrift für die Eingabe unqualifizierter Namen zum Erstellen oder Zugreifen auf Datenbankobjekte.
Es gibt auch eine Systeminformationsfunktion, die bei einer Abfrage das aktuelle Schema zurückgibt
select current_schema();
Im Falle einer falschen Schreibweise kann der Besitzer eines Schemas den Namen ändern, vorausgesetzt, der Benutzer hat auch Erstellungsrechte für die Datenbank, mit dem
ALTER SCHEMA old_name RENAME TO new_name;
Und schließlich, um ein Schema aus einer Datenbank zu löschen, gibt es einen Drop-Befehl
DROP SCHEMA schema_name;
Der DROP-Befehl schlägt fehl, wenn das Schema irgendwelche Objekte enthält, also müssen sie zuerst gelöscht werden, oder Sie können optional alle Inhalte eines Schemas mit der CASCADE-Option rekursiv löschen
DROP SCHEMA schema_name CASCADE;
Diese Grundlagen erleichtern Ihnen den Einstieg in das Verständnis von Schemas!