MySQL Abfrage über mehrere Tabellen vereinfachen

semmelkuh

VerwirrterBenutzer
ID: 188086
L
28 April 2006
558
30
Hallo :)

Ich habe eine zentrale Tabelle "profil" und zahlreiche weitere Tabellen, z.B. "vor_nachname" und "spitzname".
In der "profil"-Tabelle befindet sich eine individuelle Kennung und eine ID für jedes Profil.
Die anderen Tabellen haben auch eine Spalte Kennung, allerdings ist diese mit der ID gefüllt aus der "profil"-Tabelle.
Bei der Abfrage allerdings wird nach der Kennung gesucht (nicht nach der ID). Nun soll passend zu dieser Kennung die ID aus der "profil"-Tabelle gesucht werden und mit dieser die restlichen Daten aus den zahlreichen anderen Tabellen.

Das ganze natürlich möglichst in einer Abfrage. Ich habe mir folgendes zusammengebastelt:

Code:
SELECT 
vor_nachname.data AS "Name", spitzname.data AS "Spitzname" 
FROM 
vor_nachname, spitzname 
WHERE 
vor_nachname.kennung  = (SELECT id FROM profil WHERE kennung = "N7fzK0")  AND spitzname.kennung = (SELECT id FROM profil WHERE kennung = "N7fzK0") 
ORDER BY 
vor_nachname.timestamp DESC, spitzname.timestamp DESC;

Das Problem dabei ist, dass in der WHERE Bedingung für jede Tabelle einzeln ein SELECT durchgeführt wird. Kann man das irgendwie vereinfachen?
Ich habe es so probiert, aber das funktioniert nicht:
Code:
WHERE vor_nachname.kennung  AND spitzname.kennung = (SELECT id FROM profil WHERE kennung = "N7fzK0")
Code:
WHERE vor_nachname.kennung, spitzname.kennung = (SELECT id FROM profil WHERE kennung = "N7fzK0")

Ich hab so das Gefühl, man kann das besser mit einem JOIN lösen, aber irgendwie hab ich das nicht hingekriegt...

Desweiteren müssen die Daten in so vielen Tabellen liegen, da sich die einzelnen Angaben zu verschiedenen Zeiten ändern können und die alten Daten erhalten bleiben müssen. Um nicht mächtig viel Platz zu verschwenden werden nur die Daten neu gespeichert, die sich auch verändert haben. Wenn wir schon dabei sind: Gibt es eventuell hier eine bessere Lösung? :p

Vielen Dank
semmelkuh
 
Ja, stimmt wohl... sieht sehr merkwürdig aus :D

Also es ist so:
Die Daten von einem Profil (also z.B. der Name) ändern sich ständig, allerdings alle Daten einzeln, also z.B. der Name heute, der Spitzname morgen.
Ich möchte aber alle Daten gespeichert lassen. Deshalb erstelle ich bei einer Namensänderung in der Nametabelle einen neuen Eintrag mit der ID des Profils und dem Namen und einem Timestamp über den es dann möglich ist den aktuellen Namen zu ermitteln.
Ich könnte natürlich auch nur eine Tabelle mit all diesen Daten haben und bei einem neuen Eintrag die nicht veränderten Daten weglassen, was dann bedeutet, dass sie aus einem älteren Datensatz gefischt werden müssen.
Das würde aber die SQL Abfrage noch komplizierte machen. Beispielsweise: Hey, das ist der aktuelle Datensatz, aber da steht nur der Name drin... dann nehme ich den nächstälteren, aber da steht nur das Alter drin... im nächstälteren nur der Spitzname. Somit müsste ich eine Menge Datensätze durchgucken, bis ich alle Daten gesammelt habe.
Und wenn ich bei jeder Änderung auch die unveränderten Daten neu speicher, nimmt das zu viel Platz weg.

Ich hoffe das war verständlich...

semmelkuh
 
k, ich hoffe ich habe es richtig verstanden.
warum machst du es nicht so:

du hast deine Tabelle mitglieder:
user_id | name | spitzname | ...

damit du nun auch sehen kannst die die person früher hieß, machst du ein changelog:
changelog_id | user_id | attribut | value

da würde eben drinne stehen, dass der User früher xyz (value) hieß (attribut: name).

Wenn du nun einen Datensatz hast, der sich auf diesen User bezieht (gästebuch, forum usw) referenzierst du die user_id in mitglieder, denn die daten dort sind immer aktuell.
 
Ahh okay, das ist in der Tat eine gute Möglichkeit.

Allerdings ist eine Veränderung der Daten sehr wahrscheinlich, sodass bei deiner Methode vermutlich schon nach kurzer Zeit jedes Attribut eines Mitglieds geändert ist und um dann an die kompletten aktuellen Daten zu gelangen muss wieder ein komplexer SQL Query erstellt werden, der eben alle Changelogeinträge für den User raussucht und die verschiedenen Attribute auch noch richtig zuordnet usw.
Oder hab ich es falsch verstanden? :p

semmelkuh
 
Ich glaub ice meint, dass du den aktuellen Stand des Attributs nocheinmal zusätzlich in mitglieder speichern sollst, dann kannst du das sehr einfach abfragen.;)
 
Also ich würde das SELECT auf dem ersten Blick so konzipieren:
PHP:
SELECT 
  vor_nachname.data AS "Name",
  spitzname.data AS "Spitzname" 
FROM 
  vor_nachname
JOIN spitzname
  ON vor_nachname.kennung = spitzname.kennung
JOIN profil
  ON spitzname.kennung = profil.id
WHERE
  profil.kennung = "N7fzK0" 
ORDER BY 
  vor_nachname.timestamp DESC, spitzname.timestamp DESC;
 
Ich glaub ice meint, dass du den aktuellen Stand des Attributs nocheinmal zusätzlich in mitglieder speichern sollst, dann kannst du das sehr einfach abfragen.;)

richtig die aktuellen Attribute sind in der Mitglieder Tabelle, da man diese ja immer braucht.
Wenn man doch mal die alten Infos braucht - warum auch immer - kann man in mitglieder_changelog sich anzeigen lassen wie die Information früher aussah.
 
richtig die aktuellen Attribute sind in der Mitglieder Tabelle, da man diese ja immer braucht.
Wenn man doch mal die alten Infos braucht - warum auch immer - kann man in mitglieder_changelog sich anzeigen lassen wie die Information früher aussah.

Okay, super :)
Ich habe das jetzt so gemacht, wie du es gesagt hast und bis jetzt funktioniert das gut :D
Danke! :)