[linux-l] SQL / PostgreSQL
Olaf Radicke
olaf_rad at gmx.de
Do Sep 21 22:41:28 CEST 2006
Am Donnerstag, 21. September 2006 15:22 schrieb Pascal Volk:
> * Am Mi, 20 Sep 2006 schrub Olaf Radicke:
> > Lösung gefunden:
> > [...]
> > Wenn ich also meine ID haben will, muss ich den weg "zu Fuss" machen.
> > Erster Schritt:
> > SELECT nextval('einschraenkung_merkmal_id_seq');
> > Dazu muss ich natürlich den Sequenz Namen kennen. Der setzt sich zusammen
> > aus Tabellenname, Tiefstrich, Spaltenname, Tiefstrich, "seq".
>
> Nein und nein.
> Was macht denn nextval? Etwa den nächsten (erst setzen) und dann
> zurückgeben? Ja - genau.
> Rufe dazu mehr SELECT nextval('einschraenkung_merkmal_id_seq'); auf, und du
> wirst sehen, dass jedesmal ein anderen Wert rauskommt. Aber Du wirst
> niemals einen Datensatz haben, der die ID hat, die Dir mit nextval
> angezeigt wurde.
>
> Wo steht bitte geschrieben, dass die Sequenz 'relation_filed_seq' heißen
> muss? Sie kann so heißen, ja.
>
> > Jetzt habe ich meine eindeutige ID, die mir niemand mehr wegnehmen kann.
> > Egal welche Operationen auf der Tabelle in der zwischenzeit ausgeführt
> > werden, wann immer ein Anderer direkt nextval() oder indirekt SERIAL
> > aufruft, er wird immer eine andere ID bekommen, als ich. Auch wenn ich
> > mir 10 Jahre Zeit lasse zwischen dem nextval()-Aufruf und dem
> > INSERT-Befehl. Meine ID wird für mich frei sein.
>
> Ha, das hast Du Dir schön gedacht.
> Du nimmst Dir, mit der oben beschrieben Variante, die ID selbst weg, aka
> Trick 17 m. S. Kein Datensatz wird diese ID jemals bekommen.
[...]
Vielleicht kann ich mich ja auch nicht richtig ausdrücke. Deshalb noch mal die
PostgreSQL-FAQ:
4.11.2) Wie bekomme ich den Wert einer SERIAL-Sequenz?
------------------------------------------------------
Eine Möglichkeit wäre, mit der nextval()-Funktion den nächsten SERIAL-Wert von
dem Sequenzobjekt vor der Auszuführung einer INSERT-Anweisung anzufordern und
ihn dann explizit in die INSERT-Anweisung einzubinden. Anhand der
Beispieltabelle in 4.11.1 könnte dieser Vorgang in einer Pseudosprache so
aussehen:
new_id = output of execute("SELECT nextval('person_id_seq')");
execute("INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal')");
Danach stünde der neue Wert in der Variablen new_id für die Verwendung in
weiteren Abfragen zur Verfügung, zum Beispiel als Fremdschlüssel zur
Tabelle 'person'). Bitte beachten Sie, dass der Name des automatisch
erstellten SEQUENCE-Objektes folgenden Name hat: <table>_<serialcolumn>_seq
wobei 'table' und 'serialcolumn' die Namen der jeweils betreffenden Tabelle /
Spalte darstellen.
Als weitere Möglichkeit können Sie nach einer INSERT-Anweisung den automatisch
eingefügten SERIAL-Wert mit der currval()-Funktion zurückgeben lassen:
execute("INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal')");
new_id = output of execute("SELECT currval('person_id_seq')");
4.11.3) Führt currval() zu einer Race-Condition mit anderen Nutzern?
--------------------------------------------------------------------
Nein. currval() liefert einen Wert zurück, der von Ihrer Datenbank-Session
bestimmt wird, und der anderen Sessionen nicht zur Verfügung steht.
[...]
4.12) Was ist ein OID? Was ist ein CTID?
----------------------------------------
Jede Zeile, die in PostgreSQL erzeugt wird, bekommt eine eindeutige OID,
sofern die Tabelle nicht mit der Option WITHOUT OIDS angelegt wurde. OIDs
sind automatisch zugewiesene 4-Byte-Integer, die innerhalb der gesamten
Datenbank einmalig sind. Allerdings laufen sie bei einem Wert von ungefähr 4
Milliarden über. PostgreSQL verwendet OIDs, um seine interne Systemtabellen
zu verbinden.
Um einmalige Idenfikatoren in Datentabellen zu erstellen, wird allerdings
empfohlen, statt OIDs Werte zu verwenden, die vonSERIAL- Sequenzen erzeugt
werden. SERIAL-Sequenzen sind innerhalb einer Tabelle einmalig und daher
weniger anfällig für Überläufe. Außerdem können 8-Byte-Sequenzwerte mit
SERIAL8 erzeugt werden.
CTIDs werden benutzt, um bestimmte physikalische Zeilen durch Block und Offset
Werte zu identifizieren. CTIDs verändern sich, sobald Zeilen verändert oder
zurückgeladen werden. Sie werden in Indexeinträgen benutzt um auf die
physikalischen Zeilen zu zeigen.
(http://sql-info.de/de/postgresql/FAQ_german.html#4.11.2)
Gruß
Olaf
Mehr Informationen über die Mailingliste linux-l