[gelöst] [SQL] Datenbankstruktur und die Sache mit den IDs

Cyperfriend

Der ohne Avatar
Registriert
14 Juli 2013
Beiträge
1.123
Ich habe zwei Tabellen

Kunden:
Code:
Expand Collapse Copy
ID | Kunde | Strasse | Ort | Telefon | E-Mail

Standorte:
Code:
Expand Collapse Copy
ID | K_ID | Strasse | Ort

Die beiden Tabellen werden zur Standortübersicht mit folgendem Befehl gejoint:
PHP:
Expand Collapse Copy
select db_standorte.*, db_kunden.id from db_standorte 
								join db_kunden on db_standorte.k_id = db_kunden.id 
								where k_id='".$_GET['id']."'";
Soweit funktioniert das auch. Das Problem ist jetzt, dass ich mit $row['id'] immer die 1 ausgegeben bekomme. Logisch, wenn man den Befehl mal im PHPMyAdmin ausführt. Das befördert dann folgende Tabellenstruktur zutage:
Code:
Expand Collapse Copy
ID | K_ID | Strasse | Ort | ID
Die letzte ID ist immer eine 1, die erste ID die tatsächliche Zeilen-ID ist die Erste.

Problem soweit erkannt. Komme ich zur Frage:
Ich dachte immer, dass die ID auch ID heißen sollte (nicht muss). So wie mir das aber scheint funktioniert das nicht. Gilt es als saubere Lösung, wenn man beispielsweise als erste ID "K_ID" für die Kundentabelle und "S_ID" für die Standort-Tabelle nimmt? Die jetzige K_ID müsste ich halt in "KS_ID" (KundenStandort) umbenennen.

Ist das wirklich die Lösung oder sollte man es anders angehen?
 
Zuletzt bearbeitet:
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

In vielen Büchern die ich gelesen habe, wurden die ID Spalten immer einfach als ID bezeichnet. Egal in welcher Tabelle. Anschließend wurde beim Joinen ein Alias für dieses Feld vergeben, damit es nicht im Ergebnis durch ein gejointes ID-Feld überschrieben wird.
Meiner Meinung nach ist das großteils persönliche Präferenz, wie man die Spaltennamen bezeichnet, solange sie aussagekräftig sind. Die ID Spalte bezeichnet normalerweise die ID der jeweiligen Tabelle und nicht die einer anderen Tabelle (außer sie heißt z.B. kunden_id, aber das ist dann eh logisch).

Code:
Expand Collapse Copy
select db_standorte.*, db_kunden.id as kunden_id from db_standorte 
                                join db_kunden on db_standorte.k_id = db_kunden.id 
                                where db_standorte.k_id='".$_GET['id']."'";

Bitte beachte, dass du die SQL Abfrage so nicht durchführst, ohne den $_GET Parameter zu escapen und Datenbanksicher zu machen.
 
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Ich muss leider zugeben, von PHP so gut wie gar nichts zu wissen.

Normalerweise gilt es als "die sauberste Lösung", die ID-Spalten einer Tabelle auch entsprechend mit dem Tabellennamen zu versehen.

Beispiel:
Tabelle: "Kunde"
Attribute/Spalten/Felder/...: Kunde_ID, Name_1, Name_2, usw...

Und Namen der Tabellen stehen niemals im Plural!

Hoffe ich konnte dir trotzdem etwas behilflich sein ;)
 
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Gilt es als saubere Lösung, wenn man beispielsweise als erste ID "K_ID" für die Kundentabelle und "S_ID" für die Standort-Tabelle nimmt?

Es gibt hier grundsätzlich drei Argumentationen.
1: In jeder Tabelle ein gleichnamiges Feld ID zu haben führt zu Leichtsinnsfehlern, in der Kundentabelle sollte das Feld KundenID heißen.
2: In einer Tabelle Kunden ein Feld KundenID zu haben ist "Smurfnaming", das Feld wird ja durch Kunden.ID angesprochen, Kunden.KundenID ist sinnfrei.
3: keine Ahnung, gibt sicher noch ein, zwei weitere.

Welche der beiden Lager du dich anschließt ist im Grunde egal, ich bevorzuge das zweite, aber ich sehe den Sinn des ersten.
Auf keinen Fall solltest du aber mal das eine und mal das andere machen, eine durchgängiges Namensschema ist extrem sinnvoll.

PS: du brauchst nicht Standorte.K_ID und Kunden.ID ausgeben, die Spalten sind durch den JOIN doch sowieso identisch ;-)
 
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Ich kann ebenfalls beide Argumentationen nachvollziehen, bevorzuge aber Ersteres, d.h. eine ID-Spalte mit eigenem Namen pro Tabelle. Der Hauptgrund dafür ist in der Tat, dass man dadurch in Queries mit JOINs mehrdeutige Spaltennamen (mit unterschiedlichen Inhalten) und die damit verbundenen, u.U. nicht sofort offensichtlichen Probleme vermeiden kann. Ausserdem muss man dadurch in vielen Fällen Spalten nicht mit vollem Namen (`tabellenname`.`spaltenname`) ansprechen, kann sich die Vergabe von Alias-Namen ersparen und kann in JOINs ggf. die USING(...)-Syntax nutzen.

Ausserdem muss man sich entscheiden, wie man Fremdschlüssel benennen möchte. Neben der offensichtlichen Variante - `kundeid` oder `kunde_id` für eine Tabelle namens `kunde` - empfehlen einige Quellen die Vergabe eines Präfixes (`fk_kunde` oder `fk_kunde_id`) und/oder eine Kombination der beiden Tabellennamen (`fk_standort_kunde_id` o.ä.). Ich persönlich bevorzuge die Form ohne Präfix und ohne die beiden Tabellennamen und benenne die Spalten in der Regel so, wie sie auch in der referenzierten Tabelle heissen. Dass es sich um Fremdschlüssel handelt, geht aus dem Namen und ggf. gesetzten Constraints ohnehin hervor.
 
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Ich bevorzuge ebenfalls einen eigenen Namen pro Tabelle, musste aber mal bei einem Projekt mitarbeiten, bei dem nur der Anfangsbuchstabe als Präfix für "id" verwendet wurde, also z.B. "sid", "aid" oder "cid". Leider begann ein Großteil der Tabellen mit S, und da dort teilweise 3 oder 4 Tabellen gejoint werden müssen, nervte es schon sehr, ständig den Tabellennamen mit angeben zu müssen.
 
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Um auf das ursprüngliche Problem zurück zu kommen:

Lass den Unsinn mit *. Macht es zwar schön kurz zu schreiben, verschlechter aber schon mal die Lesbarkeit. In deinem Fall wäre die zweit-einfachste Lösung bei doppelten Spaltennamen einfach mit einem Alias zu arbeiten, sprich ein AS hinter die Spalte die umbenannt werden soll und alles ist in Ordnung.
Warum zweit-einfachste Lösung? Weil du in deinem Beispiel nicht mal nen Join brauchst, die einzige Spalte aus der gejointen Tabelle die du ausließt, ist ja bereits in der ursprünglichen Tabelle enthalten...
 
  • Thread Starter Thread Starter
  • #8
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Stimmt. Das Join hätte ich mir schenken können.
Was das * angeht. Bei kleinen Tabellen sicher eine Option, aber wenn man mal Tabellen mit 20 und mehr Spalten hat, dann stelle ich es in Frage, ob es sinnvoll ist alle Spalten einzeln anzugeben, nur um sich die ID-Spalte zu ersparen, zumal es sicherlich Situationen geben kann, wo man sie dann doch auch noch braucht.

An alle Anderen: Danke für eure Antworten. Ich bin jetzt klüger.
 
Re: [SQL] Datenbankstruktur und die Sache mit den IDs

Ich habe zwei Tabellen

Kunden:
Code:
Expand Collapse Copy
ID | Kunde | Strasse | Ort | Telefon | E-Mail

Standorte:
Code:
Expand Collapse Copy
ID | K_ID | Strasse | Ort

Die beiden Tabellen werden zur Standortübersicht mit folgendem Befehl gejoint:
PHP:
Expand Collapse Copy
select db_standorte.*, db_kunden.id from db_standorte 
								join db_kunden on db_standorte.k_id = db_kunden.id 
								where k_id='".$_GET['id']."'";
Soweit funktioniert das auch. Das Problem ist jetzt, dass ich mit $row['id'] immer die 1 ausgegeben bekomme. Logisch, wenn man den Befehl mal im PHPMyAdmin ausführt. Das befördert dann folgende Tabellenstruktur zutage:
Code:
Expand Collapse Copy
ID | K_ID | Strasse | Ort | ID
Die letzte ID ist immer eine 1, die erste ID die tatsächliche Zeilen-ID ist die Erste.


PHP:
Expand Collapse Copy
select db_standorte.*, db_kunden.id from db_standorte 
								join db_kunden on db_standorte.k_id = db_kunden.id 
								where k_id='".$_GET['id']."'";

Schreibe doch mal aus, was du haben möchtest:

PHP:
Expand Collapse Copy
SELECT db_standorte.*, db_kunden.id 
FROM db_standorte 
	JOIN db_kunden
	ON db_standorte.k_id = db_kunden.id
WHERE k_id='".$_GET['id']."'";

PHP:
Expand Collapse Copy
db_standorte.ID, db_standorte.K_ID, db_standorte.Strasse, db_standorte.Ort, db_kunden.id
Die KundenID bekommst du hier sogar 2 mal UND du hast sie schon, weil danach gesucht wird. Bist du dir sicher, dass du das brauchst?
PHP:
Expand Collapse Copy
db_standorte.ID, db_standorte.Strasse, db_standorte.Ort
würde schon ausreichen, die Kundenid ist $_GET['id']

Außerdem solltest du Eindeutigkeit wahren.
Wenn du also die Kunden und die Standort-ID gleich benannt hast ("id"), aber beides willst, dann nennst du sie für das Ergebnis um:
PHP:
Expand Collapse Copy
db_standorte.ID as standortid, db_kunden.id as kundenid, db_standorte.Strasse, db_standorte.Ort

Und nein, id's müssen nicht immer id heißen, du kannst sie gerne auch karl, otto, fred oder merkel nennen. Das ist der Datenbank herzlich egal.
Ids sollten eindeutig sein, also benenne sie am besten so, dass sie möglichst etwas wiederspiegeln, das eindeutig ist: kundennummer und standortid
 
Zurück
Oben