Etwas komplexeres Löschen

Hi, und zwar überleg ich mir, ob ich Ohne java folgenden Lösche-Vorgang realisieren kann.


Ich habe eine Tabelle die Folgende Struktur hat:

create table ( 
objectid integer,
time integer,
stats_value integer
);

Es gibt ca. 1000 Objekte. Jedes Objekt erhält jede Minute einen Stats-Eintrag (d.h. einen Statistik-Wert für eine Minute).

bei 1000 Objekten sind das pro Stunde 1000*60=60.000 Einträge, d.h. nach 1h (60 minuten) sind das 60 Einträge pro Objekt.

Jetzt möchte ich alle Werte von allen Objekten entfernen, die über die aktuellen 60 Werte hinausragen.

Ich sehe aktuell dein Problem nicht.

Hast du das einfach mal ausprobiert?

Wenn konstant pro Minute ein Eintrag kommt, und Du nur 60 halten willst, dann kannst Du doch z.B. via einem Trigger beim Insert die löschen, die älter als 1 Stunde sind. Ich unterstelle mal, daß für time nicht ein INT verwendet wird, sondern ein Timestamp.

Oder hab ich da was flasch verstanden?

Andreas

time ist ein Integer (sekunden-unix-timestamp).

Im Peinzip könnte ich das machen, alle Einträge, die älter sind als 60 Minuten löschen. Sollte jedoch der Statistik zähler für 10 Minuten mal aussetzen möchte ich nicht ein “Loch” in der Statistik haben.

Daher möchte ich alle Werte von einem Objekt in eine Liste bringen, und die ältesten löschen.

Hier mal ein Index

1  | stats-wert
2  | stats-wert
3  | stats-wert
4  | stats-wert
5  | stats-wert
....
60| stats-wert
61| stats-wert
62| stats-wert

So, jetzt möchte ich 1 + 2 entfernen. D.h. die zuerst erstellt wurden entfernen.
Und das natürlich für alle Objekte.


Pseudocode, wie ich es mit java machen würde:

result = query(“select objectid from table group by objectid”);
for( $CURR_OBJECT_ID in results )
query(“delete from table where object_id in (select objectid from table where object_id=$CURR_OBJECT_ID order by created ASC offset 60)”

Wieder ein Trigger, der aber sowas wie folgt ausführt:

die Tabelle:

test=*# select * from objekte ;
 id | time
----+------
  1 |    2
  1 |    3
  1 |    4
  1 |    5
  1 |    6
  2 |    1
  2 |    2
  2 |    3
  3 |    1
(9 rows)
[code]

Du willst aber pro id nur max. 5, also ein Trigger beim Einfügen:
(Du fügst einen neuen mit ID=1 ein)

[code]
test=# delete from objekte where (id,time) in (select * from objekte where id=1 order by time desc offset 5);
DELETE 1

Andreas

Ah okay perfekt. Besten Dank. Werd das dann mit Trigger lösen. Hört sich vernünftig an. super Sache!

Pass aber auf, das du diesen Trigger nicht bei jedem der Tausend Objekte feuerst. Das dürfte dich mehr Performance kosten als alles andere, was deine Anwendungen ausführen.

Guter Einwand. Man sollte vielleicht prüfen, ob das wirklich so notwendig ist oder ob es nicht vielleicht besser wäre, das Löschen zyklisch via CRON durchzuführen. Vielleicht gibt es ja auch lastarme Zeiten für sowas. Die Anzahl von 60.000 Zeilen ist für PG vernachlässigbar, aber der Aufwand für das Löschen ist doch relativ hoch.

Andreas

Jep wirklich guter einwand. werde das doch per externes Programm durchführen, da meine Datenbank sowieso performance ohne Ende braucht.

Danke für den Hinweis!