Chris: Order By Rand ziemlich unzuverlässig

Tach auch,
ich hab ein großes Problem, und zwar lasse ich via ORDER BY rand() mir zufällig immer einen Eintrag aus meiner MySQL Tabelle auslesen, jetzt bin ich jedoch eben auf php4 umgestiegen und schwups es geht nicht mehr, vielmehr liefert rand() mir permanent den selben eintrag aus der mysql tabelle ?

was kann ich jetzt machen ? ausser wieder php3 draufspielen, hab bereits mal auf der php.net site und mysql site geguckt, aber da steht nix davon dat sich der code geändert hätte

danke gruß Chris

  1. Tach auch,
    ich hab ein großes Problem, und zwar lasse ich via ORDER BY rand() mir zufällig immer einen Eintrag aus meiner MySQL Tabelle auslesen, jetzt bin ich jedoch eben auf php4 umgestiegen und schwups es geht nicht mehr, vielmehr liefert rand() mir permanent den selben eintrag aus der mysql tabelle ?

    Du solltest das ganze erst mit der Funktion srand() initialisieren, da Dir rand sonst den selben wert ausgibt.

    Ein kleines Beispiel ist hier zu finden: http://www.php4-forum.de/beispiele/zufall.htm

    was kann ich jetzt machen ? ausser wieder php3 draufspielen, hab bereits mal auf der php.net site und mysql site geguckt, aber da steht nix davon dat sich der code geändert hätte

    danke gruß Chris

    Ich hoffe es hilft Dir,
    Gruss Stefan

    1. Hi stefan,

      mhm... ne leider nicht, also der code ist 100% korrekt, und mit initialisieren von srand wird immer noch der selbe Wert ausgewählt, was kann man anders machen als rand() zu nutzen, da irgendwie geht es wohl nicht mehr wirklich zuverlässig unter php4 ?

      gruß Chris

      1. Hi,

        mhm... ne leider nicht, also der code ist 100% korrekt,

        Das glaube ich nicht, bitte Beweise auf den Tisch des Hauses.

        und mit initialisieren von srand wird immer noch der selbe Wert ausgewählt, was kann man anders machen als rand() zu nutzen, da irgendwie geht es wohl nicht mehr wirklich zuverlässig unter php4 ?

        Glaube nicht, das PHP4 rand() kaputgespielt hat, aber unmöglich ist ja nix ;-)

        Als Alternativen stehen dir mehrere Möglichkeiten zur Verfügung:

        • selber einen RNG in PHP schreiben (Nachteil: kompliziert)
        • eine Checksum nehmen (Nachteil: sehr kurze Loops)
        • sich anderweitig Zufallszahlen beschaffen (Nachteil: lahm (random.org o.ä. Quelle) bzw schlecht möglich (/dev/random))

        so short

        Christoph Zurnieden

        1. Hi,
          jo Code ist korekt, hab derweil auch von einem selbigen Problem bei google gefunden... aber nur ne Lösung lässt auf sich warten, es geht nix... ich kann egal was machen es geht alles nicht. Dass komische ist, wenn ich so Random zahlen erzeugen lass sind die wirklich immer anders... ich dreh bald durch :((((

          ich bräuchte ne alternative zu rand() so wie es "damals" ging, da rand() ist ja noch alzualt (zumindest unter mysql -- hab'sch gelesen *g*)

          gruß Chris

          1. Apropos, Beweise is schön und gut, würd ich gerne, kann dir ja ne siteadresse geben, aber dat bringt ja nix, da kommt ja immer dat selbe...

          2. Hi,

            jo Code ist korekt,

            Das bezweifele ich immer noch.

            hab derweil auch von einem selbigen Problem bei google gefunden...

            Wenn Du uns an dem Link teilhaben läßt, wäre das recht nett.

            Es fehlen übrigens auch jede Menge Informationen, wenn Du uns schon nicht den Code verraten willst: PHP-Version, Argumente beim Bauen, angelinkte Bibliotheken usw.

            aber nur ne Lösung lässt auf sich warten, es geht nix... ich kann egal was machen es geht alles nicht. Dass komische ist, wenn ich so Random zahlen erzeugen lass sind die wirklich immer anders... ich dreh bald durch :((((

            Aha, also ist rand() gar nicht kaput, interessant.
            Damit liegt es dann doch am Code. Da Du uns den nicht zeigen willst, können wir da nicht viel machen, Kristallkugeln sind alle in der Reparatur.
            Zumindest der o.a. Link zu einem ähnlichen Problem wäre hilfreich gewesen.

            ich bräuchte ne alternative zu rand() so wie es "damals" ging, da rand() ist ja noch alzualt (zumindest unter mysql -- hab'sch gelesen *g*)

            Nein, denn rand() funktioniert kja, wie Du selber schon festgestellt hast und einen Mersenne-Twister o.ä in PHP nachztubauen fände ich zwar eine interessante Aufgabe, aber so dolle auch wieder nicht, das ich das gratis tun würde ;-)

            so short

            Christoph Zurnieden

            1. Ja von mir aus hier ist der Code, aber der ist korekt, zumal alles unter php3 einwandfrei lief... und an der mysql version is nix geändert worden.

              wie bereits schonmal erwähnt momentan php4 und es geht nicht... immer der selbe artikel, hab mir dat script jetzt knapp 10.000 mal aufrufen lassen: immer der selbe artikel, hab das ergebnis logen lassen ebenfalls in eine mysqltabelle ergebniss: 10.031 Aufrufe : 10.031 Artikel mit ID 531

              Code:
              $result_neuerartikel = @mysql_query("SELECT * FROM artikel WHERE artikel!='$nowartikel' ORDER BY rand()");

              vorher wird ganz normal meine datenbank conected..

              gruß Chris

              1. Moin,

                wie bereits schonmal erwähnt momentan php4 und es geht nicht... immer der selbe artikel, hab mir dat script jetzt knapp 10.000 mal aufrufen lassen: immer der selbe artikel, hab das ergebnis logen lassen ebenfalls in eine mysqltabelle ergebniss: 10.031 Aufrufe : 10.031 Artikel mit ID 531

                Das ist nicht rein zufällig der einzige Artikel auf den deine WHERE-Bedingung zutrifft? Ansonsten: Tu noch ein LIMIT 1 hinzu, wenn du nur einen Artikel auslesen willst.

                Und tu

                $result_neuerartikel = @mysql_query("SELECT * FROM artikel WHERE artikel!='$nowartikel' ORDER BY rand()");

                das @ da weg, zumindest während der Fehlersuche. Ich weiss auch nicht wo das immer herkommt. Das @ scheint mir weitaus gefährlicher zu sein als register_globals. Mag das nicht mal jemand deprecaten?

                --
                Henryk Plötz
                Grüße aus Berlin
                ~~~~~~~~ Un-CDs, nein danke! http://www.heise.de/ct/cd-register/ ~~~~~~~~
                ~~ Help Microsoft fight software piracy: Give Linux to a friend today! ~~
                1. Hi,

                  ne also von 10.031 Artikeln triff immer nur ein Artikel zu, halt der den der User selber ausgewählt hat, nur der zufällig ist permanent der selbe, hab dat Limit 1 hinzugefügt, und dat @ weg... Problem immer noch das selbe :(

                  gruß Chris

                  1. Moin!

                    ne also von 10.031 Artikeln triff immer nur ein Artikel zu, halt der den der User selber ausgewählt hat, nur der zufällig ist permanent der selbe, hab dat Limit 1 hinzugefügt, und dat @ weg... Problem immer noch das selbe :(

                    Moment, noch mal langsam zum mitmeißeln: Der User wählt sich einen Artikel aus, der deswegen als einziger aus der Datenbank gewählt wird - wie soll denn da noch der Zufall mit reinspielen? Wenn du exakt einen definierten Artikel aufgrund der WHERE-Bedingung auswählst, kannst du den gar nicht "zufällig" sortieren lassen.

                    Abgesehen davon: Das "rand()" ist keine PHP-Funktion, sondern eine MySQL-Funktion (steht im SQL-Query drin), also kann ein Wechsel von PHP3 zu PHP4 keine Auswirkungen haben. Das nur mal zur Klarstellung, einige Antworter hier im Thread scheinen das genauso zu verwechseln, wie du selbst auch.

                    - Sven Rautenberg

                    1. Also ok, vielleicht hab ich mich da was falsch ausgedrückt: also nochmal:
                      Der User wählt einen Artikel aus dieser wird dann auch angezeigt, links am Rand wird als Vorschau ein zufälliger Artikel angezeigt, aber: dieser soll letztlich nicht mit dem Artikel übereinstimmen die der User eh schon selber angeklickt hat, denn was will ein User mit der Info über einen anderen vielleicht interressanten Artikel wenn er selbigen (!!) bereits selber zu Detailansicht angeklickt hat ?!?! So jetzt sollte es klar sein, oder ? *gg*
                      auf jeden Fall, schön und gut, dass weiß ich selber das rand() im mysql query drin steht, nur wieso kommt immer der selbe Artikel ? ok, es sind keine wirklichen zufallszahlen, keine ahnung welcher verteilung die folgen etc ist auch egal, aber, dass bei (hab mein script nocheinmal überarbeitet und um schleifen ersetzt) mitlerweile über 300.000 Anfragen immer (und ich sage wirklich immer !) der selbe artikel kommt ist komisch ? zumal das script unter php3 einwandfrei lief ohne dass ich was verändert hab und ich sage echt: nichts verändert, lediglich wurde php4 aufgespielt !
                      Hab dat ding unter php3 (auf meinem lokalen windows rechner getestet) und es geht; sprich es kommt nicht (!) immer der selbe artikel...

                      woran soll dat denn jetzt liegen ? ich dreh gleich noch durch, letztlich kann ich mir also nur noch alle ids von artikeln in ein array einlesen und daraus eine id zufällig ermitteln und diese id wieder einlesen ??? dat kann doch nicht wahr sein :(( dreh gleich durch

                      gruß eike

                      1. noch ne kleine ergänzung, einfaches ändern auf php3 ist nicht möglich da ich scripte von anderen leuten die am projekt arbeiten mit funktionen etc aus php4 geschrieben sind

                        gruß chris e.

                      2. Moin!

                        woran soll dat denn jetzt liegen ? ich dreh gleich noch durch, letztlich kann ich mir also nur noch alle ids von artikeln in ein array einlesen und daraus eine id zufällig ermitteln und diese id wieder einlesen ??? dat kann doch nicht wahr sein :(( dreh gleich durch

                        Zitat aus der MySQL-Doku:
                        "If "SELECT * FROM tab ORDER BY RAND()" doesn't work for you. Try to put a random value between the brackets."

                        Und jetzt bist du wieder dran... Zufallswerte in PHP sollten dir ja mittlerweile auch ein Begriff sein.

                        - Sven Rautenberg

                        1. ähm... ja klasse, jetzt geht es *lach* danke, nur wieso es nicht mehr funzte kannst du mir nicht sagen, oder ?? naja, egal, halt alle Scripte abändern und dann geht es wieda *g* (bis zum nächsten php-Version-wechsel *lach*)

                          danke und gruß
                          Chris

                          1. Hi,

                            »»(bis zum nächsten php-Version-wechsel *lach*)

                            Dann halt Dich mal ran, PHP5 ist gerade raus ;-)

                            so short

                            Christoph Zurnieden

                        2. Hi,

                          woran soll dat denn jetzt liegen ? ich dreh gleich noch durch, letztlich kann ich mir also nur noch alle ids von artikeln in ein array einlesen und daraus eine id zufällig ermitteln und diese id wieder einlesen ??? dat kann doch nicht wahr sein :(( dreh gleich durch

                          Zitat aus der MySQL-Doku:
                          "If "SELECT * FROM tab ORDER BY RAND()" doesn't work for you. Try to put a random value between the brackets."

                          Kann es sein, daß PHP 3 beim MySQL-Connect automatisch einmal RAND(zufallswert) ausgeführt hat und das bei PHP 4 jetzt nicht mehr der Fall ist?

                          cu,
                          Andreas

                          --
                          MudGuard? Siehe http://www.Mud-Guard.de/
                          Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
              2. Hi,

                Ja von mir aus hier ist der Code, aber der ist korekt, zumal alles unter php3 einwandfrei lief... und an der mysql version is nix geändert worden.

                BTW und auch für's Archiv: PHP3 und PHP4 sind mittlerweile fast schon zwei verschiedene Programme, nicht nur zwei aufeinanderfolgende Versionen. die 3er Version ist unter der GPL gestellt, die 4er unter eine Art BSD-Lizenz aber nicht zur gPL kompatibel. Die 3er wird auch ganz normal weiterentwickelt, ist ein regulärer Fork.

                wie bereits schonmal erwähnt momentan php4 und es geht nicht... immer der selbe artikel, hab mir dat script jetzt knapp 10.000 mal aufrufen lassen: immer der selbe artikel, hab das ergebnis logen lassen ebenfalls in eine mysqltabelle ergebniss: 10.031 Aufrufe : 10.031 Artikel mit ID 531

                Code:
                $result_neuerartikel = @mysql_query("SELECT * FROM artikel WHERE artikel!='$nowartikel' ORDER BY rand()");

                vorher wird ganz normal meine datenbank conected..

                So, das ist zwar immer noch recht sparsam an Information, aber immerhin mehr als nix. Da das einzige, was Du gewechselt hast, die PHP Version ist, ist nachzuschauen, ob da mysql_query() noch die gleiche Syntax hat. Außerdem wird gegen eine PHP-Variable im Query verglichen, wird die bei mysql_query() in PHP4 immer noch genauso aufgelöst? Stimmt das Quoting?
                Kontrollier alles und komm dann wieder falls das Dingen unerwarteterweise immer noch nicht funktionieren sollte.

                so short

                Christoph Zurnieden

                PS:
                Da kein "kryptographisch harter" Zufall benötigt wird, kannst Du ja mal einen linearen Kongruenzgenerator probieren. Schweres Wort, einfache Iterations Formel:
                $x_i = ax_{i-1} + b mod m$
                Für die Implementation ist eine kleine Umstellung brauchbar, das Ergebniss sind dann zwei Zeilen

                /* $seed muß global sein */
                function lkg($seed, $a, $b,$N){
                  $result = ($seed * $a + $b) % $N;
                  $seed = result;
                }

                Eine paar passende Parameter sind z.B.
                a = 16807, b = 0, N = 2^31 -1 = 2147483647.
                (Ja, der Startparameter für $seed ist ziemlich egal, würde die Zeit empfehlen)

                Das ist für sowas eher zu empfehlen, da Du so die äußerst kostbare Systementropy nicht antastest. Wahrscheinlich ist es außerdem noch etwas schneller ;-)

                CZ

  2. Hi,

    ich hab ein großes Problem, und zwar lasse ich via ORDER BY rand() mir zufällig immer einen Eintrag aus meiner MySQL Tabelle auslesen, jetzt bin ich jedoch eben auf php4 umgestiegen und schwups es geht nicht mehr, vielmehr liefert rand() mir permanent den selben eintrag aus der mysql tabelle ?

    ORDER BY RAND()
    hat - wenn es so in einem SQL-Befehl steht - nichts mit PHP zu tun, denn es ist ja die Datenbank-Funktion RAND, die benutzt wird.

    Aber ohne den relevanten Code ist das nur Raterei.

    cu,
    Andreas

    --
    MudGuard? Siehe http://www.Mud-Guard.de/
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.