# SQL-Tabelle sinnvoll gestalten?!



## dobermant (25. April 2007)

Guten tag,,
ich möchte eine Bilderdatenbank anlegen. Dazu nutze ich MySQL/PHP.

Die Bilder sollen nach Land, Region, Ort sortiert werden können.

Ich habe 4 Tabellen: gc_items , gc_land, gc_region, gc_ort

Felder in gc_item -> id , name, pfad, id_land, id_region, id_ort

Felder in gc_land, gc_region, gc_ort -> id, name

Wenn ich jetzt z.b. 1 Bild anzeigen will, dazu den Landesname, Regionname und Ortsname, muss ich insgesamt 4 SQL abfragen machen. Erstmal das Bild abfragen + die ID´s fuer Land, Region und Ort und dann nochmal mit Hilfe der ID´s die namen von Land, Region und Ort abfragen...

Nun meine Frage ist das sinvoll? sollte ich nicht lieber in der Bildtabelle gc_items gleich die namen der Orte mitspeichern und nicht nur die ID´s? 

Ich kann mich erinnern, dass mir einer erklärte, es ist besser nur mit ID´s zu arbeiten und die Namen dann nochmal extra abfragen, weil dann nicht soviele TXT Felder in der Datenbank sind und somit alles schneller geht. Was ist nun ricvhtig?

PS: Die datenbank soll bis zu 50000 Fotos ausgelegt sein.

Ich habe auch noch sowas wie JOIN in erinnerung, hat jemand vielleicht mal ne Beispielabfrage für mein Problem?

Danke fuer Eure Tipps

Dober


----------



## DeeJTwoK (25. April 2007)

Richtig, das mit dem JOIN ist ein guter Ansatz. Damit erspart man sich die 4 Abfrage, weil man nur eine brauch:
Mit

```
SELECT * FROM gc_items JOIN gc_land ON gc_items.id_land = gc_land.id
```
erhälst du also direkt das Land dabei.
Wenn du dann noch mit mehreren JOINs die anderen Tabellen anhängst, kannst du mit einem Befehl alle Daten auf einmal bekommen.

MfG 
DJ

PS: Wenn du in beiden Tabellen (gc_items und gc_land) die Spalte mit der Landes ID gleich nennst (z.B. land_id) geht es auch so:

```
SELECT * FROM gc_items JOIN gc_land USING(land_id)
```
Ist etwas einfach zu lesen.Vor allem, wenn die anderen JOINs auch noch dabei kommen...


----------



## dobermant (25. April 2007)

oha...das klingt gut...besten dank...eine frage noch...
aus alten zeiten erinnere ich mich auch, dass mal einer sagte keine
"SELECT * FROM" zu machen...aus Sicherheitsgründen oder wegen der Performance...ist da was dran?

Danke


----------



## dobermant (25. April 2007)

oha...das klingt gut...besten dank...eine frage noch...
aus alten zeiten erinnere ich mich auch, dass mal einer sagte keine
"SELECT * FROM" zu machen...aus Sicherheitsgründen oder wegen der Performance...ist da was dran?

hab jetzt meine SQL Abfrage fertig, zumindestens funktioniert sie. Kann man da noch was optiemieren, oder ist das OK so?


```
$sql = "SELECT gc_items.name, gc_items.pfad, gc_items.hits, gc_items.land, gc_items.ort, gc_items.region, gc_land.id, gc_land.land AS land_str, gc_region.id, gc_region.region AS region_str , gc_ort.id, gc_ort.ort AS ort_str 
FROM gc_items, gc_land, gc_region, gc_ort WHERE gc_items.land = gc_land.id AND  gc_items.region = gc_region.id ";

$result1 = mysql_query($sql, $conn);
while($pic_beliebt = mysql_fetch_array($result1, MYSQL_ASSOC)) { $i++;
	$pname[$i]=$pic_beliebt[name];
	$ppfad[$i]=$pic_beliebt[pfad];
	$pland[$i]=$pic_beliebt[land_str];
	$pregion[$i]=$pic_beliebt[region_str];	
	$pregion[$i]=$pic_beliebt[region_str];	
	$phits[$i]=$pic_beliebt[hits];

}
```

Danke


----------



## fa_herrmann (25. April 2007)

dobermant hat gesagt.:


> hab jetzt meine SQL Abfrage fertig, zumindestens funktioniert sie. Kann man da noch was optiemieren,


´

Ja, INNER / LEFT / RIGHT mit ON verwenden, statt dieses Hilfskonstruktes mit einer WHERE-Einschränkung. Where-Klauseln werden bei den meisten DB-Systemen erst am Schluss berücksichtigt, das heisst: erst wird (intern) ein riesiges recordset gebildet, danach wird eingeschränkt.

Bei sehr großen Tabellen sind zudem Joins über sehr viele Tabellen performancefressend. Da sollte man sich unter Umständen noch einmal über die Normalisierung des DB-Modells Gedanken machen. Aber 500000 DS sind nicht wirklich viel, wenn der Datenbankserver den Namen halbwegs verdient


----------



## dobermant (25. April 2007)

fa_herrmann hat gesagt.:


> ´
> Ja, INNER / LEFT / RIGHT mit ON verwenden, statt dieses Hilfskonstruktes mit einer WHERE-Einschränkung. Where-Klauseln werden bei den meisten DB-Systemen erst am Schluss berücksichtigt, das heisst: erst wird (intern) ein riesiges recordset gebildet, danach wird eingeschränkt.



Verstehe...sollte ja im normalen MySQL Handbuch beschriebn sein..Und dabei war ich so stolz auf meine SQL Abfrage(vorher waren es 4 Abfragen für dasselbe Ziel) und jetzt muss ich erfahren dass es nur ein "Hilfskonstrukt" ist.. ;-)



fa_herrmann hat gesagt.:


> ´
> Bei sehr großen Tabellen sind zudem Joins über sehr viele Tabellen performancefressend. Da sollte man sich unter Umständen noch einmal über die Normalisierung des DB-Modells Gedanken machen. Aber 500000 DS sind nicht wirklich viel, wenn der Datenbankserver den Namen halbwegs verdient



Das wird sich zeigen...Besten Dank für die kompotente Antwort
Dober


----------

