Re: Ku

From: Peter Wullinger <some-mail-drop(at)gmx(dot)net>
To: Dirk Olbertz <olbertz(dot)dirk(at)gmx(dot)de>
Cc: pgsql-de-allgemein(at)postgresql(dot)org
Subject: Re: Ku
Date: 2004-09-25 16:31:18
Message-ID: 20040925163117.GA750@peter.home.wul
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-de-allgemein

In epistula a Dirk Olbertz, die horaque Sat, Sep 25, 2004 at 10:28:40AM -0400:
> Hi Janko,
>
> vielen Dank schonmal für diese Zusammenstellung. Ich werde mich mal da
> reinhängen.
>
> Ich werde die libpq nutzen und bin im Moment vor allem an den beiden
> Konzepten
> - Transaktion und
> - Cursor
> interessiert. Was beides grob ist, weiß ich, ich bin mir nur unsicher,
> wie ich mit beiden Dingen umzugehen habe. Dazu mal ein paar konkrete
> Frage, vielleicht könnt ihr mir ja eure Standpunkte erklären.
>

Hört sich für mich nach "Grundlagenvorlesung relationale Datenbanken"
an, die Dinge, die du ansprichst sind eigentlich nicht
PostgreSQL-spezifisch, sondern gehören zum SQL Standard. MySQL ist
allerdings nicht unbedingt dafür bekannt, sich an den Standard zu
halten.

Beispiele: http://sql-info.de/mysql/gotchas.html

(An alle, die mit PostgreSQL arbeiten: Vor dem Lesen obiger
Seite den Kaffee weg und den Stuhl auf sicheren Untergrund
stellen)

<professorenhut>

Transaktionen dienen erst mal zu zwei Sachen

- Garantie von Atomizität
- Isolation

Das Allerweltsbeispiel zu beidem ist wohl
(sinngemäß übernommen aus [1]):

CREATE TABLE konto (
kontonr VARCHAR(30)
CHECK (kontonr LIKE '[0-9]{2,3} [0-9]{3,3} [0-9]{3,3}')
PRIMARY KEY,
kontostand MONEY
);

Transaktion A Transaktion B

wert := SELECT kontostand
FROM konto
WHERE kontonr = '123-123-123';

wert := SELECT kontostand
FROM konto
WHERE kontonr = '123-123-123';

wert := wert + 10;

wert := wert - 100;

UPDATE konto
SET kontostand = wert
WHERE kontonr = '123-123-123';

UPDATE konto
SET kontostand = wert
WHERE kontonr = '123-123-123';

Das Beispiel ist zwar schlecht, weil man die entsprechende
Operation auch gleich ins UPDATE-Statement einbauen könnte,
aber es illustriert das Grundprinzip.

Auf jeden Fall steht nach Ausführung der obigen Befehle der falsche
Wert in der Datenbank. Packt man die beiden Befehle oben in eine
Transaktion ist das natürlich nicht der Fall.

Bei vielen Datenbanken kommt dann noch dazu, daß gehäufte
Aktualisierungen innerhalb einer Transaktion oftmals schneller
ausgeführt werden, wie ohne.

Bei einzelnen SELECTs bringt eine Transaktion natürlich herzlich
wenig, das ist wohl auch der Grund, warum für viele Web-Anwendungen
MySQL bevorzugt wird. Dort braucht man eigentlich die Fähigkeiten
einer "richtigen" Datenbank nicht, sondern es zählt vor allem die
Tatsache, daß die Abfragen schnell ablaufen.

Transaktionen sind auch für Programmierer interessant, den
die erleichtern die Implementierung von unabhängigen Updates:
Führt man mehrere Aktualisierungen hintereinander durch, kann
es sein, daß eine davon fehlschlägt. Ohne Transaktionsunterstützung
muß man sich dann selbst darum kümmern, die vorhergehenden Operationen
rückgängig zu machen (unter Berücksichtigung, daß andere Prozesse
auch auf dieselben Daten zugreifen können). Mit Transkationen reicht
ein einfaces "ROLLBACK;".

Zu Cursors:

Das muß man sich so vorstellen, als würde man eine Abfrage als
"Datenstrom" erstellen. Innerhalb dieses Datenstroms kann
man dann einen Zeiger (CURSOR) plazieren.

Ich weiß nicht, auf welche Funktionalität du bei MySQL da anspielst,
aber wenn ich richtig rate, meinst du den "LIMIT"-Clause für den
SELECT-Befehl (gibt es auch in PostgreSQL).

Der Vorteil von CURSORs ist ziemlich klar: Sie sind schneller.

Für einen Befehl wie

SELECT *
FROM tabelleA JOIN tabelleB
ON FeldA = FeldB
WHERE FeldC = WertA
LIMIT 1 OFFSET 1999

muß die Datenbank den Befehl erneut interpretieren, einen
Ausführungsplan erstellen, die Datensätze holen und innerhalb
der Datensatzmenge bis zum 1999sten Wert vorspringen um den 2000sten
Wert zu holen. Das ist natürlich viel Aufwand, wenn man es 2000 mal
machen muß, um einzeln die Datensätze von 1 bis 2000 zu holen.

Mit CURSORs kann man einfach jedesmal

FETCH NEXT FROM <cursor_name>;

schreiben. Das erspart der Datenbank das Aufstellen des Query-Planes
(Die Abfrage ist ja schon bekannt) und einen Großteil der anderen
Operationen. Die Datenbank muß nur noch wissen, wie sie in einem
bekannten Datensatz"strom" eine Zeile vorwärts kommt.

</professorenhut>

Ich hoffe, das hilft dir ein wenig beim Verständis, ansonsten
empfehle ich das Skript der Datenbankvorlesung einer beliebigen
Fachhochschule/Universität.

Gruß,
Peter

[1] Abraham Silberschatz, Henry F. Korth, S. Sudarshan,
Database System Concepts, 4th Edition, McGraw-Hill,
ISBN 0-07-112268-0

--
Miteinander zu sprechen ist besser als gegeneinander zu schweigen.
-- Ignazio Silone

In response to

Responses

Browse pgsql-de-allgemein by date

  From Date Subject
Next Message Dirk Olbertz 2004-09-25 23:25:08 Re: Kurze (technische) Übersicht über PostgreSQL gesucht
Previous Message Dirk Olbertz 2004-09-25 14:28:40 Re: Kurze (technische) Übersicht über PostgreSQL gesucht