Gustl: mySql-DB Positionskampf

also ich komm nicht weiter. meine db hat bildinfos die ich nach WHERE jahr = ? ORDER BY pos (pos=smallint) ausgebe. pos ist pro jahr durchnummeriert, es gibt also pos 1 bei 2005, pos 1 bei 2006 etc.

jetzt müsste ich eine bildinfo von mir aus von pos 25 nach pos 5 umbenennen, alle bildinfos ab pos 6 müsste ich also um +1 erhöhen und neu durchzählen.

das scheint mir kompliziert und es klappt auch irgendwie nicht.

welche möglichkeiten hab ich die aufgabe sicher zu lösen ?

grüsse gustl

  1. Hallo Gustl,

    also ich komm nicht weiter. meine db hat bildinfos die ich nach WHERE jahr = ? ORDER BY pos (pos=smallint) ausgebe. pos ist pro jahr durchnummeriert, es gibt also pos 1 bei 2005, pos 1 bei 2006 etc.

    jetzt müsste ich eine bildinfo von mir aus von pos 25 nach pos 5 umbenennen, alle bildinfos ab pos 6 müsste ich also um +1 erhöhen und neu durchzählen.

    das scheint mir kompliziert und es klappt auch irgendwie nicht.

    Wo ist das Problem? Wahrscheinlich in Deiner MySQL-Version, die Du uns einfach verschweigst. Das ganze ist in drei Schritten zu erledigen

    • Setze die Position von Pos 25 auf einen künstlichen Wert
        (eine UPDATE-Anweisung)
    • Erhöhe die Position von pos 24 bis pos 5 um 1
        (eine UPDATE-Anweisung)
    • Setze die Position vom künstlichen Wert auf pos 5
        (eine UPDATE-Anweisung)

    Anmerkungen:
    Kapsele den Vorgang in eine Transaktion.
    Schreibe für den Vorgang eine Funktion (MySQL 5 und neuer).

    Wo siehst Du etwas Kompliziertes? Was funktioniert nicht?

    Freundliche Grüße

    Vinzenz

    1. Wo ist das Problem? Wahrscheinlich in Deiner MySQL-Version, die Du uns einfach verschweigst. Das ganze ist in drei Schritten zu erledigen

      Sorry: MySQL-Client-Version: 5.0.30

      Wo siehst Du etwas Kompliziertes? Was funktioniert nicht?

      Freundliche Grüße

      Vinzenz

      Hallo Vinzenz !

      Ja, wenn ich mir das so durchlese: Was ist dran kompliziert ? Eigentlich nix.

      Ich hatte folgendes vor: Setzte pos von INT auf FLOAT. Wenn ich nun das Bild auf eine neue pos setzen will, z.B. 8 dann setze ich den künstlichen Wert auf 7.5, also nach 7. das ganze neu nach ORDER BY pos holen und neu durchzählen. wenn ich den Datensatz an letzter Stelle haben will (ang. letzter ist 105 müsste ich halt nur auf 106 setzen und neu durchzählen. hmmm, auch logisch aber das ging nicht. 1.5 oder auch 1,5 blieb vor 1.

      Ich bin übrigens SQL-Anfänger und auch sonstig keine Leuchte.

      Ich dachte also ORDER BY pos müsste doch erkennen, das pos float ist und mir das ergebnis schön ordnen, damit ichs nur noch neu durchzählen muss und dann ists ok.

      also natürlich interessierts mich wo es bei meinem lösungsansatz hapert ...

      Muss ich vielleicht schreiben ORDER BY pos NUM oder so ? Ich find da nix gscheids drüber warum die Ordnung nicht richtig ist.

      Gruss Gustl

      1. Hallo Gustl,

        Wo ist das Problem? Wahrscheinlich in Deiner MySQL-Version, die Du uns einfach verschweigst. Das ganze ist in drei Schritten zu erledigen

        Sorry: MySQL-Client-Version: 5.0.30

        die Client-Version interessiert weniger. Wichtig ist vor allem die Serverversion, denn diese entscheidet, was der Server kann. Es liegt zwar die Vermutung nahe, dass es ebenfalls eine 5er-Version ist (derzeit ist in der stabilen 5.0-Serie 5.0.27 aktuell).

        Du bekommst die Serverversion z.B. über das MySQL-proprietäre SQL-Statement:

        SELECT VERSION()

        heraus.

        Ich hatte folgendes vor: Setzte pos von INT auf FLOAT.

        Oh je. Wie willst Du das tun? Warum willst Du das tun?

        Wenn ich nun das Bild auf eine neue pos setzen will, z.B. 8 dann setze ich den künstlichen Wert auf 7.5, also nach 7. das ganze neu nach ORDER BY pos holen und neu durchzählen.

        ORDER BY zählt nichts durch. ORDER BY sortiert. Verabschiede Dich von der Vorstellung, dass Datensätze in einer Datenbank richtig umsortiert würden.

        Ich bin übrigens SQL-Anfänger

        Du hattest neulich irgendwelche Perl-SQL-Fragen ;-)

        also natürlich interessierts mich wo es bei meinem lösungsansatz hapert ...

        Dein Lösungsansatz ist völlig falsch und ungeeignet. Was hast Du an meinem Lösungsansatz nicht verstanden? Dein Lösungsansatz hat mit meinem überhaupt nichts gemeinsam (außer eventuell dem künstlichen Wert).

        • Setze die Position von Pos 25 auf einen künstlichen Wert
            (eine UPDATE-Anweisung)

        Die Spalte hat den Datentyp SMALLINTEGER. Ich bezweifle, dass Du als Position den Wert 0 verwendest. Verwende also 0 für Dein "Zwischenspeichern":

        ~~~sql UPDATE bildinfo
          SET pos = 0      -- der künstliche Wert als Zwischenspeicher
          WHERE pos = 25   -- der zu verschiebende Wert

          
        
        > > - Erhöhe die Position von pos 24 bis pos 5 um 1  
        > >   (eine UPDATE-Anweisung)  
          
          ~~~sql
        UPDATE bildinfo  
          SET pos = pos + 1           -- Alle Einträge  
          WHERE pos BETWEEN 5 AND 25  -- zwischen 5 und 25 (25 ist nicht mehr belegt :-))  
                                      -- rutschen eins runter
        
        • Setze die Position vom künstlichen Wert auf pos 5
            (eine UPDATE-Anweisung)

        ~~~sql UPDATE bildinfo
          SET pos = 5                 -- Setze den Eintrag aus dem "Zwischenspeicher"
          WHERE pos = 0               -- auf Position 5

          
        Wenn Du MySQL 5.x hast, packst Du die drei Anweisungen (ja, nur drei) in eine Funktion, der Du als Übergabeparameter die Ausgangsposition und die neue Position übergibst.  
          
        Du musst auswerten, ob der Eintrag nach oben (wie im Beispiel) oder nach unten verschoben wird und entsprechend reagieren. Hier kannst Du ganz normal mit bedingter Ausführung arbeiten wie in anderen Programmiersprachen auch.  
          
        Weiterhin wäre es eine gute Idee (die etwas Performanz kostet), sicherzustellen, dass der hier fixe Wert des Zwischenspeichers auch unbenutzt ist - und ggf. den Wert des Zwischenspeichers dynamisch zu bestimmen MIN(spalte) - 1 oder MAX(spalte) + 1 ...  
          
        Durch was bestimmen sich Deine Positionen überhaupt? Vielleicht läßt sich das auch ganz anders lösen.  
          
          
        Freundliche Grüße  
          
        Vinzenz
        
        1. die Client-Version interessiert weniger.

          Server Version: 5.0.30-Debian_3-log

          Ich hatte folgendes vor: Setzte pos von INT auf FLOAT.
          Oh je. Wie willst Du das tun? Warum willst Du das tun?

          1.In der Datenbbank-Verwaltung 2.Hab ich doch schon erklärt

          ORDER BY zählt nichts durch. ORDER BY sortiert. Verabschiede Dich von der Vorstellung, dass Datensätze in einer Datenbank richtig umsortiert würden.

          Nun das ist mir schon klar dass ORDER BY nur sortiert. Ich wollte wissen warum ORDER BY 1,5 vor 1 sortiert und 2,5 vor 2. Wenn das nicht so wär würde eigentlich meine Lösung auch bereits laufen.

          Es ist schwierig im Forum weil so viel aneinander vorbeigeredet wird.

          Ich bin übrigens SQL-Anfänger
          Du hattest neulich irgendwelche Perl-SQL-Fragen ;-)

          Ja die DBI musste ich lernen und so einiges mehr ...

          Dein Lösungsansatz ist völlig falsch und ungeeignet.

          Danke das baut auf :) Aber lange Rede kurzer Sinn :) Natürlich hab ich Deine Lösung verstanden und er ist auch sinnvoll.

          Durch was bestimmen sich Deine Positionen überhaupt? Vielleicht läßt sich das auch ganz anders lösen.

          Das verstehe ich nicht, durch was ? Na durch die Positionsnummern in pos oder ?

          Ich habe 5 Spalten angelegt: 0=ident;1=bildname;2=bemerkung;3=jahr;4=pos

          Die gesamten Programmroutinen machen folgendes:

          1.) Neu: Benennen und laden einer Bilddatei auf den Server und dann komprimieren.
          2.) Neu: Eintragen der nötigen Infos für dieses Bild in die Datenbank für spätere Ausgabe der Bildergalerie. (zunächst mal einfach hochgezählt)
          3.) Bearbeiten: Ersetzen des Bildes
          4.) Bearbeiten: Ersetzen der Anmerkung
          5.) Bearbeiten: Löschen des Bildes und der DB-Infos
          6.) Verschieben der Bildposition nach pos :) Da sind wir ...

          7.) Anzeige der "Bildergalerie" selektiert nach entsprechendem Jahr und nach der pos.

          6 hapert.

          Grüsse Gustl

        2. ~~~sql

          UPDATE bildinfo

          SET pos = pos + 1           -- Alle Einträge
            WHERE pos BETWEEN 5 AND 25  -- zwischen 5 und 25 (25 ist nicht mehr belegt :-))
                                        -- rutschen eins runter

            
          
          > Du musst auswerten, ob der Eintrag nach oben (wie im Beispiel) oder nach unten verschoben wird und entsprechend reagieren. Hier kannst Du ganz normal mit bedingter Ausführung arbeiten wie in anderen Programmiersprachen auch.  
            
          
          > Freundliche Grüße  
          >   
          > Vinzenz  
            
          Also Vinzenz, meine Idee mit dem Komma-Zwischenwert ist mist, hast recht :)  
            
          So also:  
            
          setze alte\_pos 25 auf 0 .  
            
          ist alte\_pos 25 und neue\_pos 5, also neue\_pos < alte\_pos rechne ich pos = pos + 1 zwischen alte\_pos und neue\_pos .  
            
          setze 0 auf neue\_pos 5 .  
            
          Und umgekehrt:  
            
          setze alte\_pos 5 auf 0 .  
            
          ist alte\_pos 5 und neue\_pos 25, also neue\_pos > alte\_pos rechne ich pos = pos - 1 zwischen zwischen alte\_pos und neue\_pos .  
            
          setze 0 auf neue\_pos 25 .  
            
          Hab ichs nun gefressen ?  
            
          Grüsse Gustl  
          
          
          1. Hallo Gustl,

            Also Vinzenz, meine Idee mit dem Komma-Zwischenwert ist mist, hast recht :)

            bei der nächsten Verschiebung nähmst Du dann 1,25 oder 1,75 ...

            Und umgekehrt:

            setze alte_pos 5 auf 0 .

            ist alte_pos 5 und neue_pos 25, also neue_pos > alte_pos rechne ich pos = pos - 1 zwischen zwischen alte_pos und neue_pos .

            setze 0 auf neue_pos 25 .

            sieht doch schon mal gut aus. Du kannst doch programmieren. Dein nächster Schritt wäre, dies in eine Funktion für Dein MySQL 5.0 zu packen.

            Zum Testen von solchen Sachen in einer Testumgebung finde ich die MySQL-Client-Tools ganz angenehm:

            http://www.mysql.com/products/tools/

            Freundliche Grüße

            Vinzenz

          2. Hab ichs nun gefressen ?

            Du hast eine strukturierte Vorgehensweise ins Auge gefasst, das ist schon mal nicht schlecht.

            Allerdings hast Du es erst wirklich gefressen, wenn Du "Positionskämpfe" (LOL) zukünftig nicht mit dem (bzw. im) Datendesign führst.   ;)

  2. also ich komm nicht weiter. meine db hat bildinfos die ich nach WHERE jahr = ? ORDER BY pos (pos=smallint) ausgebe. pos ist pro jahr durchnummeriert, es gibt also pos 1 bei 2005, pos 1 bei 2006 etc.

    jetzt müsste ich eine bildinfo von mir aus von pos 25 nach pos 5 umbenennen, alle bildinfos ab pos 6 müsste ich also um +1 erhöhen und neu durchzählen.

    Das Datenfeld pos scheint der Bock zu sein, wenn Du sortieren willst, dann sortiere "just in time", also wenn die Liste gebraucht wird, nicht vorrätig und auf keinen Fall fang an Sortierungen selbst zu verwalten und gar Abhängigkeiten zu schaffen.