Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Tabellengröße begrenzen (https://www.delphipraxis.net/140586-tabellengroesse-begrenzen.html)

himitsu 21. Sep 2009 17:20

Datenbank: MySQL • Version: 5 • Zugriff über: ja ähhh

Tabellengröße begrenzen
 
Moin Moin,

wie kann man möglichst "effizient" (mit wenigen Abfragen) die "Größe" einer Tabelle begrenzen?


Also es gibt da neben anderen Feldern ein "Time" (TIMESTAMP) und ein "Size" (INT), welches nochmal die Datenmenge in einem anderem Feld angibt.
Und ich möchte die Tabelle auf eine maximale Größe begrenzen, "Sum(Size)" oder so,
also die jeweils ältesten Einträge löschen, sobald die Größe überschritten wird.


Über die Anzahl der Einträge bekomm ich's hin,
aber jetzt alles auszulesen, nach Alter zu sortieren, die Einträge zusammenzurechen, bis der Grenzwert erreicht ist und über das Alter des "letzen" Eintrags dann alles Ältere zu löschen, wäre nicht grad "optiomal". :freak:


(im Notfall muß ich halt die Anzahl und nicht die "Größe" begrenzen)

hoika 21. Sep 2009 17:41

Re: Tabellengröße begrenzen
 
Hallo,

das geht nicht so einfach, wenn man z.B. VarChar hat.
Aber die maximale Record-Groesse muesstest du doch bestimmen können,
wenn du deine Datenstruktur kennst.

Das Ermitteln der ältesten Records hängt ja auch von deiner Struktur ab
(ich habe hier immer ein ID AUTOINC).

Unter Firebird wäre das dann etwa so

SQL-Code:
Delete From Table_X Tab1
Where Tab1.Id in
  (Select First 100 Tab2.Id From Table_X Tab2
   Order By Tab2.Id)
Die Zahl 100 musst du nat. berechnen.

Sollte das Subselect zu langsam sein, nimm eine SP.


Heiko

himitsu 21. Sep 2009 19:55

Re: Tabellengröße begrenzen
 
Code:
[b]Tabelle "Cache"[/b]
Name VARCHAR(31) UNIQUE KEY
Time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
Size INT
Data TEXT
Hash CHAR(32)
Size entspricht sozusagen Length(Data)

wenn ich z.B. diese Daten in der Tabelle hab (Datum/Zeit vereinfacht)
> schon nach Datum sortiert, da das Neuste ja immer angehängt wird
Code:
Name Time Size ...
A   1°°   123  ...
B   2°°   345  ...
C   3°°   234  ...
D   4°°   111  ...
E   5°°   432  ...
F   6°°   789  ...
G   7°°   333  ...
H   8°°   123  ...
und die Größe auf 2000 begrenzen möchte

Alles = 2490
H bis C = 2022
H bis D = 1788

Also müßte hier A-C gelöscht werden, damit die Größe wieder unter die 2000 kommt

also von unten her alles drin lassen, bis die Summe der Size-Felder die Grenze erreicht und ab da den Rest löschen.


[add]
mir fällt grad ein, ich könnte, falls es so nicht geht,
mit einem Durchschnitt rechnen :gruebel:
Sum(Size) / Count(*) = Durchschnittliche größe der Einträge
Sum(Size) - Grenze = was zuviel ist
(Sum(Size) - Grenze) / (Sum(Size) / Count(*)) wäre dann doch die Anzahl der zu löschenden Einträge
also nach aufsteigend nach Datum sortieren und die ersten X Datensätze löschen

ich glaub ich versuch's erstmal so, auch wenn so die größe mal überschritten werden kann, falls sich keine Lösung findet

himitsu 22. Sep 2009 12:57

Re: Tabellengröße begrenzen
 
So, bis/falls sich doch noch eine "ordentliche" Lösung findet, hab ich es quasi erstmal so
Code:
Query("SELECT COUNT(*) AS RowCount, SUM(Size) AS FullSize FROM Cache");
$Count = ceil(($FullSize - MAXIMUM) / ($FullSize / $RowCount));
Query("DELETE FROM Cache ORDER BY Time ASC LIMIT $Count");
Aber bekommt man das jetzt auch irgendwie noch in eine einzelne Query rein?
[add]
eventuell auch gleich noch kombiniert damit
Code:
DELETE FROM Cache WHERE Time < $Time

so geht es ja leider nicht, da hier immer nur der kleiner Wert "WHERE Time < $Time" bzw. "LIMIT $Count" angewendet wird, aber nicht die jeweils größere Anzahl an Löschungen.
Code:
Query("DELETE FROM Cache WHERE Time < $Time ORDER BY Time ASC LIMIT $Count");

oh man, kein Wunder, daß ich's nicht so mit Datenbanken hab ... ich dreh hier noch bald durch :freak:

p80286 22. Sep 2009 13:54

Re: Tabellengröße begrenzen
 
Hallo Himitsu,

da ich aus der Oracle-ecke komme weiß ich nicht ob Du es so umsetzen kannst:

ich würde eine Funktion definieren
SQL-Code:
Is_Size_toolarge
und diese dann in einer Löschprocedure verwenden, etwa so
SQL-Code:
While IS_SIZE_TOOLARGE do
   DELETE_OLDEST_CASE
Die Größenermittling und die Löschung hast Du ja schon definiert.
für den Benutzer gibt es dann nur noch einen Befehl und das wäre doch in Deinem Sinne.

Gruß
K-H

himitsu 22. Sep 2009 15:01

Re: Tabellengröße begrenzen
 
Von Funktionen direkt in der DP hab ich garkeine Ahnung

und diese Schleife im Programm auszuführen wäre etwas viel Overload,
denn ich wollte mir mit dieser Cache ein paar DB-Zugriffe und andere Berechnungen sparen
und da würde es doch den "Gewinn" durch eine schlechte Cacheverwaltung verringern oder gar alles noch verschlimmern, wenn ich da massenhaft Abfragen ausführe.

p80286 22. Sep 2009 16:06

Re: Tabellengröße begrenzen
 
Ahh Sooooo,

ich hatte mich schon gewundert, warum Du eine Tabellengröße begrenzen willst.
Auf der anderen Seite eine Zweierpotenz rauf oder runter macht den Kohl auch nicht fett, darum ist's ja eine Datenbank (es soll da allerdings ein IBM-Produkt geben das sich auch DB schimpft, das bei 100k-Datensätzen etwas kurzamig wird / nein nicht DB2)

Gruß
K-H

alzaimar 22. Sep 2009 17:46

Re: Tabellengröße begrenzen
 
Wir machen das immer über eine 'Timestamp'-Spalte, in der der Zeitpunkt der Erstellung des Datensatzes steht. Dann definieren wir willkürlich (oder Kundenvorgabe) die maximale Lebensdauer unserer Daten und schnippen 'zwischendurch' (1-1000x pro Tag) alle Daten weg, die zu alt sind.

Damit haben wir zwar nicht aufs Byte genau eine maximale Größe, aber weniger Arbeit, sind sofort fertig und haben zudem noch eine definierte Aussage über die Qualität (max. Alter). Das geht bei dem größenbasierten Ansatz nicht. Performanceprobleme haben wir auch nicht, weil wir das periodische Löschen bei extrem hohem Datenaufkommen einfach öfter ausführen:
SQL-Code:
Delete From Tabelle Where DatumDerErstellung < Jetzt() - MaximalesAlterInTagen
So in dem Dreh.

himitsu 22. Sep 2009 18:10

Re: Tabellengröße begrenzen
 
Das mit dem Alter ist auch schon drinnen, aber ich hab mir meine Cache, also die Klasse so erstellt, daß sie im Dateisystem oder in der DB speichern kann und im Dateisystem war mir die Größe wichtiger.

Und da ich beides über die gleichen Parameter verwalten wollte, hab ich nun 2 Größen drin
- maximales Alter
- maximaler Speicher

Auf's Byte genau hab ich's nun nicht, aber ich glaub ich kann damit leben :angel2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:48 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz