Postgres Einsatz von Serials und Indices
Biesterfeld
- datenbank
Hej,
ich habe eine grundsätzliche Verständnisfrage zu Datenbanken. Zb. habe ich folgende Datendefinition:
CREATE TABLE tabX (
x_no SERIAL UNIQUE PRIMARY KEY,
entry VARCHAR(4) UNIQUE NOT NULL
);
CREATE TABLE tabY(
y_no SERIAL UNIQUE PRIMARY KEY,
entry VARCHAR(4) UNIQUE NOT NULL
);
CREATE TABLE x2y(
x_no INTEGER REFERENCES tabX ( x_no ),
y_no INTEGER REFERENCES tabY ( x_no )
);
Nun überlege ich mir einen Index für die beiden Primärschlüssel einzuführen, um Abfragen über die Linkingtabelle performanter zu gestalten.
Da ich aber die Serials (x_no und y_no) eigentlich sowieso nicht brauche (außer zum linken) und die entries unique not null sind, ist meine Frage, ob ich gleich die entries als Primärschlüssel deklarieren kann und den Index auf diesen Aufbauen.
Welche Methode ist performanter?
Besten Dank im voraus
Biesterfeld
Am "performantesten" ist immer der Index, der zum Suchen benutzt wird und bei der Suche schon fest steht, daß man nur ein paar Prozent der gesamten Datenmenge als Ergebnis bekommt.
Ich weiß nicht, wie Varchar-Indizes aufgebaut sind, es kann sein, daß die, da Strings, etwas mehr Platz brauchen als Number-Indizes.
Gruß
Hans
Hej Hans und Rouven,
Dank euch schonmal.
Am "performantesten" ist immer der Index, der zum Suchen benutzt wird und bei der Suche schon fest steht, daß man nur ein paar Prozent der gesamten Datenmenge als Ergebnis bekommt.
Ich glaube ich habe mein Problem nicht ganz deutlich geschildert.
Also meine DB enthält etwa 7 Daten- und 6 Linking-Tabellen. Und es kommt also öfter vor, dass ich eine Abfrage über alle Tabellen machen muss.
_Nur_ für die Linking-Tabellen, habe ich die SERIAL-Spalte in den einzelnen Daten-Tabellen eingefügt. Und daher ergibt sich die Frage ob es performanter ist, über die SERIALS zu linken, oder diese zu indizieren, oder direkt die entries die unique und not null sind zu indizieren und über diese zu linken.
Beste Grüße
Biesterfeld
Hi,
also erfahrungsgemäß ist die Sache mit der Primärschlüsselwahl immer so eine Sache. Vorab: IIRC sollte jeder Primärschlüssel automatisch wie ein Index funktionieren, damit wäre eine weitere Indizierung dieser Spalte(n) unnötig. Zusätzliche Indizes, wie bereits von Hans erwähnt, lohnen sich eigentlich nur für Spalten nach denen gesucht, respektive über die gejoint wird.
Nun zur Wahl des Primärschlüssels. Wenn du sowieso eine UNIQUE-Angabe auf deiner Spalte drauf hast und ein Datensatz sonst keine weiteren Attribute hat, dann lohnt sich im Prinzip kein zusätzlicher Primärschlüssel. Interessant wird die Sache bei größeren Tabellen, d.h. wenn ein Datensatz aus mehreren Spalten besteht. Auch hier finden sich ja immer Möglichkeiten die eigentlichen Daten als Primärschlüssel zu verwenden, und wenn es alle Attribute zusammen sind. Dennoch ist dort dann die Empfehlung einen künstlichen Schlüssel einzufügen, weil dies die Änderung am Datensatz erleichert. Beispiel wäre z.B. eine Kundenkartei mit Aufträgen und Kundendaten. Doppelte Nachnamen mal außen vor, könnte man ja auf die Idee kommen Vorname+Nachname als Primärschlüssel für die Kunden zu nehmen, dementsprechend beim Auftrag als Fremdschlüssel Namen+Vornamen festzuhalten. Heiratet jetzt einer der Kunden und ändert damit seinen Nachnamen, so verursacht dis eine Menge Änderungsaufwand. Man sollte sich also eine Struktur suchen, bei der ein Primärschlüssel im Nachhinein _nicht_ mehr verändert wird, eben die künstliche Spalte KundenID oder sonstwas.
MfG
Rouven
yo,
ich habe ein weing gebraucht, um zu verstehen, was genau du meinst. ich hoffe doch, dass jetzt der groschen bei mir gefallen ist.
ich kenne mich in postgres nicht aus, aber ein primary key besteht grundsätzlich aus zwei constrainst, nämlich UNIQUE und NOT NULL. wenn nun eine spalte(n) schon einen constraint primary key zugewiesen ist, dann braucht man das NOT NULL und das UNIQUE nicht noch einmal expliziet hizufügen.
Da ich aber die Serials (x_no und y_no) eigentlich sowieso nicht brauche (außer zum linken) und die entries unique not null sind, ist meine Frage, ob ich gleich die entries als Primärschlüssel deklarieren kann und den Index auf diesen Aufbauen.
wie Rouven schon sagte, einen künstlichen schlüssel als pk zu nehmen, macht durchaus sinn. aber das ist ansichtssache und muss jeder dba selber entscheiden.
den namen der spalte serial würde ich ändern, da es meiner meinung nach bessere namen gibt, wie zum beispiel id. dann wird es deutlicher, dass es sich um einen künstlichen schlüssel handelt. nur zum verlinken brauchst du diese spalte nicht, da du eine weitere spalte hast, die ebenfalls NOT NULL und UNIQUE ist. aber dann kommt wieder die frage nach dem künstlichen schlüssel oder nicht. wenn er nun schon mal da ist, würde ich ihn auch bestehen lassen.
wie bereits erwähnt, legt das dbms für jeden primary key auch einen index an. auch diesen schritt kannst du dir sparen. tuning an sich ist ein schwieriges thema. man kann solche aussagen wie die frage nach einem index nicht so allgemein beantworten, dass das tuning von vielen dingen abhängt. das vorhandensein eines index kann die abfrage sogar langsamer machen.
mit anderen worten, ob deine abfragen schneller werden hängt von dem speziellen fall ab.
Ilja