Richi: Datensatz vielleicht kopieren

Hallo Forum,

ich habe gerade folgendes realisiert und frage mich, ob das auch "schlanker" geht (DB: mysql5)?

Abfrage, ob ein Datenbankeintrag mit bestimmten Bedingungen existiert:
SELECT ID,spalte1 FROM Tabelle WHERE spalte2 > 123

Prüfen, ob die ID des gefundenene Datensatzes (autoinrement) die höchste in der Tabelle ist.
SELECT MAX(ID) FROM Tabelle, 0)

Prüfen (in php), ob die zuvor gefundene ID höher oder gleich der Max-ID ist.

Falls es nicht die höchste ID ist, dann Datensatz duplizieren und den mit der gefundenen ID stattdessen löschen.

...

Das sind natürlich schon recht viele Schritte für ein doch eher simples Probem.

Daher meine Fragen:

  1. Geht das nicht auch "schlanker"?
  2. Kann ich z.B. auch einfach die ID des gefundenen Datensatzes ändern? Obwohl die Spalte "autoincrement" ist? Macht das vielleicht gar nichts aus?
  3. Gehts das alles auch in 1 Query oder ist das nicht möglich?

Viele Grüße, Richard

  1. Lieber Richi,

    ich bin noch SQL-Neuling, aber spontan hätte ich das jetzt so probiert:

    SELECT ID, spalte1  
    FROM Tabelle  
    WHERE spalte2>123  
        AND ID=(  
            SELECT MAX(ID)  
            FROM Tabelle  
        )
    

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Lieber Richi,

      ich bin noch SQL-Neuling, aber spontan hätte ich das jetzt so probiert:

      SELECT ID, spalte1

      FROM Tabelle
      WHERE spalte2>123
          AND ID=(
              SELECT MAX(ID)
              FROM Tabelle
          )

      
      >   
        
      Hallo Felix,  
        
      ich bin auch SQL-Neuling. Deine Abfrage würde nicht das machen, was ich möchte, im Gegenteil. Sie würde nur dann ein Ergebnis erzielen, wenn der Eintrag auch wirklich der letzte wäre. Ich möchte aber den Eintrag zu einer bestimmten Bedingung zum letzten Eintrag machen, auch wenn er es eigentlich nicht ist.  
        
      Aber mein Ansatz ist ohnehin falsch, sorry.  
        
      Was ich eigentlich möchte, ist, dass ein bestimmter Eintrag vom User nicht in eine Reihenfolge mit bereits vorhandenen Einträgen gemacht werden kann.  
        
      Das sollte ich aber vielleicht anders lösen.  
        
      1) Entweder ID verschlüsseln und entschlüsseln (hier würde base64 ausreichen, weil es wirklich vergleichsweise Schnickschnack ist, was ich erreichen will. Es soll eben nur nicht auf den ersten Blick in eine Sortierreihenfolge mit vorhandenen Einträgen zu bringen sein. Wenn sich dann einer bemühen will, dann soll er doch.)  
        
      2) eine zusätzliche Spalte mit einer Art unique\_id anlegen, nach der die Einträge weiter behandelt werden (also select, update oder delete).  
        
      Oder hat einer einen noch simpleren oder besseren Vorschlag für mich?  
        
      Viele Grüße, Richard
      
      1. Mahlzeit Richi,

        Ich möchte aber den Eintrag zu einer bestimmten Bedingung zum letzten Eintrag machen, auch wenn er es eigentlich nicht ist.

        Aha - Du interpretierst also eine größere ID als "späterer Eintrag". Und genau das ist falsch. Ein rein technischer Primary Key hat erstmal überhaupt gar keine fachliche Bedeutung. Er dient lediglich zur Identifizierung eines Datensatzes.

        Wenn Du Deine Datensätze in irgendeine zeitliche Abfolge bringen willst, erweitere Deine Tabelle um eine TIMESTAMP-Spalte oder etwas ähnliches - je nach Deinen Anforderungen.

        Wenn die Datensätze frei sortierbar sein sollen, dann erweitere die Tabelle um eine Spalte mit einem sortierbaren Datentyp.

        MfG,
        EKKi

        --
        sh:( fo:| ch:? rl:( br:& n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
        1. Hi EKKI,

          Aha - Du interpretierst also eine größere ID als "späterer Eintrag". Und genau das ist falsch.

          Haha. (nett gemeintes Lachen), erwischt, denkst Du? Nein, ich habe eine timestamp-spalte, die die Datensätze in die zeitliche Abfolge bringt. Allerdings, wenn User weiß, dass die Spalte ID eine autoincremet-spaltist und er auch weiß, dass man den timestamp ausschließlich beim schreiben eines Datensatzes beeinflussen kann (nämlich durch Schreiben des Datensatzes), dann kann er über die ID schon auch eine zeitliche Einordnung vornehmen.

          Grundsätzlich hast Du natürlich recht. Es geht aber auch gar nicht um die Funktion, die ist ja gegeben (eben, weil ich die ID auschließlich(!) zur Identifizierung des Datensatzes benutze. Ist halt Pech, dass man ihr eine weitere Bedeutung bei bestimmten Vorwissen zuordnen kann.

          Wenn die Datensätze frei sortierbar sein sollen, dann erweitere die Tabelle um eine Spalte mit einem sortierbaren Datentyp.

          Es geht nicht um die Sortierbarkeit. Es geht darum, dass ich Einträge vorbereiten will, die für den User aber nicht vorbereitet aussehen sollen. Sprich, er sieht den Eintrag, der aber eine kleinere ID hat als aktuelle Einträge. Somit kann er schlussfolgern, dass dieser Eintrag nicht "just-in-time" geschreiben wurde, sondern bereits 1 oder 2 Tage zuvor vorbereitet wurde. Die ID sieht er ja bspw. im Link zum Eintrag, denn die ID identifiziert den Eintrag ja.

          Viele Grüße, Richard

          1. Lieber Richi,

            Dein ID-Wert als "int auto-increment" ist dann vielleicht nicht das, was Du aufgrund Deines Schönheitsfehlers willst. Warum keinen zufälligen Hash, dessen Vorhandensein in der DB vorher geprüft wird? Mit varchar(20) ließe sich da einiges anstellen...

            Liebe Grüße,

            Felix Riesterer.

            --
            ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
            1. Lieber Richi,

              Dein ID-Wert als "int auto-increment" ist dann vielleicht nicht das, was Du aufgrund Deines Schönheitsfehlers willst. Warum keinen zufälligen Hash, dessen Vorhandensein in der DB vorher geprüft wird? Mit varchar(20) ließe sich da einiges anstellen...

              Hi Felix,

              klar, der würde passen. Genauso könnte man vermutlich auch mit den mysql AES en- und decrypt Methoden arbeiten. Aber auch base64 auf die int-Spalte anwenden dürfte ausreichen.

              Viele Grüße, Richard

              1. Lieber Richi,

                Aber auch base64 auf die int-Spalte anwenden dürfte ausreichen.

                das klingt für mich nach blankem Unsinn.

                Vergiss nicht, Du willst einen vermeintlichen Schönheitsfehler operieren.

                Liebe Grüße,

                Felix Riesterer.

                --
                ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
          2. Hi,

            Es geht darum, dass ich Einträge vorbereiten will, die für den User aber nicht vorbereitet aussehen sollen. Sprich, er sieht den Eintrag, der aber eine kleinere ID hat als aktuelle Einträge. Somit kann er schlussfolgern, dass dieser Eintrag nicht "just-in-time" geschreiben wurde, sondern bereits 1 oder 2 Tage zuvor vorbereitet wurde.

            Und was genau ist daran das Problem?

            MfG ChrisB

            --
            RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
            1. Hi,

              Und was genau ist daran das Problem?

              Was meinst Du genau?

              Mfg, Richard

              1. Hi,

                Und was genau ist daran das Problem?

                Was meinst Du genau?

                Ich möchte wissen, welches Problem du tatsächlich glaubst lösen zu müssen, und warum.

                MfG ChrisB

                --
                RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                1. Lieber ChrisB,

                  Ich möchte wissen, welches Problem du tatsächlich glaubst lösen zu müssen, und warum.

                  er will vermeiden, dass beim User in der URL irgend etwas in der Form ?id=123 steht, weil dann der User anhand der Zahl ahnen könnte, ob die Info erst heute, oder schon übervorgestern eingestellt wurde. Im Grunde sucht er nach einer anderen Form der Indizierung als eben numerisch, damit da nicht mehr "123" steht, sondern etwas, das nicht nach auto-increment aussieht und somit obigen Rückschluss nicht mehr ermöglicht.

                  Liebe Grüße,

                  Felix Riesterer.

                  --
                  ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
                  1. Hi,

                    Ich möchte wissen, welches Problem du tatsächlich glaubst lösen zu müssen, und warum.

                    er will vermeiden, dass beim User in der URL irgend etwas in der Form ?id=123 steht,

                    Dass er das „will“, ist mir klar.

                    weil dann der User anhand der Zahl ahnen könnte, ob die Info erst heute, oder schon übervorgestern eingestellt wurde.

                    Was das Problem *daran* sein soll, ist für mich immer noch ungeklärt.

                    Im Grunde sucht er nach einer anderen Form der Indizierung als eben numerisch, damit da nicht mehr "123" steht, sondern etwas, das nicht nach auto-increment aussieht und somit obigen Rückschluss nicht mehr ermöglicht.

                    Dann soll er auf auto_increment verzichten, und sich stattdessen irgendeine Art von Unique-ID als identifizierendes Kennzeichen des Datensatzes selber reinbasteln.
                    Funktionen für das Erstellen einer solchen bietet MySQL ja schon an, http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html

                    MfG ChrisB

                    --
                    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                    1. Hi,

                      erstmal Danke an Felix fürs Erklären, was ich möchte.

                      Funktionen für das Erstellen einer solchen bietet MySQL ja schon an, http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html

                      Danke auch an Dich.

                      Richard

        2. Lieber EKKi,

          Wenn Du Deine Datensätze in irgendeine zeitliche Abfolge bringen willst, erweitere Deine Tabelle um eine TIMESTAMP-Spalte oder etwas ähnliches - je nach Deinen Anforderungen.

          Wenn die Datensätze frei sortierbar sein sollen, dann erweitere die Tabelle um eine Spalte mit einem sortierbaren Datentyp.

          Deine zweite Aussage beinhaltet im Grunde Deine erstere, denn Datumsangaben sind sortierbar. Oder habe ich da etwas falsch verstanden?

          Liebe Grüße,

          Felix Riesterer.

          --
          ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
          1. Moin!

            Wenn Du Deine Datensätze in irgendeine zeitliche Abfolge bringen willst, erweitere Deine Tabelle um eine TIMESTAMP-Spalte oder etwas ähnliches - je nach Deinen Anforderungen.

            Wenn die Datensätze frei sortierbar sein sollen, dann erweitere die Tabelle um eine Spalte mit einem sortierbaren Datentyp.

            Deine zweite Aussage beinhaltet im Grunde Deine erstere, denn Datumsangaben sind sortierbar. Oder habe ich da etwas falsch verstanden?

            Stimmt natürlich, aber mit "Datum" verbinden man eine zeitliche Verknüpfung eines Eintrags - und die ist in der Regel fest, sobald sie einmal gewählt wurde. Eine Sortierspalte hingegen ist einfach nur dafür da, die Reihenfolge flexibel festzulegen. Da ist keine weitere Bedeutung mit verbunden.

            - Sven Rautenberg

  2. Mahlzeit Richi,

    Prüfen, ob die ID des gefundenene Datensatzes (autoinrement) die höchste in der Tabelle ist.
    SELECT MAX(ID) FROM Tabelle, 0)

    Prüfen (in php), ob die zuvor gefundene ID höher oder gleich der Max-ID ist.

    Falls es nicht die höchste ID ist, dann Datensatz duplizieren und den mit der gefundenen ID stattdessen löschen.

    Welche fachliche Bedeutung hat hier die Spalte "ID" (ich schätze mal, das ist der Primary Key für diese Tabelle)? Man sollte dem Primary Key *NIEMALS* eine fachliche Bedeutung beimessen, die er nicht hat und nicht haben darf. Es handelt sich lediglich um ein eindeutiges Datum, mit dem man jeden Datensatz eindeutig identifizieren kann. Mehr darfst Du nicht hineininterpretieren.

    Also: was steht dort (in der Spalte "ID") implizit noch mit drin?

    Wenn Du dafür eine eigene Spalte anlegst, hast Du kein Problem mit dem unsinnigen "Umkopieren" von Datensätzen - weil Du es schlicht und ergreifend nicht mehr brauchst.

    1. Geht das nicht auch "schlanker"?

    Ja. Indem Du dem Primary Key keine fachliche Bedeutung beimisst und das Tabellendesign reparierst.

    1. Kann ich z.B. auch einfach die ID des gefundenen Datensatzes ändern? Obwohl die Spalte "autoincrement" ist? Macht das vielleicht gar nichts aus?

    Wieso solltest Du den Primary Key eines Datensatzes ändern wollen?

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:& n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Hallo EKKI,

      Welche fachliche Bedeutung hat hier die Spalte "ID" (ich schätze mal, das ist der Primary Key für diese Tabelle)?

      Ja, genau das ist er. Und eben der einzige wirkliche unique-wert für den Datensatz.

      Also: was steht dort (in der Spalte "ID") implizit noch mit drin?

      Nichts. :-) Einfach nur ein autoincrement-int-wert, den ich zum lesen, updaten und löschen des Datensatzes benötige.

      Wenn Du dafür eine eigene Spalte anlegst, hast Du kein Problem mit dem unsinnigen "Umkopieren" von Datensätzen - weil Du es schlicht und ergreifend nicht mehr brauchst.

      Siehe bitte auch http://forum.de.selfhtml.org/?t=206841&m=1404879

      Viele Grüße, Richard