Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
(Web-) Design und webbasierte Sprachen Tipps & Tricks, Designabgleich, HTML & Javascript, Flash, ASP, PHP, Perl/CGI...

Abfrage für eine Forenübersicht

Diskussion: Abfrage für eine Forenübersicht im Forum (Web-) Design und webbasierte Sprachen, in der Kategorie Web, Network & Multimedia Palace; Anzeige Hallo ich bin grad dabei für mein Projekt ein kleines forum zu bauen, allerdings habe ich ein paar probleme ...

Antwort
Alt 21.04.09, 16:45   #1 (permalink)
Member of Honour
 
Benutzerbild von easteregg
 
Registriert seit: 14.09.07
easteregg Leistung: Pentium Ieasteregg Leistung: Pentium I
easteregg eine Nachricht über ICQ schicken
Likes: 62
Standard Abfrage für eine Forenübersicht

Anzeige

Hallo
ich bin grad dabei für mein Projekt ein kleines forum zu bauen, allerdings habe ich ein paar probleme mit den SQL abfragen.

folgendes db konstrukt:

tabelle categorien: id,name,benutzerlevel
tabelle forum: id,cat_id,name
tabelle topics: id,forum_id,name,user_id,erstellzeit
tabelle posts: id,topic_id,user_id,erstellzeit

die eben über die jeweiligen ids miteinander verknüpft werden sollen.

wenn ich jetzt die forenübersicht erstellen möchte soll das in etwa so aussehen:

Code:
---------------------------------------------------------
| categoriename                                         |
---------------------------------------------------------
|  | name des forums     | beitragszähler | letzter post|
---------------------------------------------------------
|  | name des forums     | beitragszähler | letzter post|
---------------------------------------------------------
bis dahin kein problem, die abfrage dazu sieht folgendermaßen aus:

Code:
SELECT
  categorie.name as cat,forum.name,forum.id,topics.name,posts.user_id
FROM
  board_cat as categorie
INNER JOIN
  board_forum as forum
ON
  categorie.id = forum.cat_id
LEFT OUTER JOIN
  board_topics as topics
ON
  topics.forum_id = forum.id
LEFT OUTER JOIN
  board_posts as posts
ON
  topics.id = posts.topic_id
wie kann ich jetzt aber auch absichern, dass ich als user_id und topic.name bei dem left outer join auch immer den letzten beitrag bekomme, und nicht irgend einen?
__________________
» Flattr mich! - Wenn dir mein Beitrag geholfen hat! «
<| 2 AMD Opterons 2384@ 8x3,2ghz | Tyan S2915 | 10GB | 2x 8800GT | 8400GS | Dell 3008WFP + 2x2007FP |>
easteregg ist offline   Mit Zitat antworten
Alt 21.04.09, 17:21   #2 (permalink)
gelöscht
Guest
 
Likes:
Standard

Mit einer WHERE - Klausel, damit kannst du dir ja immer den letzten Datensatz dann aus der Tabelle rausholen.

BTW: mit LIMIT kannste es auch abfragen.

Grüße

Zephyros
  Mit Zitat antworten
   
HaBOT
 
- Anzeige -

Werbung ist gerade online    
Alt 21.04.09, 17:26   #3 (permalink)
Member of Honour
Themenstarter
 
Benutzerbild von easteregg
 
Registriert seit: 14.09.07
easteregg Leistung: Pentium Ieasteregg Leistung: Pentium I
easteregg eine Nachricht über ICQ schicken
Likes: 62
Standard

ich glaub ich seh den wald vor lauter bäumen nichtmehr.
wie meinst du das genau, gib mal bitte ein beispiel.
__________________
» Flattr mich! - Wenn dir mein Beitrag geholfen hat! «
<| 2 AMD Opterons 2384@ 8x3,2ghz | Tyan S2915 | 10GB | 2x 8800GT | 8400GS | Dell 3008WFP + 2x2007FP |>
easteregg ist offline   Mit Zitat antworten
Alt 21.04.09, 17:33   #4 (permalink)
gelöscht
Guest
 
Likes:
Standard

Ich weiß, SQL kann nervig sein ;) Erst recht wenn die Abfrage so lang werden.

Mit der WHERE - Klausel kannst du ja bekanntlich deine Abfrage auf einen bestimmten String/Integer beschränken.

Bsp.:

Code:
SELECT user_id FROM user WHERE user_id = 5 oder SELECT user_id FROM user WHERE user_id LIKE "5"
In diesem Falle, wird nur die user_id ausgegeben die die 5 besitzt, im 1. Fall ist es ein INTEGER - Wert und im 2. Fall (mit LIKE) ist es eine Zeichenkette.

Mit der LIMIT - Klausel kannst du deine Abfrage dazu bewegen, ab einem bestimmten Datensatz anzufangen und dir nur eine bestimmte Anzahl an Datensätze dann anzeigen lassen.

Bsp.:

Code:
SELECT * FROM users LIMIT 0,5
Das heißt nun, es werden nur die Datensätze der Tabelle User ab Datensatz 0 bis zum Datensatz 4 angezeigt, da ja SQL auch bei 0 anfängt zu zählen.

Müsstest mal gucken, wie genau du das am besten bei dir einbauen kannst.

Ach mal wieder ein Edit:
Mit der MIN(ID) oder MAX(ID) kannst du vielleicht einfacher deine Abfrage gestalten, in dem du einfach die MAX - ID des letzten Posts ermittelst.


Grüße

Zephyros
  Mit Zitat antworten
Alt 21.04.09, 17:54   #5 (permalink)
Member of Honour
Themenstarter
 
Benutzerbild von easteregg
 
Registriert seit: 14.09.07
easteregg Leistung: Pentium Ieasteregg Leistung: Pentium I
easteregg eine Nachricht über ICQ schicken
Likes: 62
Standard

wie das limit und where arbeitet ist mir soweit klar, ich haba uch grad festgestellt, dass ich nen allgemeineren denkfehler hab.

oben in dem query bekomm ich ja bei mehreren beiträgen die selbe categorie mehrmals zurück, daher müsste ich ja über die forums.id gruppieren.

also nochmal von vorne, mittlerweile habe ich zwei themen erstellen zum besseren erklären:

Code:
mysql> SELECT t.name,p.time FROM board_posts AS p INNER JOIN board_topics AS t ON p.topic_id = t.id ORDER BY time DESC;
+-----------+------------+
| name      | time       |
+-----------+------------+
| test2     | 1240328328 |
| testthema | 1240323773 |
+-----------+------------+
2 rows in set (0.00 sec)
ich möchte auf meiner übersichtssseite ja in dem großen query immer nur das letzte thema haben, daher musst ich da ja noch ein group by anhängen!

Code:
SELECT
  categorie.name as cat,forum.name,forum.id,topics.name,posts.user_id,posts.time
FROM
  board_cat as categorie
INNER JOIN
  board_forum as forum
ON
  categorie.id = forum.cat_id
LEFT OUTER JOIN
  board_topics as topics
ON
  topics.forum_id = forum.id
LEFT OUTER JOIN
  board_posts as posts
ON
  topics.id = posts.topic_id
GROUP BY
  forum.id;
das problem jetzt, wenn ich das so ausführe bekomme ich nicht das test2 als letzten beitrag zurück, sondern testthema, was ja aber so nicht stimmt.

Code:
mysql> SELECT
    ->   categorie.name as cat,forum.name,forum.id,topics.name,posts.user_id,posts.time
    -> FROM
    ->   board_cat as categorie
    -> INNER JOIN
    ->   board_forum as forum
    -> ON
    ->   categorie.id = forum.cat_id
    -> LEFT OUTER JOIN
    ->   board_topics as topics
    -> ON
    ->   topics.forum_id = forum.id
    -> LEFT OUTER JOIN
    ->   board_posts as posts
    -> ON
    ->   topics.id = posts.topic_id
    -> GROUP BY
    ->   forum.id;
+---------+------+----+-----------+---------+------------+
| cat     | name | id | name      | user_id | time       |
+---------+------+----+-----------+---------+------------+
| testcat | News |  1 | testthema |       3 | 1240323773 |
| testcat | test |  2 | NULL      |    NULL |       NULL |
+---------+------+----+-----------+---------+------------+
2 rows in set (0.00 sec)
sprich ich müsste jetzt ja irgendwie vor dem group by forum.id noch irgendwie sortieren, dass ich den jünsten beitrag bekomme?
mit nem order by oder nem where lässt sich das ja aber nicht bewerkstelligen.
die einzige idee die ich hätte wäre einen subquery einzubauen, aber das ist ja nicht sonderlich performant und irgendwie auch nicht sonderlich elegant.

Code:
SELECT
  categorie.name as cat,forum.name,forum.id,topics.name,posts.
  (select time FROM board_posts WHERE board_posts.topic_id = topics.id ORDER BY `time` DESC)
FROM
  board_cat as categorie
INNER JOIN
  board_forum as forum
ON
  categorie.id = forum.cat_id
LEFT OUTER JOIN
  board_topics as topics
ON
  topics.forum_id = forum.id
GROUP BY
  forum.id
__________________
» Flattr mich! - Wenn dir mein Beitrag geholfen hat! «
<| 2 AMD Opterons 2384@ 8x3,2ghz | Tyan S2915 | 10GB | 2x 8800GT | 8400GS | Dell 3008WFP + 2x2007FP |>
easteregg ist offline   Mit Zitat antworten
Alt 22.04.09, 11:44   #6 (permalink)
 
Benutzerbild von metax.
 
Registriert seit: 22.01.07
metax. Leistung: 8086
metax. eine Nachricht über ICQ schicken
Likes: 10
Standard

Bei einem JOIN bildest du immer das Kreuzprodukt der beteiligten Datenmengen, das du noch über diverse Kriterien matchst. Das bietet sich immer an, wenn du große Ergebnismengen fetchen willst (z.B. alle Topics eines Posts) oder wenn die Ursprungsdatenmenge sehr klein ist.
Je größer die zusammenmultiplizierte Zielmenge ist, desto unperformanter wird ein JOIN (geschweige denn 4 JOINs).
Da du in deiner Situation (letzter Beitrag) pro Board nur ein Topic selektieren willst, würde ich diese Abfrage separat in einem Query (oder Alternativ in einem Subquery) abfragen. So viel Unterschied macht das nicht, und in dem großen 4-Fach JOIN kommst du sonst nicht vernünftig ran.
Das geschickte Setzen von Inizes (bzw. Fremdschlüsseln) kann an Performance nochmal was rausholen.
mfg, metax.
__________________
Wenn keiner zuschaut, teile ich heimlich durch Null!
Meine Homepage: Planet Metax | meine Bilder: DeviantArt | Twitter
metax. ist offline   Mit Zitat antworten
Alt 22.04.09, 11:54   #7 (permalink)
Member of Honour
Themenstarter
 
Benutzerbild von easteregg
 
Registriert seit: 14.09.07
easteregg Leistung: Pentium Ieasteregg Leistung: Pentium I
easteregg eine Nachricht über ICQ schicken
Likes: 62
Standard

hast du irgendwo dokumentation zu fremdschlüsseln und wie man die sinvoll anwendet?
ich hab von den ganzen indizegeschichten leider gar keine ahnung, da sql für mich ne trail'n'error lernmaßnahme war ;D
__________________
» Flattr mich! - Wenn dir mein Beitrag geholfen hat! «
<| 2 AMD Opterons 2384@ 8x3,2ghz | Tyan S2915 | 10GB | 2x 8800GT | 8400GS | Dell 3008WFP + 2x2007FP |>
easteregg ist offline   Mit Zitat antworten
Alt 22.04.09, 13:48   #8 (permalink)
CDW
Moderator
 
Benutzerbild von CDW
 
Registriert seit: 20.07.05
CDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: OpteronCDW Leistung: Opteron
Likes: 202
Standard

Such mal in dem Zusammenhang nach relatinalen Datenbanken/Entwürfen:
http://de.wikipedia.org/wiki/Relationale_Datenbank
http://de.wikipedia.org/wiki/Fremdsc...schl.C3.BCssel
__________________
Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf!
Selig, wer nichts zu sagen hat und trotzdem schweigt.
CDW ist offline   Mit Zitat antworten
Alt 22.04.09, 21:05   #9 (permalink)
 
Benutzerbild von metax.
 
Registriert seit: 22.01.07
metax. Leistung: 8086
metax. eine Nachricht über ICQ schicken
Likes: 10
Standard

Nun, ein Index (bzw. Schlüssel) sorgt a priori erstmal dafür, dass über einem Feld eine Art sortiertes Inhaltsverzeichnis (B-Baum oder ähnliches) angelegt wird, so dass du bei einem Direktzugriff auf das Feld nicht alle Datensätze durchsuchen musst, sondern die gesuchten Einträge schnell findest.
Felder, die oft in SELECT-Queries im WHERE- oder HAVING-Teil vorkommen, sind performanter, wenn über ihnen ein Index erstellt wurde.
Ein Primärschlüssel (bzw. in schwächerer Form: Unique) sorgen außerdem noch dafür, dass Werte in einem Feld eindeutig sind. Dadurch kannst du Datensätze immer eindeutig identifieren und die Tabelle hat eine implizite Sortierung. Man sollte in jeder Tabelle einen Primärschlüssel setzen, und sei es nur ein fortlaufendes Nummernfeld (Integer, auto_increment). Ohne Primärschlüssel werden Tabellenzugriffe schnell extrem langsam.
Fremdschlüssel (Foreign Keys) sind Schlüssel, die auf dem Primärschlüssel einer anderen Tabelle referenzieren. Dadurch hast du zusätzlich die Bedingung, dass der Fremdschlüssel nur Werte enthalten darf, die im Primärschlüssel der Referenztabelle vorkommen und du kannst sogar Aktionen definieren, die ausgeführt werden, wenn der Referenzeintrag gelöscht oder modifiziert wird.
z.B.
Tabelle Topic:
----------------
Topic_id, Topic_title, Topic_Icon, ...
Primary Key: Topic_id (auto_increment)


Tabelle Thread
-----------------
Thread_id, Topic_reference, Thread_author, ...
Primary Key: Thread_id
Foreign Key: Topic_reference references Topic (Topic_id)

Ich hoffe, das wird nun klarer.
Fremdschlüssel kannst du in MySQL allerdings nur verwenden, wenn du die neuere DB-Engine "InnoDB" statt "MyISAM" benutzt. Ansonsten nimm für die Fremdschlüssel einfach einen normalen Index.

mfg, metax.
__________________
Wenn keiner zuschaut, teile ich heimlich durch Null!
Meine Homepage: Planet Metax | meine Bilder: DeviantArt | Twitter
metax. ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Web, Network & Multimedia Palace » (Web-) Design und webbasierte Sprachen » Abfrage für eine Forenübersicht
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
SQL Abfrage Prophion Code Kitchen 5 29.01.09 18:24
SQL-Abfrage mauralix Code Kitchen 8 12.02.07 13:29
Abfrage, ob eine Datei (Grafik) existiert valenterry (Web-) Design und webbasierte Sprachen 5 25.01.07 17:09
Eine Website öffnen lassen obwohl eine andere Eingegeben wurde Strahl Internet Allgemein 10 01.08.05 11:49
SQL Abfrage Tomekdomek (Web-) Design und webbasierte Sprachen 4 28.02.02 09:36


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61