Primary Keys nur immer Integer?

hi zusammen

Ich hab eine Tabelle mit Kundenbetreuern:

Betreuername | Kunden_ID | Land_ID | Produktgruppen_ID

Jeder Betreuer kann mehrere Kunden betreuen, deshalb wird es pro Betreuer mehrere Einträge geben. Der Primärschlüssel wäre somit der Betreuername.

Ich bin mir gewohnt, dass der Primärschlüssel immer vom Typ Integer ist und unabhängig von allen anderen Werten.

Tabelle Betreuer: ID | Betreuername

Tabelle Betreute Kunden: Betreuer_ID | Kunden_ID | Land_ID | Produktgruppen_ID

Welche Variante ist empfehlenswerter?

Liebe Grüsse

Janosh

Hallo,

Betreuernamen könen doppelt vorkommen. Deshalb sind sie als Key ungeeignet.

Trotzdem muss man sich nicht zwingend einen künstlichen Schlüssel ausdenken. Die Kriterien für die Schlüsselauswahl sind Stabilität (ändere niemals einen Schlüssel) und Eindeutigkeit (Kunststück, sonst wäre es ja keiner) evtl noch Einfachheit (Es ist angenehm mit Schlüsseln aus nur einem Attribut zu arbeiten)

Gruß

Peter

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Also ich glaube Oracle lässt solche Sachen zu. Ungeachtet dessen, würd ich in diese Tabelle BetreuerID eben vom Typ integer einführen. Ich denke mal grundsätzlich ist das schon effizienter, auch für spätere SQL-Joins.

Betreuernamen könen doppelt vorkommen. Deshalb sind sie als
Key ungeeignet.

Im konkreten Fall wären diese Namen eindeutig (weil sie nicht an einen Personennamen gebunden sind).

Trotzdem muss man sich nicht zwingend einen künstlichen
Schlüssel ausdenken. Die Kriterien für die Schlüsselauswahl
sind Stabilität (ändere niemals einen Schlüssel) und
Eindeutigkeit (Kunststück, sonst wäre es ja keiner) evtl noch
Einfachheit (Es ist angenehm mit Schlüsseln aus nur einem
Attribut zu arbeiten)

Ich finde es einfach ungewohnt, einen Schlüssel aus Text zu haben, anstatt aus einer Zahl. Und ob der Name niemals ändern wird, ist eine gute Frage. Man weiss ja eben nie, was die Zukunft bringt…

Danke für die Antwort

Gruss
Janosh

Also ich glaube Oracle lässt solche Sachen zu. Ungeachtet
dessen, würd ich in diese Tabelle BetreuerID eben vom Typ
integer einführen. Ich denke mal grundsätzlich ist das schon
effizienter, auch für spätere SQL-Joins.

Danke für deine Antwort.

Im Normalfall wäre aber die Abfrage, welche Kunden werden von Betreuer X bearbeitet? In diesem Fall wäre nur 1 Tabelle betroffen, während bei der Einführung des Integer-Schlüssels 2 Tabellen betroffen wären.

Ist das dennoch effizienter bei grossen Tabellen?

Gruss,
Janosh

Hallo Janosh!

Im Normalfall wäre aber die Abfrage, welche Kunden werden von
Betreuer X bearbeitet? In diesem Fall wäre nur 1 Tabelle
betroffen, während bei der Einführung des Integer-Schlüssels 2
Tabellen betroffen wären.

Ist das dennoch effizienter bei grossen Tabellen?

Die richtige Antwort darauf: Das kann man so nicht sagen :wink:. Vielleicht etwas hilfreicher und ausführlicher geht’s mit Extrembeispielen:
Bsp A mit nur einer Tabelle:
Irgendwann kommst du zum Schluss, dass du zum Betreuer nicht nur den Namen, sondern auch noch den Lebenslauf abspeichern willst (so ein netter VARCHAR2(2000) oder so). Dieses speicherst du jetzt pro Kundenbetreuungssatz ab (also wenn der Betreuer XYZ 100 Kunden betreut, dann eben 200 K) und liest es dann auch gleich jedesmal mit, wenn du die Tabelle liest. Des weiteren stellst du ein wenig später auch noch fest, dass du einen Betreuer hast, der aber im Moment mal keine Kunden betreut (neu, karenziert, wasauchimmer). Den spiecherst du jetzt entweder gar nicht, woanders oder mit einem Dummy-Kunden. Erscheint mir alles nicht besonders hübsch, aber wenn ich das da oben alles nicht habe und ein Betreuername 3 Zeichen hat, dann bin ich dafür mit Sicherheit schneller, als wenn ich das ganze über zwei Tabellen mache).
Bsp B mit zwei Tabellen:
Es gibt nur zwei Betreuer, einer Betreut Kunde X, der andere betreut alle anderen Kunden (so 10.000.000 an der Zahl, schliesslich sind wir ja ein dotcom, da geht das schon). Du speicherst jetzt anstelle des 100-stelligen (sprich 100 Byte) langen Betreuercodes 10.000.001 mal nur jeweils 22 Byte für die Zahl. Macht 724 MB Ersparnis - bei keinerlei Performance Verlust (die Betreuungsdaten des ersten Betreuers zu lesen ist zusätzlich zum Index-Zugriff auf die Kunden-Betreuer-Daten noch ein Full-Table-Scan auf die Betreuer (den Index hier sparen wir uns lieber, bevor unsere DB noch auf die Ide kommt, den auch tatsächlich zu verwenden); die Betreuungsdaten des zweiten Betreuers zu lesen ist ein Full-Table-Scan auf beide Tabellen, wobei der FTS der Betreuer-Tabelle wohl kaum ins Geweicht fällt).

Fazit: Welche Lösung performanter ist, hängt nicht nur von der Struktur, sondern auch von der Verteilung und Natur der Daten ab. Allerdings würde ich generell das Performance-Problem - das es ja möglicherweise gar nicht gibt - erst dann behandeln, wenn die Datenstruktur einmal RICHTIG ist, und das hat wiederum viel weniger mit Normalformen und schlauen Büchern als mit Hausverstand, TESTS und vor allem den Anforderungen zu tun (eine DB, aus der primär gelesen wird [aka OLAP] stellt ganz andere Anforderungen, als eine, in der gleichermassen gelesen, Sätze eingefügt, geändert und gelöscht werden [aka OLTP]). Konkret sollte es einer modernen relationalen DB ziemlich wurscht sein, ob sie gerade aus einer, zwei oder fünf Tabellen liest, schliesslich wurden relationale Datenbanken genau dafür konzipiert (und schön langsam fängt das sogar auch noch an zu funktionierenn).

Ich hoffe das war nicht allzu verwirrend,
lg
Martin

vielen dank für die ausführliche antwort und die nachvollziehbaren beispiele.

ich hab mich jetzt mal für die normalisierte variante entschieden.

gruss,

janosh

1 Like

Hallo janosh!

vielen dank für die ausführliche antwort und die
nachvollziehbaren beispiele.

Freut mich, wenn ich dir helfen konnte. Und weil das letzte „danke“, das ich bekommen habe schon gar so lang her ist - und es mich wirklich begeistert, wenn ich wenigstens sicher sein kann, dass der Fragesteller meine Antwort zumindest gelesen hat - bekommst du dafür auch gleich noch ein Sternchen.

Gruß
Martin