SELECT und DELETE in einem
Markus Hauptmann
- datenbank
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
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:
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
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
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
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
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:
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
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
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