PHP MySQL Paginierung mit zufälliger Reihenfolge

8

Dies ist ein Problem mit einer Bestellung Suchergebnisse auf meiner Website,

Wenn eine Suche durchgeführt wird, werden zufällige Ergebnisse auf der Inhaltsseite angezeigt. Diese Seite enthält auch Seitenumbrüche. Ich Benutzer folgt als meine SQL-Abfrage.

%Vor%

Also meine Fragen sind

  1. Ich muss sicherstellen, dass jedes Mal, wenn ein Benutzer die nächste Seite besucht, Ergebnisse, die er bereits gesehen hat, nicht mehr angezeigt werden (in der nächsten Abfrage ausschließen, auf speichereffiziente Weise, aber immer noch von rand ())

  2. jedes Mal, wenn der Besucher auf die erste Seite geht, gibt es eine andere Reihe von Ergebnissen. Ist es möglich, die Seitennummerierung zu verwenden, oder wird die Reihenfolge immer zufällig sein.

  3. Ich kann seed im MYSQL verwenden, aber ich bin mir nicht sicher, wie ich das praktisch anwenden soll.

mahen3d 24.05.2012, 00:21
quelle

6 Antworten

11

Zufällige Reihenfolge in MySQL ist so ein Problem wie sie kommen. In der Vergangenheit habe ich mich normalerweise dafür entschieden, das Problem nach Möglichkeit zu umgehen. In der Regel wird ein Benutzer niemals mehr als ein- oder zweimal zu einer Reihe von Seiten wie dieser zurückkehren. Dies gibt Ihnen die Möglichkeit, all die verschiedenen widerlichen Implementierungen der zufälligen Reihenfolge zugunsten einer paar einfache, aber nicht ganz 100% zufällige Lösungen zu vermeiden.

Lösung 1

Wählen Sie aus einer Reihe von vorhandenen Spalten aus, die bereits für die Sortierung indiziert wurden. Dazu können erstellte, geänderte Zeitstempel oder andere Spalten gehören, nach denen Sie sortieren können. Wenn ein Benutzer zum ersten Mal auf die Website kommt, haben Sie diese in einem Array, wählen Sie eine zufällig aus und wählen Sie dann nach dem Zufallsprinzip ASC oder DESC .

In Ihrem Fall, jedes Mal, wenn ein Benutzer zu Seite 1 zurückkehrt, wählen Sie etwas Neues, speichern Sie es in der Sitzung. Auf jeder folgenden Seite können Sie diese Art verwenden, um einen konsistenten Paging-Satz zu generieren.

Lösung 2

Sie könnten eine zusätzliche Spalte haben, die eine zufällige Nummer zum Sortieren speichert. Es sollte offensichtlich indexiert werden. Führen Sie regelmäßig die folgende Abfrage aus:

  

UPDATE-Tabelle SET rand_col = RAND ();

Dies funktioniert möglicherweise nicht für Ihre Spezifikationen, da Sie scheinbar jeden Benutzer dazu zwingen, jedes Mal etwas anderes zu sehen, wenn er Seite 1 erreicht.

    
Chris Henry 24.05.2012, 02:55
quelle
32

Verwenden Sie RAND (SEED) . Aus der Dokumentation: " Wenn ein konstantes ganzzahliges Argument N angegeben wird, wird es als Startwert verwendet. " ( Ссылка ).

Im obigen Beispiel ist die Ergebnisreihenfolge rand, aber sie ist immer gleich. Sie ändern einfach den Samen und Sie erhalten eine neue Reihenfolge.

%Vor%

Sie können die Saat jedes Mal ändern, wenn der Benutzer die erste Ergebnisseite erreicht.

    
Arivan Bastos 17.05.2014 02:01
quelle
0

Sie haben mehrere Probleme zu bewältigen! Ich empfehle, dass Sie Schritt für Schritt gehen.

Erstes Problem: Ergebnisse, die sie bereits nicht mehr gesehen haben

  1. Jedes zurückgegebene Objekt wird in einem Array gespeichert. (angenommen der Index id im Beispiel)
  2. Wenn der Benutzer zur nächsten Seite geht, übergeben Sie die Abfrage an NICHT IN :

MySQL-Abfrage

%Vor%

Dies bedeutet, dass alle id übereinstimmen, die nicht 1, 14, 25 oder 645 sind.

Was das Leistungsproblem betrifft: auf eine speichereffiziente Weise

%Vor%

Anzeigen der Zeilen 0 - 9 (insgesamt 10, Abfrage dauerte 0,0004 Sekunden)

UND

%Vor%

Anzeigen der Zeilen 0 - 9 (insgesamt 10, Abfrage dauerte 0,0609 Sek.)

Verwenden Sie also ORDER BY RAND () nicht, verwenden Sie vorzugsweise SELECT RAND ().

    
Zuul 24.05.2012 00:37
quelle
0

Zuerst sollten Sie aufhören, die ORDER BY RAND-Syntax zu verwenden. Dies beeinträchtigt die Leistung in großen Reihen.

Sie müssen die LIMIT-Einschränkungen manuell bestimmen. Wenn Sie die zufälligen Ergebnisse weiterhin verwenden möchten und nicht möchten, dass Benutzer dieselben Ergebnisse auf der nächsten Seite anzeigen, besteht die einzige Möglichkeit darin, das gesamte Ergebnis für diese Suchsitzung in der Datenbank zu speichern und diese Informationen beim Navigieren zur nächsten Seite zu bearbeiten.

Das nächste im Webdesign sollten Sie verstehen - die Verwendung beliebiger Datenblöcke auf Ihrer Website ist sehr, sehr, sehr schlecht für die visuelle Wahrnehmung der Benutzer.

    
odiszapc 24.05.2012 00:30
quelle
0

Ich möchte, dass Ihr PHP Ihre zufälligen Datensatznummern oder Zeilen zum Abrufen generiert, diese an Ihre Abfrage weitergibt und ein Cookie auf dem Client des Benutzers speichert, das anzeigt, welche Datensätze sie bereits gesehen haben.

Es gibt keinen Grund dafür, dass diese benutzerspezifischen Daten auf dem Server gespeichert werden (es sei denn, Sie verfolgen es, aber es ist trotzdem zufällig, also wen interessiert's).

    
FlavorScape 24.05.2012 00:30
quelle
0

Die Kombination von

  1. zufällige Reihenfolge
  2. Paginierung
  3. HTTP (zustandslos)

ist so hässlich wie es kommt: 1. und 2. zusammen brauchen eine Art "persistente Zufälligkeit", während 3. dies schwieriger zu erreichen ist. Darüber hinaus ist 1. kein Job, für den ein RDBMS optimiert ist.

Mein Vorschlag hängt davon ab, wie groß Ihr Datensatz ist:

Wenige Zeilen (ca. & lt; 1K):

  • Wählen Sie alle PK-Werte in der ersten Abfrage (erste Seite)
  • aus
  • mische diese in PHP
  • Shuffle-Liste in Sitzung speichern
  • Wählen Sie für jeden Seitenaufruf die Daten entsprechend den gespeicherten PKs

Viele Zeilen (10K +):

Dies setzt voraus, dass Sie einen AUTO_INCREMENT eindeutigen Schlüssel namens ID mit einer überschaubaren Anzahl von Löchern haben. Verwenden Sie bei Bedarf ein Korrekturskript (hohes Löschverhältnis)

  • Verwenden Sie eine Umordnungsfunktion, die z. die Sitzungs-ID zum Erstellen einer Funktion rand_id(continuous_id)
  • Wenn Sie z.B. die Datensätze 100.000 bis 100.009 berechnen $a=array(rand_id(100,000), rand_id(100,001), ... rand_id(100,009));
  • $a=implode(',',$a);
  • $sql="SELECT foo FROM bar WHERE ID IN($a) ORDER BY FIELD(ID,$a)";
  • Um auf die Lücken in Ihrer ID zu achten, wählen Sie einige Datensätze zu viele aus (und werfen Sie den Überschuss weg), indem Sie zu wenige ausgewählte Datensätze durchgehen.
Eugen Rieck 24.05.2012 01:01
quelle

Tags und Links