PostgreSQL Leitfaden
1.
Einleitung
Einführung in PostgreSQL
Wenn man mit Entwicklern über unterschiedliche Datenbanklösungen spricht,
wird die Antwort üblicherweise zwei große Datenbanken umfassen. Die eine würde
MySQL sein und die andere wäre das, worauf sich dieser Text bezieht:
PostreSQL. Die Vorteile der einen gegenüber der anderen sind eine mehr
oder weniger langwierige Debatte, aber man kann sagen, dass PostgreSQL
eine stärkere Fokussierung auf relationale Datenbank-Strukturen hat als
MySQL. Die meisten Standard-Fähigkeiten wie FOREIGN KEY wurden
erst in MySQL 5 hinzugefügt. Jedoch geht dieses Dokument davon aus, dass Sie
PostgreSQL als Datenbank gewählt haben. Der erste Schritt mit dem wir
beginnen, ist der emerge Prozess. Im nächsten Abschnitt wird der
Installationsprozess mit "emerge" sowie die grundlegende Konfiguration
beschrieben.
PostgreSQL Installation
Um anzufangen, müssen wir zunächst ein emerge des PostgreSQL-Paketes
durchführen. Führen Sie dazu den folgenden Code aus, um sicherzustellen, dass
die Optionen des Paketes richtig gesetzt sind:
Befehlsauflistung 1.1: Überprüfung der PostgreSQL Build-Optionen |
# emerge -pv postgresql
These are the packages that I would merge, in order:
Calculating dependencies ...done!
[ebuild N ] dev-db/postgresql-8.0.4 -doc -kerberos +libg++ +nls +pam +perl -pg-intdatetime +python +readline (-selinux) +ssl -tcl +xml +zlib 0 kB
|
Hier ist eine Liste der unterschiedlichen Build-Optionen:
| USE-Flag |
Bedeutung |
| doc |
Dieses USE-Flag steuert die Installation von Dokumentation ausserhalb der
normalen Handbuchseiten (man pages). Wenn der Speicherplatz knapp ist, oder
wenn Sie alternative Methoden benutzen, um die Dokumentation einzusehen
(online z.B.), können Sie dieses Flag deaktivieren.
|
| kerberos |
Wenn diese Option aktiv ist, hat der Administrator während des
Verbindungsaufbaus zur Datenbank die Möglichkeit kerberos zur
Authentifizierung seiner Benutzer/Dienste zu verwenden.
|
| nls |
Wenn diese Option aktiv ist, kann PostgreSQL übersetzte Meldungen für
Benutzer, die nicht Englisch sprechen, verwenden.
|
| pam |
Wenn diese Option aktiv ist und der Administrator PostgreSQL entsprechend
konfiguriert hat, können sich Benutzer/Dienste über PAM (Pluggable
Authentication Module) zu einer Datenbank verbinden.
|
| perl |
Wenn diese Option aktiviert ist, wird die Unterstützung für Perl in
PostgreSQL eingebaut.
|
| pg-intdatetime |
Wenn diese Option aktiviert ist, unterstützt PostgreSQL 64-Bit-Integer
Datumstypen.
|
| python |
Wenn diese Option aktiviert ist, wird die Unterstützung für Python in
PostgreSQL eingebaut.
|
| readline |
Wenn diese Option aktiviert ist, unterstützt PostgreSQL das Bearbeiten von
Kommandozeilen mit readline. Das beinhaltet eine Kommando-Historie
und isearch.
|
| selinux |
Wenn diese Option aktiviert ist, wird eine Policy für selinux zur
Unterstützung von PostgreSQL installiert.
|
| ssl |
Wenn diese Option aktiviert ist, kann PostgreSQL OpenSSL benutzen um
den Datenverkehr zwischen Client und Server zu verschlüsseln.
|
| tcl |
Wenn diese Option aktiviert ist, wird die Unterstützung für Tcl/Tk in
PostgreSQL eingebaut.
|
| xml |
Wenn diese Option aktiviert ist, wird XML-Unterstützung im XPATH-Stil
eingebaut. Mehr Infomationen zur Benutzung der XML-Unterstützung in
PostgrSQL gibt es bei:
PostgreSQL and XML.
|
| zlib |
Diese Option ist nicht für PostgreSQL selbst, sondern für pg_dump um
seine Ausgabe zu komprimieren.
|
Wenn Sie PostgreSQL entsprechend Ihren Wünschen angepasst haben, starten Sie
die Installation mit emerge:
Befehlsauflistung 1.2: Emerge-ing PostgreSQL |
# emerge postgresql
>>> /usr/lib/libecpg.so.5 -> libecpg.so.5.0
>>> /usr/bin/postmaster -> postgres
* Make sure the postgres user in /etc/passwd has an account setup with /bin/bash as the shell
*
* Execute the following command
* emerge --config =postgresql-8.0.4
* to setup the initial database environment.
*
>>> Regenerating /etc/ld.so.cache...
>>> dev-db/postgresql-8.0.4 merged.
|
Wie in der Ausgabe von einfo gezeigt, sind noch einige Einstellungen zu machen.
Das nächste Kapitel wird einen Blick auf die Konfiguration von PostgreSQL
werfen.
2.
PostgreSQL Konfiguration
Initialisieren der Datenbank-Umgebung
Wie bereits in der Ausgabe von emerge erwähnt, muss zunächst die
Datenbank-Umgebung initialisiert werden. Aber bevor dies geschieht, muss eine
Sache beachtet werden: Anders als etwa MySQL ist das "root" Passwort von
PostgreSQL das Passwort des aktuellen Benutzers. Das Ebuild erzeugt aber nur den
Benutzer und nicht das Passwort. Deshalb muss, bevor wir anfangen, das
Passwort des Benutzers "postgres" gesetzt werden:
Befehlsauflistung 2.1: Setzen des Passworts |
# passwd postgres
New UNIX password:
Retype new UNIX password:
passwd: password updated successfully
|
Nachdem dies eingerichtet ist, kann die Initialisierung der Datenbank-Umgebung
erfolgen:
Befehlsauflistung 2.2: Konfiguration der Datenbank-Umgebung mit emerge --config |
# emerge --config =postgresql-8.0.4
Configuring pkg...
* Creating the data directory ...
* Initializing the database ...
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale C.
fixing permissions on existing directory /var/lib/postgresql/data ... ok
creating directory /var/lib/postgresql/data/global ... ok
creating directory /var/lib/postgresql/data/pg_xlog ... ok
creating directory /var/lib/postgresql/data/pg_xlog/archive_status ... ok
creating directory /var/lib/postgresql/data/pg_clog ... ok
creating directory /var/lib/postgresql/data/pg_subtrans ... ok
creating directory /var/lib/postgresql/data/base ... ok
creating directory /var/lib/postgresql/data/base/1 ... ok
creating directory /var/lib/postgresql/data/pg_tblspc ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 1000
creating configuration files ... ok
creating template1 database in /var/lib/postgresql/data/base/1 ... ok
initializing pg_shadow ... ok
enabling unlimited row size for system tables ... ok
initializing pg_depend ... ok
creating system views ... ok
loading pg_description ... ok
creating conversions ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.
Success. You can now start the database server using:
/usr/bin/postmaster -D /var/lib/postgresql/data
or
/usr/bin/pg_ctl -D /var/lib/postgresql/data -l logfile start
*
* You can use /etc/init.d/postgresql script to run PostgreSQL instead of pg_ctl.
*
|
Nun ist die initiale Datenbank-Umgebung eingerichtet. Der nächste Abschnitt
wird die Überprüfung der Installation und die Einrichtung von
Benutzern für den Zugriff auf die Datenbank erläutern.
Einrichtung der PostgreSQL-Datenbank
Nachdem PostgreSQL nun eingerichtet wurde, ist es eine gute Idee, die
Installation an diesem Punkt zu überprüfen. Stellen Sie zunächst sicher, dass
der Dienst korrekt startet:
Befehlsauflistung 2.3: Start des PostgreSQL-Dienstes |
# /etc/init.d/postgresql start
* Starting PostgreSQL ... [ ok ]
|
Nachdem überprüft wurde, dass dies Funktioniert, ist es eine weitere gute
Idee, den Dienst zum Runlevel "default" hinzuzufügen, so dass PostgreSQL beim
Hochfahren des Rechners startet:
Befehlsauflistung 2.4: Hinzufügen des Dienstes zum Runlevel "default" |
# rc-update add postgresql default
* postgresql added to runlevel default
|
Nachdem der Dienst nun gestartet wurde, ist es Zeit zu versuchen eine
Test-Datenbank einzurichten. Lassen Sie uns für den Anfang eine Test-Datenbank
mit dem Kommando createdb anlegen. Wir übergeben die Option -U um
den Benutzer zu setzen (ansonsten wird als Voreinstellung der aktuelle
Benutzername verwendet) und außerdem die Option -W um das Passwort
anzufordern, das wir oben erzeugt haben. Schließlich übergeben wir dem Kommando
den Namen der Datenbank, die wir erstellen wollen:
Befehlsauflistung 2.5: Anlegen einer Datenbank mit createdb |
$ createdb -U postgres -W test
Password:
CREATE DATABASE
|
Die Datenbank wurde erfolgreich angelegt und wir können nun überprüfen, ob
sie einfache Aufgaben durchführen kann. Wir machen dann weiter und löschen diese
Datenbank mit dem Kommando dropdb.
Befehlsauflistung 2.6: Löschen einer Datenbank mit dropdb |
$ dropdb -U postgres -W test
Password:
DROP DATABASE
|
Im Moment kann nur der Benutzer "postgres" Befehle ausführen. Das
ist offentlichtlich nicht die Art von Setup wie man es sich für eine
Mehrbenutzer-Umgebung wünscht. Der nächste Abschnitt wird einen Blick auf das
Arbeiten mit Benutzer-Accounts werfen.
Einrichtung von Benutzer-Accounts für Datenbanken
Wie bereits erwähnt ist es in einer Mehrbenutzer-Umgebung nicht gerade
wünschenswert sich jedesmal mit dem Benutzer "postgres" einloggen zu
müssen. In den meisten Fällen wird es mehrere Benutzer und Dienste geben, die
auf den Server zugreifen, und jeder hat unterschiedliche Anforderungen an die
Zugriffsrechte. Um das zu bewältigen, kann der Befehl createuser
benutzt werden. Dieses Kommando ist eine Alternative zum Starten mehrer
SQL-Abfragen und ist vom Standpunkt des Administrators aus eine ganzes Stück
flexibler. Wir fahren damit fort, zwei Benutzer anzulegen. Ein 'superuser', der
andere Benutzer hinzufügen und die Datenbank administrieren kann, und einen
Standard-Benutzer.
Befehlsauflistung 2.7: Erstellen des Superusers |
$ createuser -a -d -P -E -U postgres -W chris
Enter password for new user:
Enter it again:
Password:
CREATE USER
|
Nun haben wir den Superuser erzeugt. Die Kommandozeilen-Option -a gibt
an, dass der Benutzer andere Benutzer hinzufügen kann. -d bedeutet, dass
dieser Benutzer Datenbanken erstellen kann. -P erlaubt Ihnen das Passwort
des Benutzers einzugeben und -E verschlüsselt es aus Gründen der
Sicherheit. Wir testen jetzt die Berechtigungen des neuen Benutzers, indem wir
den Standard-Benutzer erstellen:
Befehlsauflistung 2.8: Erstellen des Standard-Benutzers |
$ createuser -A -D -P -E -U chris -W testuser
Enter password for new user:
Enter it again:
Password:
CREATE USER
|
Erfolg! Unser neuer Benutzer wurde mit dem kürzlich erzeugten Superuser
erstellt. Die Optionen -A und -D bewirken das Gegenteil von
-a und -d und verwehren dem Benutzer die Erstellung anderer
Benutzer und Datenbanken. Da nun Benutzer vorhanden sind, mit denen gearbeitet
werden kann, wird das nächste Kapitel zeigen wie die neue Datenbank benutzt
werden kann.
3.
PostgreSQL Benutzen
Einstellung von Berechtigungen
In unserer neuen Datenbank-Umgebung haben wir nun einen Benutzer, der
Datenbanken und andere Benutzer anlegen kann, und den Hauptbenutzer 'postgres',
der alles tun kann. Der Benutzer, der vorhin erstellt wurde, kann sich im Moment
nur in den Server einloggen, und mehr nicht. In der Regel müssen Benutzer in der
Lage sein Daten einzugeben und auszulesen und machmal auch jede Menge anderer
Aufgaben erledigen zu können. Damit der neue Benutzer also irgendetwas tun kann,
müssen wir eine Datenbank entsprechend einrichten. Das kann man ganz einfach
durch die Übergabe des Parameters -O an createdb erreichen. Wir
beginnen damit, mit unserem Superuser eine neue Datenbank, MyDB, zu
erstellen, die dem kürzlich erstellen 'testuser' gehören soll:
Befehlsauflistung 3.1: Erstellung der MyDB Datenbank |
$ createdb -O testuser -U chris -W MyDB
Password:
CREATE DATABASE
|
In Ordnung, jetzt haben wir eine neue Datenbank "MyDB" und ein "testuser"
kann darauf zugreifen. Um dies zu überprüfen, loggen wir uns als Benutzer
"testuser" in die neue Datenbank "MyDB" ein. Dazu verwenden wird das Programm
psql. Dieses Programm wird dazu benutzt sich mit einer
PostgreSQL-Datenbank von der Kommandozeile aus zu verbinden. Verbinden Sie sich
nun zu der neuen Datenbank wie folgt:
Befehlsauflistung 3.2: Einloggen in die MyDB Datenbank als Benutzer testuser |
$ psql -U testuser -W MyDB
Password:
Welcome to psql 8.0.4, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
MyDB=>
|
So, der Benutzer ist jetzt in die Datenbank eingeloggt und kann ein paar
Befehle starten. Um ein Gefühl für die Benutzung von PostgreSQL zu bekommen,
wird der nächste Abschnitt einen Blick auf einige grundlegende Kommandos werfen,
um in psql zu navigieren.
Grundlegende PostgreSQL Befehle und das Erstellen einer Tabelle
Für jemanden, der MySQL gewohnt ist, ist dies hier quasi Pflichtlektüre.
PostgreSQL ist hier etwas sonderbar, wenn es um das Ausführen von Befehlen
geht. Für den Anfang folgt hier eine Liste einiger Befehle, die später noch
diskutiert werden:
| Befehl |
Verwendung |
MySQL Äquivalent |
| \c[onnect] [DBNAME|- [USER]] |
Verbindet zu einer anderen Datenbank |
USE DATABASE |
| \q |
Beendet psql
|
quit |
| \i FILE |
Befehle aus der Datei FILE ausführen |
source FILE |
| \o [FILE] |
Sende das Resultat einer Abfrage nach FILE
|
INTO OUTFILE, gibt alles aus (nicht nur SELECTS) |
| \d [NAME] |
Beschreibt eine Datenbank oder Tabelle (sowie andere Dinge) |
DESC(RIBE) |
| \db [PATTERN] |
Zeigt verfügbare Tabellen an, auf die das Muster PATTERN
zutrifft (oder alle wenn kein Muster angegeben wird)
|
SHOW TABLES |
Mit der Ausnahme von \c[onnect] werden alle Kommandos in diesem
Abschnitt benutzt. Im Augenblick ist die Datenbank noch leer. Wir müssen also
noch ein paar Daten einfügen. Der erste Schritt um Daten einzugeben ist,
sie in eine Tabelle zu schreiben. Im Augenblick haben wir noch keine Tabellen in
der Datenbank, also müssen wir eine erzeugen. Das geschieht mit dem Befehl
CREATE TABLE. Wir erstellen eine Tabelle mit Artikeln. Sie enthält eine
Artikelnummer, eine Beschreibung und den Preis:
Befehlsauflistung 3.3: Erstellung einer Artikel-Tabelle |
MyDB=> CREATE TABLE products (
MyDB(> product_id SERIAL,
MyDB(> description TEXT,
MyDB(> price DECIMAL
MyDB(> );
NOTICE: CREATE TABLE will create implicit sequence "products_product_id_seq"
for serial column "products.product_id"
CREATE TABLE
|
Sie können die Ausgabe "NOTICE" ignorieren, sie ist harmlos. Wenn man die
letzte Zeile der Ausgabe betrachtet, scheint CREATE TABLE erfolgreich
verlaufen zu sein. Aber lassen Sie uns trotzdem mit dem Kommando
\düberprüfen, ob die Tabelle wirklich korrekt angelegt wurde:
Befehlsauflistung 3.4: Betrachten der neu erstellen Tabelle |
MyDB=> \d products
Table "public.products"
Column | Type | Modifiers
-------------+---------+------------------------------------------------------------------
product_id | integer | not null default nextval('public.products_product_id_seq'::text)
description | text |
price | numeric |
|
Die Tabelle wurde tatsächlich erfolgreich erzeugt. Da nun eine Tabelle erstellt
wurde, muss sie mit Daten gefüllt werden. Im nächsten Abschnitt werden wir
betrachten, wie man eine Datenbank mit Daten füllt.
Eingabe von Daten in die Datenbank
Dieser Abschnitt wird zwei Methoden, eine neu erstellte Tabelle mit Daten zu
füllen, betrachten. Lassen Sie uns zunächst das grundlegendste Kommando
INSERT betrachten:
Befehlsauflistung 3.5: Syntax von INSERT |
INSERT INTO [Tabellenname] (spalte1,spalte2,spalte3) VALUES(wert1,wert2,wert3)
|
Tabellenname enthält den Namen der Tabelle in die Daten eingefügt
werden sollen. Der Ausdruck (spalte1,spalte2,spalte3) gibt spezifische Spalten
an, in die Werte eingegeben werden sollen. VALUES(wert1,wert2,wert3) ist die
Auflistung der Daten. Die Werte werden in der gleichen Reichenfolge wie die
Spalten eingefügt (spalte1 erhält wert1, spalte2 erhält wert2, spalte3 erhält
wert3). Die Anzahl muss jeweils identisch sein. Lassen Sie uns fortfahren
und einen Artikel in die Datenbank einfügen:
Wichtig:
Nachdem ich lange Zeit mit Datenbanken gearbeitet habe, empfehle ich
selbst, INSERT-Ausdrücke exakt wie oben anzugeben. Entwickler machen oft
den Fehler, INSERT INTO ohne Angabe von Spalten zu benutzen. Das ist
unproduktiv, weil es einen Fehler verursacht wenn neue Spalten zur Datenbank
hinzugefügt werden und die Anzahl der Spalten und Werte nicht mehr dieselbe ist.
Sie sollten immer die Spalten angeben, es sei denn, Sie sind zu 300%
sicher, dass Sie niemals eine Spalte hinzufügen werden.
|
Befehlsauflistung 3.6: Einfügen von Daten in die Tabelle |
MyDB=> INSERT INTO products (description,price) VALUES('A test product', 12.00);
INSERT 17273 1
|
Die letzte Zeile muss näher erläutert werden. Die Rückgabe eines
Insert-Kommandos ist eine OID (Object Identifier) und die Anzahl der
hinzugefügten Zeilen. OIDs gehen etwas über den Rahmen dieses Leitfadens hinaus.
Die Adresse PostgreSQL
manual hat einige gute Informationen dazu. Nun, für den Fall, dass Sie
20.000 Produkte haben, könnten dieser Insert-Befehl etwas mühselig werden.
Aber noch ist nicht alles verloren: Das Kommando COPY kann dazu benutzt
werden, um Daten aus einer Datei oder von stdin in eine Tabelle einzufügen.
Lassen Sie uns in diesem Beispiel anehmen, Sie haben eine CSV-Datei (comma
separated values) mit Artikelnummer, Beschreibung und Preis. Diese Datei sieht
wie folgt aus:
Befehlsauflistung 3.7: products.csv |
2,meat,6.79
3,soup,0.69
4,soda,1.79
|
Jetzt werden wir das Kommando COPY benutzen, um unsere Daten einzufügen:
Wichtig:
Der Befehl COPY FROM STDIN wird benutzt, weil nur der Benutzer 'postgres'
Daten aus einer Datei einfügen kann (aus offensichtlichen Sicherheitsgründen).
|
Befehlsauflistung 3.8: Verwendung von COPY um die Tabelle "products" zu füllen |
MyDB=> COPY products FROM STDIN WITH DELIMITER AS ',';
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> 2,meat,6.79
>> 3,soup,0.69
>> 4,soda,1.79
>> \.
|
Leider gibt dieser Befehl nicht die gleichen Status-Informationen zurück wie das
Kommando INSERT INTO. Woher wissen wir, dass die Daten eingefügt wurden?
Im nächsten Abschnitt werden wir uns Abfragen ansehen, mit denen wir unsere
Daten überprüfen können.
Verwendung von PostgreSQL Abfragen
Dieser Abschnitt wird die Benutzung des Kommandos SELECT betrachten, um
Daten in unseren Tabellen anzusehen. Das grundlegende Format von SELECT
sieht folgendermaßen aus:
Befehlsauflistung 3.9: SELECT syntax |
SELECT (spalte1,spalte2|*) FROM (tabelle) [WHERE (konditionen)]
|
Es gibt zwei Arten Spalten auszuwählen. Die erste ist die Verwendung von
* um alle Spalten anzugeben, und die zweite ist die Angabe einer Liste
der Spalten, die Sie sehen wollen. Die zweite Methode ist praktisch, wenn Sie
eine spezifische Spalte aus einer großen Liste finden wollen. Lassen Sie uns mit
der Benutzung von * beginnen, um alle Spalten anzugeben:
Befehlsauflistung 3.10: Betrachten der Tabelle "products" |
MyDB=> SELECT * FROM products;
product_id | description | price
------------+----------------+-------
1 | A test product | 12.00
2 | meat | 6.79
3 | soup | 0.69
4 | soda | 1.79
(4 rows)
|
Wie Sie sehen, sind alle Daten die wir oben einfügt haben tatsächlich in der
Tabelle. Nun lassen Sie uns annehmen, wir wollten nur die Beschreibung und den
Preis sehen und legten keinen Wert auf die Artikelnummer. In dem Falle würden
wir die spaltenspezifische Variante von SELECT verwenden:
Befehlsauflistung 3.11: Betrachten betimmter Spalten aus der Tabelle "products" |
MyDB=> SELECT description,price FROM products;
description | price
----------------+-------
A test product | 12.00
meat | 6.79
soup | 0.69
soda | 1.79
(4 rows)
|
Nun wird nur das Produkt und der Preis angezeigt, so dass wir uns nur auf die
wichtigen Daten konzentrieren können. Nehmen wir an, wir wollten jetzt nur die
Artikel sehen, die teurer als 2 Dollar sind. Hier ist eine praktische
WHERE-Klausel, dazu:
Befehlsauflistung 3.12: Betrachten bestimmter Zeilen aus der Tabelle "products" |
MyDB=> SELECT description,price FROM products WHERE price > 2.00;
description | price
----------------+-------
A test product | 12.00
meat | 6.79
(2 rows)
|
Nun wird eine Liste der Produkte über 2.00 Dollar angezeigt, was die Daten noch
stärker konzentriert. Diese Art der Abfrage von Informationen ist sehr mächtig
und hilft, überaus nützliche Berichte zu erstellen.
Fazit
Dies schließt den PostgreSQL-Leitfaden ab. Ein großes Dankeschön geht an
Masatomo Nakano, den früheren PostgreSQL-Maintainer von Gentoo, für seine Hilfe
durch die Beantwortung meiner Fragen. Verbesserungsvorschläge zu diesem
Leitfaden können an Chris White gesendet werden. Für
weiterführende Informationen beachten Sie bitte die PostgreSQL Website.
Die Inhalte dieses Dokuments sind, sofern nicht explizit
anders genannt, unter der Creative Commons -
Namensnennung / Weitergabe Lizenz lizenziert. Die Gentoo Name and Logo
Usage Guidelines treffen zu.
|
|
Seite aktualisiert 25. April 2007 |
Die Originalversion dieses Dokuments wurde zuletzt am 13. Juni 2012 aktualisiert |
Zusammenfassung:
Dieser Leitfaden soll die grundlegende Einrichtung von PostgreSQL erläutern.
Das Setup, das hier beschrieben wird, sollte für einfache Web-Applikationen
sowie für jedes andere Programm, das PostgreSQL-Unterstützung anbietet,
ausreichen.
|
Chris White
Autor
Xavier Neys
Bearbeiter
Rolf Herzog
Übersetzer
Tobias Heinlein
Korrektor
|
|
Donate to support our development efforts.
|
|
|