CronJob-Service
bei SELFPHP mit ...
|
+ minütlichen Aufrufen
+ eigenem Crontab Eintrag
+ unbegrenzten CronJobs
+ Statistiken
+ Beispielaufrufen
+ Control-Bereich
Führen Sie mit den CronJobs von
SELFPHP zeitgesteuert Programme
auf Ihrem Server
aus. Weitere Infos
|
:: Anbieterverzeichnis ::
Globale Branchen
Informieren Sie sich über ausgewählte Unternehmen im Anbieterverzeichnis von SELFPHP
:: Newsletter ::
Abonnieren Sie hier den kostenlosen
SELFPHP Newsletter!
|
MySQLi/PDO/(MySQL) Anfänger, Fortgeschrittene oder Experten können hier Fragen und Probleme rund um MySQLi/PDO/(MySQL) diskutieren |
01.02.2007, 11:13:00
|
Anfänger
|
|
Registriert seit: Jul 2006
Beiträge: 69
|
|
optimieren von DB-Zugriffen
Hallo zusammen,
ich bin mir nicht ganz sicher, ob es sich um ein reines MySQL-Thema handelt, aber größten Teils schon:
Ich skizziere mal kurz, wie eine Seite von mir, eine Art Bilder-Gallerie mit der ich nicht so recht zufrieden bin, funktioniert:
In der Datenbank gibt es zwei Tabellen.
Tabelle A
hier gibt es einen Eintrag für jede zu erstellende html seite.
Spalten: SEITEN_ID (nicht fortlaufend); Überschrift; Text; Timestamp
Tabelle B
hier sind die Links zu den einzelnen Bildern abgelegt.
Spalten: BILD_ID; SEITEN_ID (referenz zu A); BILD_URL; Bildtext
Für den Aufbau der Seite benötige ich folgende Informaitonen:
1. Erster und letzter Eintrag in Tabelle A - für die Seitennavigation und um Fehleingaben beim "www.url.de?Seite=X" aufzufangen.
Derzeit gelöst durch zwei Abfragen auf die SEITEN_ID einmal aufsteigend und einmal abfallen sortiert limit 0, 1.
2. Abfrage aller Daten der aufgerufenen Seiten_ID für den Seitenaufbau
Derzeit gelöst mit select * from a where Seiten_ID=X
3. Ausgehend von der aktuellen Seite soll für die Navigation ein Link für vorwärts und rückwärts gebaut werden. Dazu müßte ich den Vorgänger und den Nachfolger von X in der Tabelle A feststellen.
Derzeit ohne echte Lösung. Ich ziehe von x 1 ab und addiere 1 dazu um die Links zu bauen, dass funktioniert aber nur, solange SEITEN_ID fortlaufend ist, ist es aber schon nicht mehr.
Und eigentlich möchte ich statt dem Text "vor" und "zurück" die entsprechenden Überschirften aus der Tabelle A anzeigen.
Vieleicht kann man das Ganze wesentlich einfacher halten, ich kann es leider nicht.
Ich vermute mal, wenn ich die Tabella A in ein Array lesen würde könnte ich mit einem Zugriff auf die DB auskommen, allerdings weiß ich nicht, wie ich dann wieder an die einzelnen daten komme.
Ich hoffe auf eure kompetenten Anregungen und Vorschläge. Danke.
|
01.02.2007, 11:47:10
|
Member
|
|
Registriert seit: Jun 2006
Ort: Bayern
Alter: 56
Beiträge: 930
|
|
AW: optimieren von DB-Zugriffen
Um dir da mehr sagen zu können, wäre es nicht verkehrt dein Script ein zu stellen.
Zu 3. x - 1 und x + 1 ist schon richtig. Bloß solltest du dies nicht auf die ID beziehen sondern auf LIMIT.
__________________
Grüße Andes
|
01.02.2007, 12:03:05
|
Anfänger
|
|
Registriert seit: Jul 2006
Beiträge: 69
|
|
AW: optimieren von DB-Zugriffen
Hier isser, etwas gekürzt und anonymisiert...
PHP-Code:
<?php
$sql = "SELECT SEITE_ID FROM A ORDER BY SEITE_ID DESC LIMIT 0, 1";
$maxi_result = mysql_query($sql) OR die(mysql_error());
$maxi_row = mysql_fetch_assoc($maxi_result);
$maxiSeite = $maxi_row['SEITE_ID'];
$sql = "SELECT SEITE_ID FROM A ORDER BY SEITE_ID ASC LIMIT 0, 1";
$mini_result = mysql_query($sql) OR die(mysql_error());
$mini_row = mysql_fetch_assoc($mini_result);
$miniSeite = $mini_row['SEITE_ID'];
if(!isset($_GET['Seite']) || !is_numeric($_GET['Seite']) || $miniSeite>$_GET['Seite'] || $maxiSeite<$_GET['Seite']) {
echo "
<html>
...
<p>Meine Bilder:</p>
";
// Liste mit Links erstellen
$sql = "SELECT * FROM A ORDER BY SEITE_ID";
$seite_result = mysql_query($sql) OR die(mysql_error());
while($seite_row = mysql_fetch_assoc($seite_result)) {
echo "
...
";
// ===== Ende von Seite 0 ======================================================
} else { //von isste GET-Seite
$aktSeite = $_GET['Seite'];
$sql = "SELECT * FROM A WHERE SEITE_ID=$aktSeite";
$seite_result = mysql_query($sql) OR die(mysql_error());
$seite_row = mysql_fetch_assoc($seite_result);
echo "
<html>
...
";
// ===== Sonderlocke Seite 1 ======================================================
if($seite_row['SEITE_ID']==1){
echo "
...
";
// ===== Normale Seite ======================================================
} else {
echo "<h1>{$seite_row['SEITE_TITEL']}</h1>\n<p>" . nl2br($seite_row['SEITE_TEXT']) . "</p>";
$sql = "SELECT * FROM B WHERE SEITE_ID=$aktSeite ORDER BY BILD_ID";
$bild_result = mysql_query($sql) OR die(mysql_error());
while($bild_row = mysql_fetch_assoc($bild_result)) {
$link_s=$bild_row['BILD_LINK'] . "size=s";
$link_l=$bild_row['BILD_LINK'] . "size=l";
echo "
<table width=\"70\" class=\"tabil\">
<tr><td>
<a href=\"$link_l\">
<img src=\"$link_s\" class=\"tabi\"></a>
</td></tr>
</table>
<p>" . $bild_row['BILD_KOMMENTAR']. "</p>
<br clear=\"all\"/>
";
}
}
// ===== Fusszeile mit Navigation alle Seiten =========================
if($aktSeite > 1) {
$zSeite=$aktSeite - 1;
$zlink="<a href=\"x.php?Seite=$zSeite \" target=\"test\">Seite zurück</a> |";
} else {
$zlink="";
}
if($aktSeite < $maxiSeite) {
$vSeite=$aktSeite + 1;
$vlink="| <a href=\"x.php?Seite=$vSeite \" target=\"test\">Seite vor</a>";
} else {
$vlink="| Fortsetzung folgt...";
}
echo "
<p align=\"center\">
<br /><br />
$zlink <a href=\"x.php\" target=\"test\">Übersicht</a> $vlink
</p>
";
$expDate = explode(" ",$seite_row['SEITE_UPDATE']);
$d = explode("-",$expDate[0]);
$aenderung = sprintf("%02d.%02d.%04d", $d[2], $d[1], $d[0]);
echo "
<div align=\"right\">
<br /><br /><br />© RoSt, letzte Änderung {$aenderung}
</div></body>
";
} // von if isset-GETseite
?>
Ich glaube trotzdem dass nur ein Select auf A die bessere Version wäre.
Wie kann man denn in einem assoziativen Array navigieren?
zeilenweise / spatenweise / min / max / vorgänger / nachfolger ???
Geändert von RoSt (01.02.2007 um 12:06:42 Uhr)
|
01.02.2007, 15:24:38
|
Member
|
|
Registriert seit: Jun 2006
Ort: Bayern
Alter: 56
Beiträge: 930
|
|
AW: optimieren von DB-Zugriffen
Ich hab dir mal dein Script auf zwei Abfragen gestutzt. Wenn du statt 'Seite vor' und 'Seite zurück' lieber den Titel des vorherigen und nächsten Bildes anzeigen möchtest. Könntest du dies über LIMIT $Seite, 3 statt LIMIT $Seite, 1 und mysql_data_seek() realisieren.
Clear ist übrigens veraltet.
Falls nicht zu jedem Eintrag in Tabelle 'A' ein Eintrag in Tabelle 'B' existiert kannst du LEFT JOIN statt INNER JOIN einsetzen. Das Datum der letzten Änderung kannst du über date_format schon bei der Abfrage in ein deutsches Format wandeln.
Ich würde den HTML-Quelltext auslagern und an den Stellen wo etwas eingetragen werden soll Platzhalter definieren. Das macht ein Script um einiges übersichtlicher und der Quelltext lässt sich einfacher und schneller anpassen.
PHP-Code:
$Seite = (!empty($_GET['Seite'])) ? $_GET['Seite'] + 0 : 0;
$sql = "SELECT SEITE_TITEL FROM A ORDER BY SEITE_ID";
$seite_result = mysql_query($sql) OR die(mysql_error());
$count = mysql_num_rows($seite_result);
if(!isset($_GET['Seite']) || $Seite < 0 || $Seite > $count) {
echo "
<html>
...
<p>Meine Bilder:</p>
";
//Liste mit Links erstellen
$x = 0;
while($seite_row = mysql_fetch_assoc($seite_result))
{
echo '<a href="?Seite='.$x.'">'.$seite_row['SEITE_TITEL'].'</a><br>';
$x++;
}
// ===== Ende von Seite 0 ======================================================
}
else {
$sql = "SELECT A.SEITE_ID AS sid, A.SEITE_TITEL AS st, A.SEITE_TEXT AS stxt, date_format(A.SEITE_UPDATE, '%d.%m.Y') AS su,
B.BILD_LINK AS bl, B.BILD_KOMMENTAR AS bk
FROM A INNER JOIN B ON (A.SEITE_ID = B.SEITE_ID)
ORDER BY SEITE_ID LIMIT $Seite, 1";
$seite_result = mysql_query($sql);
$seite_row = mysql_fetch_assoc($seite_result);
echo "<html> ... ";
// ===== Sonderlocke Seite 1 ======================================================
if($seite_row['sid'] == 1) {
echo "... ";
}
// ===== Normale Seite ======================================================
else {
echo '<h1>'.$seite_row['st']."</h1>\n<p>" . nl2br($seite_row['stxt']) . '</p>';
$link_s = $seite_row['bl'] . "size=s";
$link_l = $seite_row['bl'] . "size=l";
echo "
<table width=\"70\" class=\"tabil\">
<tr><td>
<a href=\"$link_l\">
<img src=\"$link_s\" class=\"tabi\"></a>
</td></tr>
</table>
<p>" . $seite_row['bk']. "</p>
<br clear=\"all\"/>
";
}
// ===== Fusszeile mit Navigation alle Seiten =========================
$link = '%s <a href="x.php?Seite=%s" target="test">Seite %s</a> %s';
if($Seite > 0) {
$zSeite = $Seite - 1;
$zlink = sprintf($link, NULL, $zSeite, 'zurück', '|');
}
else {
$zlink = "";
}
$vSeite = $Seite + 1;
if($vSeite < $count) {
$vlink = sprintf($link, '|', $vSeite, 'vor', NULL);
}
else {
$vlink = "| Fortsetzung folgt...";
}
echo "
<p align=\"center\">
<br /><br />
$zlink <a href=\"x.php\" target=\"test\">Übersicht</a> $vlink
</p>
";
//Datum wird bei Abfrage schon ins deutsche Format gewandelt
echo "
<div align=\"right\">
<br /><br /><br />© RoSt, letzte Änderung ".$seite_row['su']."
</div></body>
";
}
?>
__________________
Grüße Andes
Geändert von Andes (02.02.2007 um 12:43:00 Uhr)
|
01.02.2007, 16:10:12
|
Anfänger
|
|
Registriert seit: Jul 2006
Beiträge: 69
|
|
AW: optimieren von DB-Zugriffen
Vielen Dank für die Mühe. Nicht alles habe ich verstanden, da ich noch ein php-Ei bin.
PHP-Code:
while($seite_row = mysql_fetch_assoc($seite_result))
{
echo '<a href="?Seite='.$x.'">'.$seite_row['SEITE_TITEL'].'</a><br>';
$x++;
}
Hier wird davon ausgegangen, dass die Seiten also auch die Seiten_ID fortlaufend ist oder sehe ich das falsch? Seiten_ID kann Lücken haben. So stellt sich die Frage, passt man das php der Datenbank an oder umgekehrt. Ich hatte mich am ersten weg versucht, da dann die Datenbank weniger Reglementierungen unterliegt. Man könnte wahrscheinlich hier noch über die "sid" die Seiten_ID in der Datenbank ermitteln.
PHP-Code:
$Seite = (!empty($_GET['Seite'])) ? $_GET['Seite'] + 0 : 0;
Was bedeutet hier der zweite Teil?
PHP-Code:
$link = '%s <a href="x.php?Seite=%s" target="test">Seite %s</a> %s';
Was macht das "%s"?
Ich habe zwischenzeitlich meinen Array-Ansatz weiter verfolgt.
PHP-Code:
$sql = "SELECT * FROM A ORDER BY SEITE_ID";
$result = mysql_query($sql) OR die(mysql_error());
unset($seiten);
while($seiten[] = mysql_fetch_row($result));
array_pop($seiten);
Damit habe ich alle Ergebnisse in einem zweidimensionalten Array. Mit dem Vorteil eines fortlaufenden Index analog der mittels SQL erzeugten sid. Wenn ich jetzt noch rausbekommen wie man count(), prev() etc. auf mehrdimensionale Arrays anwendet, wäre auch diese Umsetzung möglich.
|
01.02.2007, 17:17:24
|
Member
|
|
Registriert seit: Jun 2006
Ort: Bayern
Alter: 56
Beiträge: 930
|
|
AW: optimieren von DB-Zugriffen
Ich hab oben noch mal etwas geändert. Da es sonst zu einem Mysql-Error kommen kann wenn $_GET['Seite'] kleiner 0 ist.
Zitat:
Zitat von RoSt
PHP-Code:
while($seite_row = mysql_fetch_assoc($seite_result))
{
echo '<a href="?Seite='.$x.'">'.$seite_row['SEITE_TITEL'].'</a><br>';
$x++;
}
Hier wird davon ausgegangen, dass die Seiten also auch die Seiten_ID fortlaufend ist oder sehe ich das falsch? Seiten_ID kann Lücken haben. So stellt sich die Frage, passt man das php der Datenbank an oder umgekehrt. Ich hatte mich am ersten weg versucht, da dann die Datenbank weniger Reglementierungen unterliegt. Man könnte wahrscheinlich hier noch über die "sid" die Seiten_ID in der Datenbank ermitteln.
|
Nein, $x ist die Datensatz-Id der Ausgabe und hat nichts mit deiner vergebenen SEITEN_ID zu tun. Also der wievielte Datensatz das ist, der ausgegeben wird. Da beide Abfragen die gleiche ORDER BY Anweisung haben, sind auch die Datensätze bei beiden Abfragen in der gleichen Reihenfolge.
Zitat:
Zitat von RoSt
PHP-Code:
$Seite = (!empty($_GET['Seite'])) ? $_GET['Seite'] + 0 : 0;
Was bedeutet hier der zweite Teil?
|
Wenn $_GET['SEITE'] vorhanden und nicht leer ist (!empty), dann '?' (? = if) wird der Variablen $Seite der Wert von $_GET['Seite'] zugewiesen. Wenn die Bedingung nicht stimmt, dann wird (: = else) der Variablen $Seite der Wert 0 zugewiesen.
$Seite = $_GET['Seite'] + 0; Verhindert, dass der Variable $Seite ein String zugewiesen wird.
Zitat:
Zitat von RoSt
PHP-Code:
$link = '%s <a href="x.php?Seite=%s" target="test">Seite %s</a> %s';
Was macht das "%s"?
|
%s sind so zu sagen Platzhalter in einem String bei denen mit sprintf oder printf Werte eingefügt werden können.
Zitat:
Zitat von RoSt
Ich habe zwischenzeitlich meinen Array-Ansatz weiter verfolgt.
PHP-Code:
$sql = "SELECT * FROM A ORDER BY SEITE_ID";
$result = mysql_query($sql) OR die(mysql_error());
unset($seiten);
while($seiten[] = mysql_fetch_row($result));
array_pop($seiten);
Damit habe ich alle Ergebnisse in einem zweidimensionalten Array. Mit dem Vorteil eines fortlaufenden Index analog der mittels SQL erzeugten sid. Wenn ich jetzt noch rausbekommen wie man count(), prev() etc. auf mehrdimensionale Arrays anwendet, wäre auch diese Umsetzung möglich.
|
Warum das Eine optimieren, wenn man an einer anderen Stelle wieder Umwege beschreitet?
Um den vorherigen und den nächsten Datensatz aus zu lesen brauchst du nur dein Limit auf 3 erhöhen und mit mysql_data_seek() kannst du dann den gewünschten Datensatz direkt ansprechen.
Ich hab das bei einer Blätterfunktion aber selbst noch nicht gemacht, da es üblich ist dies mit vor/zurück zu bezeichnen.
__________________
Grüße Andes
|
02.02.2007, 11:04:30
|
Anfänger
|
|
Registriert seit: Jul 2006
Beiträge: 69
|
|
AW: optimieren von DB-Zugriffen
Vielen dank. Habe erst jetzt den 'Trick' mit dem Limit $Seite,1 verstanden.
Werden bei dem join die Bilder aus der Tabelle B in der Reihenfolge von Bild_ID gezogen?
Mit dem '%s' werde ich mich wohl noch beschäftigen müssen...
Zitat:
Zitat von Andes
Ich hab das bei einer Blätterfunktion aber selbst noch nicht gemacht, da es üblich ist dies mit vor/zurück zu bezeichnen.
|
Das Praxisbuch bspw. arbeitet genauso, da werden unten jeweils das vorherige/nächste Thema als Blätterfunktion angeboten...
|
02.02.2007, 11:24:58
|
Member
|
|
Registriert seit: Jun 2006
Ort: Bayern
Alter: 56
Beiträge: 930
|
|
AW: optimieren von DB-Zugriffen
Zitat:
Zitat von RoSt
Werden bei dem join die Bilder aus der Tabelle B in der Reihenfolge von Bild_ID gezogen?
|
Mit JOIN werden Tabellen verknüpft und die entsprechenden zusammen gehörigen Datensätze ausgelesen.
Bei INNER JOIN werden nur Datensätze geliefert die in beiden Tabellen einen entsprechenden Eintrag haben.
Bei LEFT JOIN werden auch Datensätze aus der linken Tabelle (bei dir A) geliefert die keinen entsprechenden Datensatz in der zweiten Tabelle (B) enthalten.
Zitat:
Zitat von RoSt
Mit dem '%s' werde ich mich wohl noch beschäftigen müssen...
|
Ist doch gar nicht so schwer.
Beispiel
PHP-Code:
$string = 'Das ist %s Text';
$string = sprintf($string, 'ein');
print $string;
//oder
printf($string, 'ein');
Ausgabe: Das ist ein Text
Bei sprintf wird der modifizierte String in eine Variable gespeichert und bei printf wird er direkt ausgegeben.
Zitat:
Zitat von RoSt
Das Praxisbuch bspw. arbeitet genauso, da werden unten jeweils das vorherige/nächste Thema als Blätterfunktion angeboten...
|
Hab ich mir selbst noch gar nicht angeschaut.
__________________
Grüße Andes
|
02.02.2007, 12:07:09
|
Anfänger
|
|
Registriert seit: Jul 2006
Beiträge: 69
|
|
AW: optimieren von DB-Zugriffen
Zitat:
Zitat von Andes
Mit JOIN werden Tabellen verknüpft...
|
Hm, Frage falsch gestellt. Was der JOIN mach weiss ich.
Ich wollte nur wissen, ob bei der Abfrage, die ja die Bilder aus Tabelle B über den join zieht, die Bilder automatisch nach der BILD_ID sortiert sind oder ob sie evtl. vor der Ausgabe noch sortiert werden müssen.
Danke für das Beispiel mit '%s'. Ist tatsächlich gar nicht so schwer :)
|
02.02.2007, 12:27:20
|
Member
|
|
Registriert seit: Jun 2006
Ort: Bayern
Alter: 56
Beiträge: 930
|
|
AW: optimieren von DB-Zugriffen
Wenn die Bilder nach ihrer ID sortiert werden sollen musst du dies noch in deiner ORDER BY - Klausel angeben.
PHP-Code:
$sql = "SELECT A.SEITE_ID AS sid, A.SEITE_TITEL AS st, A.SEITE_TEXT AS stxt, date_format(A.SEITE_UPDATE, '%d.%m.Y') AS su,
B.BILD_LINK AS bl, B.BILD_KOMMENTAR AS bk
FROM A INNER JOIN B ON (A.SEITE_ID = B.SEITE_ID)
ORDER BY A.SEITE_ID, B.BILD_ID LIMIT $Seite, 1";
__________________
Grüße Andes
Geändert von Andes (02.02.2007 um 12:50:45 Uhr)
|
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
|
|
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.
HTML-Code ist aus.
|
|
|
Alle Zeitangaben in WEZ +2. Es ist jetzt 00:05:28 Uhr.
|