Lässt sich diese "Aufgabe" (ich habe kein Namen dafür) direkt/sinnvoll in Postgresql lösen?

Werbung:
Ein Integer mit Autowert ist unter PostgreSQL ein eigener Spaltentyp... (heißt serial)

IDs dienen eigentlich für einen eindeutigen Schlüsselwert, welcher in einer Tabelle nicht öfter als einmal vorkommen kann!

Kleines Szenario:
Code:
1) postgres=# create table ids(id serial primary key, name text);
CREATE TABLE
2) postgres=# insert into ids(name) values ('Hans'), ('Peter');
INSERT 0 2
3) postgres=# select * from ids;
 id | name
----+-------
  1 | Hans
  2 | Peter
(2 Zeilen)
4) postgres=# insert into ids(id, name) values (1, 'Klaudia');
5) FEHLER:  doppelter Schlüsselwert verletzt Unique-Constraint »ids_pkey«
DETAIL:  Schlüssel »(id)=(1)« existiert bereits.
postgres=#

Erklärung:
In Kommentar 1 erstelle ich eine Tabelle mit einem Auto-Wert-Integer (unter postgres serial) sowie einer beliebigen Spalte, bei mir name vom Spaltentyp text
In Kommentar 2 füge ich zwei beliebige Namen in die Tabelle "ids"
In Kommentar 3 frage ich alle Datensätze aus der Tabelle ab
In Kommentar 4 versuche ich eine ID, die bereits existiert noch einmal anzugeben und hinter Nummer 5 kommt die entsprechende Fehlermeldung.

"die gleiche id" kann in einer anderen Tabelle öfters vorkommen, wie hier zB:
Code:
postgres=# create table kombinationen(id integer references ids(id), nachname text);
CREATE TABLE
postgres=#
postgres=# insert into kombinationen(id, nachname) values (1, 'Müller');
FEHLER:  Zeichen mit Byte-Folge 0x81 in Kodierung »WIN1252« hat keine Entsprechung in Kodierung »UTF8«
postgres=#
postgres=# insert into kombinationen(id, nachname) values (1, 'Schillinger');
INSERT 0 1
postgres=#
postgres=# select * from kombinationen;
 id |  nachname
----+-------------
  1 | Schillinger
(1 Zeile)


postgres=# insert into kombinationen(id, nachname) values (1, 'Mueller');
INSERT 0 1
postgres=# select * from kombinationen;
 id |  nachname
----+-------------
  1 | Schillinger
  1 | Mueller

Die Relation (im obigen Fall) ist eine 1:m-Beziehung... (eine id kann beliebig oft in der tabelle kombinationen vorkommen)

Hoffe ich hilft dir ein wenig weiter ;)
 
noch besser ist dies:

Code:
postgres=# create table foo (id int generated always as identity primary key, data text);
CREATE TABLE
postgres=# insert into foo (data) values ('Hans');
INSERT 0 1
postgres=# insert into foo (id,data) values (100,'Lisa');
ERROR:  cannot insert a non-DEFAULT value into column "id"
DETAIL:  Column "id" is an identity column defined as GENERATED ALWAYS.
HINT:  Use OVERRIDING SYSTEM VALUE to override.
postgres=#

Bei SERIAL kannst Du noch immer einen nicht vergebenen Wert eingeben, bei GENERATED ALWAYS geht es nur noch via Brechstange.
 
Hallo zusammen,

ich habe nicht gedacht, das seit meinem letzten Post hier noch was großartig passiert.
Wie man sich Irren kann. :)

Die esten Vorschläge/Ideen "generate_series" etc. haben gereicht, um mein "Brett vor dem Kopf" zu lösen.

Kleines Feedback meinerseits.
Ich darf mit einer älteren Postgresql 9.x Version arbeiten. Dies ist nur eine Replikation einer Produktiv-DB. Darum entfallen alle evtl. neuere Postgresql Möglichkeiten.

Ich musste auf den Weg, mein bisherigen generierten Roh Output nehmen und extern weiterverarbeiten, ausweichen. Dies hat mehrere Gründe.
Erst im weiteren Verlauf habe ich gesehen/festgestellt, das z.b. die Positionsnummerierung Lücken haben "dürfen" und trotzdem Valide sind...
Von-Bis 1-100
Es kann mal vorkommen, das ein Datensatz wie z.b. 1-100, 105-150 existiert. Dies hätte ich vorher als "fehlerhaft" aussortiert.

Jetzt generiere ich nach dem Prinzip "generate_series" die Zahlen, füge alles bis auf doppelte Einträge zusammen und splitte diese in zusammenhängende Gruppen auf, welche ich gesondert Prüfe.

Dann habe ich erfahren, das es bestimmte Ranges gibt z.b. 1-100, in welcher ich nur von 1 bis z.b. 90 prüfen darf. Würde dies nicht berücksichtigt werden, so würde dies in solch einem Fall, immer zu einem Fehler führen. etc..

Und dies alles direkt in einer/mehreren Postgres Abfrage unterzubringen ...
Sicherlich evtl. irgendwie machbar, aber dies liegt, stand heute, ausserhalb meiner Reichweite.


Das beste kommt aber wie immer zum Schluss.
Gerade vor 1 Stunde fertig geworden, da heißt es, wird erst mal auf Eis gelegt.
Der Grund. Keiner hat mit dem generierten Output (fehlerhafte/unvollständige) Menge an Datensätzen und der darauf folgenden Nacharbeit gerechnet...
Da fühlt man sich schon etwas auf den Arm genommen.

Ich danke euch trotzdem für die ganzen Ideen/Vorschläge. Ich konnte daraus auf jedenfall etwas meitnehmen und neues lernen.

Viele Grüße
Chris
 
Datenanalyse ist halt so eine Sache, entweder sie liefert hübsche KPIs aber einen echten Nutzen gibt es nicht oder man findet die Leichen und es dauert alles viel Länger als erwartet.
 
Werbung:
Ich danke euch trotzdem für die ganzen Ideen/Vorschläge. Ich konnte daraus auf jedenfall etwas meitnehmen und neues lernen.
Auch wenn Du es nicht mehr lesen wirst, vielleicht tut es jemand anders, der bei dem Thread ein deja vue hat.

Zu den Leichen:
Je mehr man findet, desto weniger hat man die Möglichkeiten einer DB genutzt. Constraints, Foreign Keys, Trigger,...
Ich will nicht sagen, selbst Schuld, aber es ist ein guter Aufhänger, sich mit den Möglichkeiten auseinander zu setzen. Und wenn man dann dazu nimmt, dass die "amtierende" DB nur V9 ist- uralt für pg Verhältnisse-, und auch das niemand kümmert, dann ergibt sich schon irgendwie ein Bild.

Zum Problem:
Auch wenn das aktuelle Bild nicht vielversprechend aussieht, kann man mit SQL sehr gut explorativ arbeiten und abfragen, womit man es überhaupt zu tun hat. Man kann sehr gut aggregieren und sich ein Bild machen.
Man kann auch sehr unproblematisch sein Datenmodell extra dafür erweitern und die überraschend entdeckten "Gesetzmäßigkeiten", also erlaubte Ranges bspw. und nicht erlaubte- explizit modellieren, in separaten Tabellen. Schon wird es einfacher, schnelle und aussagekräftige Abfragen zu bauen.

Wenn man sowieso mit Postgres arbeitet, sollte es auch kein Problem sein (finanziell oder technisch), "extra dafür" einen PC / VM mit einer fetten Platte aufzusetzen und die Daten in eine Spielwelt zu importieren, wo man mit der aktuellen PG Version 100% Funktionalität verfügbar hat.
 
Zurück
Oben