Markus Hauptmann: SELECT und DELETE in einem

Hallöle ihr!

Ich arbeite derzeit an einem Projekt bei dem ich MySQL als Datenbank verwende. Es läuft alles so weit ganz gut nur stehe ich bei einer Tabelle vor einem mehr oder weniger großen Problem. In dieser einen Tabelle habe ich einen sehr hohen Datendurchsatz. Es werden zeitweise mehrere Datensätze pro Sekunde eingefügt. Diese Datensätze werden allerdings auch wieder ausgelesen und sofort darauf gelöscht. Es sind also quasi "Einweg-Datensätze", die nur einmal geschrieben und danach sofort ausgelesen und wieder gelöscht werden. Diese Tabelle besitzt aber nun wiederum nur zwei Felder, um den Datendurchsatz und die Belastung auf dem absoluten Minimum zu halten. Es ist kein Feld mit einer ID oder ähnlichem vorhanden um einen Datensatz eindeutig identifizieren zu können. Ich möchte nun einen SELECT ausführen und Datensätze die bestimmte Bedingungen erfüllen auslesen. Damit diese Datensätze dann aber kein zweites Mal ausgelesen werden können müssen diese nach dem SELECT gelöscht werden.
Bisher habe ich es so gehandhabt, dass ich unmittelbar nach dem SELECT ein DELETE mit den gleichen WHERE-Bedingungen ausführe, allerdings kann es passieren, dass zwischen dem SELECT und dem DELETE ein neuer Datensatz eingefügt wird, der von dem SELECT noch nicht ausgeliefert wurde aber durch die gleiche WHERE-Bedingung beim DELETE mit gelöscht wird. Der Datensatz wird also "verschluckt".
Nun meine eigentliche Frage: Gibt es irgendwie die Möglichkeit Datensätze auszulesen und gleichzeitig zu löschen? Oder die ausgelesenen Datensätze zu "markieren" um die in Folge zu löschen?
Oder hätte irgendjemand eine alternative Idee wie ich das Problem lösen könnte?
Danke euch.

Grüße,
Markus

  1. Halihallo Markus

    Nun meine eigentliche Frage: Gibt es irgendwie die Möglichkeit Datensätze auszulesen und gleichzeitig zu löschen? Oder die ausgelesenen Datensätze zu "markieren" um die in Folge zu löschen?

    Ohne Primary Key und Table-Lock nicht. Die einfachste Lösung demnach wäre, wenn du
    einen Primary Key mit autoinc einführst. Der Selekt liefert dir die Daten + Primary Key,
    den Primary kannst du beim nachfolgenden DELETE verwenden, um wirklich ausschliesslich
    die selektieren Datensätze (auch wenn andere auf die "alte" WHERE passen) zu löschen.

    DELETE FROM table WHERE ID IN (previously-selected-primary-keys)

    Oder hätte irgendjemand eine alternative Idee wie ich das Problem lösen könnte?

    Es gäbe mehrere Ansätze:

    1. die zuvor vorgestellte PRIMARY KEY-Methode. Problem hier: Primary Key impliziert
         Unique Index und bei derart temporären Daten drückt das auf die Performance.
    2. vor dem SELECT bis nach dem DELETE ein TABLE LOCK, sodass andere Prozesse auf die
         Tabelle während dieser Aktion nicht mehr schreiben zugreifen können. Somit wäre der
         SELECT/DELETE atomar, was soviel bedeutet, dass du keine Datensätze löschst, die nicht
         zuvor selektiert wurden. Problem hier: Performance, Verzögerung bei Schreibzugriffen.
    3. Du findest dennoch eine Möglichkeit diese Datensätze eineindeutig anzusprechen
         (wie mit ID, Primary Key), sodass die WHERE von SELECT und DELETE dieselben Datensätze
         ansprechen.
    4. Arbeiten mit Connection-Based-Temporary-Tables, die HEAP-Tables. Nachteil: Das
         schreiben und auslesen müsste im selben Prozess (oder gar der selben Connection)
         möglich sein. Ich weiss nicht, ob dies von der Aufgabenstellung her möglich ist.

    Das Problem ist schlicht: Um dieselben Daten über SELECT und DELETE zu verarbeiten,
    _musst_ du sie eindeutig ansprechen können. Die vorgeschlagenen Methoden von oben
    garantieren dies (bei richtiger Umsetzung natürlich ;-)). Ohne eineindeutige
    Identifikation der Datensätze _muss_ man in diesem Kontext mit Datenverlust rechnen.

    Viele Grüsse

    Philipp

    --
    RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
    Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
  2. Hallo Markus,

    soweit ich informiert bin, sollte es in einer Tabelle NIE zwei gleiche Datensätze geben. Ein Datensatz sollte immer einen eindeutigen Schlüssel haben, und sei er aus hundert Feldern zusammengesetzt.

    Gruß, Andreas

    1. Halihallo Andreas

      soweit ich informiert bin, sollte es in einer Tabelle NIE zwei gleiche Datensätze geben.

      Doch, eben genau in einer Tabelle ist das erlaubt. In einer Relation aber nicht. Leider
      spricht Markus von einer Tabelle, dessen Datensätze nicht eindeutig identifizierbar sind.

      Ein Datensatz sollte immer einen eindeutigen Schlüssel haben, und sei er aus hundert Feldern zusammengesetzt.

      Normalerweise stimmt das, ja. Aber Tabellen haben oftmals Vorteile gegenüber Relationen
      und sei es nur der Performanceverlust beim aktualisieren des PRIMARY-Indexes.

      @Markus: Wenn du uns etwas mehr Background-Wissen gibst, kommt dem einen oder anderen
      vielleicht noch eine viel bessere Möglichkeit in den Sinn. Aufgrund der vorliegenden
      Daten kann ich zumindest nicht mehr beitragen.

      Viele Grüsse

      Philipp

      --
      RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
      Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
      1. HalloHalli,

        soweit ich informiert bin, sollte es in einer Tabelle NIE zwei gleiche Datensätze geben.
        Doch, eben genau in einer Tabelle ist das erlaubt.

        wenn es nur _diese eine_ Tabelle gibt oder was? aber wozu soll das gut sein? mal abgesehen von der beschriebenen Anwendung, die MudGuard ja schon hinterfragt hat.

        In einer Relation aber nicht.

        das heißt: zwei gleiche Datensätze in EINER Tabelle, wenn diese Tabelle eine Verknüpfung mit einer anderen Tabelle hat?

        Leider spricht Markus von einer Tabelle, dessen Datensätze nicht eindeutig identifizierbar sind.

        ...weil zwei Datensätze gleich sind...

        Gruß, Andreas

        1. Halihallo Andreas

          soweit ich informiert bin, sollte es in einer Tabelle NIE zwei gleiche Datensätze geben.
          Doch, eben genau in einer Tabelle ist das erlaubt.
          wenn es nur _diese eine_ Tabelle gibt oder was? aber wozu soll das gut sein? mal abgesehen von der beschriebenen Anwendung, die MudGuard ja schon hinterfragt hat.

          Nein, nicht nur _diese eine_, es können in einer Datenbank auch mehrere Tabellen
          vorkommen. Es gibt gewisse Anwendungsfälle, wo eine "normale Tabelle" die bessere Wahl
          ist, als eine Relation. Nehmen wir z.B. diverse Messwerte aus einem Versuch. Es gibt
          meistens nur unterschiedliche Messwerte, aber es kann vorkommen, dass einmal genau
          dasselbe gemessen wird. Warum also künstlich einen Primary Key einführen, wenn man eh
          nur auswertend (Agregatsfunktionen mit GROUP BY) darauf zugreift? - Einen Primary Key
          braucht man hier nicht, er würde nur auf die Performance drücken.

          In einer Relation aber nicht.
          das heißt: zwei gleiche Datensätze in EINER Tabelle, wenn diese Tabelle eine Verknüpfung mit einer anderen Tabelle hat?

          Jede Relation ist eine Tabelle, spezialisiert durch zwei Eigenschaften:

          1. jede Relation hat einen PRIMARY KEY
          2. eine Relation kann einen oder mehrere optinale FOREIGN KEYs haben

          Durch Eigenschaft Nummero 1 wird ausgeschlossen, dass zwei Datensätze genau dieselben
          Daten enthalten (denn damit wäre mindestens die Definition des PRIMARY KEYs verletzt).

          Folglich: In einer Relation ist per Definition jeder Datensatz eineindeutig ansprechbar,
          in einer Tabelle muss dies nicht zwingend zutreffend sein.

          Leider spricht Markus von einer Tabelle, dessen Datensätze nicht eindeutig identifizierbar sind.
          ...weil zwei Datensätze gleich sind...

          Ganz genau.

          Viele Grüsse

          Philipp

          --
          RTFM! - Foren steigern das Aufkommen von Redundanz im Internet, danke für das lesen der Manuals.
          Selbstbedienung! - Das SelfForum ist ein Gratis-Restaurant mit Selbstbedienung, Menüangebot steht in den </faq/> und dem </archiv/>.
  3. Hi,

    ist es denn überhaupt notwendig, die Daten erst in die Datenbank zu schreiben?

    Wozu soll das ganze dienen? Mit etwas mehr Hintergrund ergibt sich vielleicht eine bessere Lösung...

    cu,
    Andreas

    --
    Der Optimist: Das Glas  ist halbvoll.  - Der Pessimist: Das Glas ist halbleer. - Der Ingenieur: Das Glas ist doppelt so groß wie nötig.
    http://mud-guard.de/? http://www.andreas-waechter.de/ http://www.helpers.de/
  4. hi,

    In dieser einen Tabelle habe ich einen sehr hohen Datendurchsatz. Es werden zeitweise mehrere Datensätze pro Sekunde eingefügt. Diese Datensätze werden allerdings auch wieder ausgelesen und sofort darauf gelöscht. Es sind also quasi "Einweg-Datensätze", die nur einmal geschrieben und danach sofort ausgelesen und wieder gelöscht werden.

    wie schon angedeutet wurde, das konzept klingt reichlich komisch.

    wäre es nicht z.b. denkbar, diese temporären daten über sessions zu verwalten?

    gib doch mal ein paar mehr informationen, warum du das so machst.

    gruss,
    wahsaga