auch von mir der hinweis, mach das so wie himitsu vorschlägt. Wir machen das mit firebird
in der aktuell größten
DB mit 6.5 TB ähnlich, der eigentliche Blobinhalt ist eine eigene
Tabelle, die nur aus einer eigene ID als PK besteht und dem Blob Inhalt.
Alle Tabellen, die Daten dazu in anderen Feldern haben, nehmen für den referenzierten Inhalt
nur ein typengleichen feld als Foreign key, der die daten verbindet.
Bei kleinen Blobs lohnt sich das zwar eher selten, aber auf dem weg kannst du lokal
einen beliebigen Select auf den restlichen Daten machen und zum Beispiel im Front
end erst dann die daten in die Blob control TIMage oder sonstwas holen, wenn der
Anwender zum Beispiel im Grid auf einem Datensatz stehen geblieben ist, zB dann
per onnavigate event einen timer resetten und wenn der timer zB 500ms ohne reset
erreicht hat, dann mit extra
query den blob inhalt holen (und falls das riesige dateien
sind wie röntgenbilder o.ä. dieser sogar temporär lokal cachen wenn die sich eh nicht
ständig ändern, zB als 12345.png in einem lokalen pfad, den du beim programmstart
oder ende ggf selber lokal aufräumst).
wir nutzen das verfahren dann auch noch dafür, das wir die eigentlichen blobs dann
je nach nummernkreis oder erstelldatum in firebird dann auch noch in extra datenbanken
zu packen, die dann nur noch readonly gebraucht werden als jahresarchiv.
bei firebird holt man sich dann eben je nach logik bei bedarf den blob aus einer
dieser datenbanken, wo man laut regel vermutet wo der inhalt wohl sein könnte, zB
anhand von einem Timestamp in deiner anderen Tabelle in der Main Database.
Warum
mssql die blobs komplett lädt, auch wenn die spalte dafür gar nicht teil vom
select ist, frag ich mich aber trotzdem. Macht firebird zum beispiel selbst dann
nicht, wenn die blob spalte abgefragt wird, technisch bekommt man dabei nämlich nur
einen kleinen teil vom blob zum client übertragen (bei kleinen blobs das was eh schon
davon in der Datenpage ist und für den rest falls bedarf besteht den eigentlich blob
pointer, der anzeigt wor es weiter geht, und um den rest zu bekommen, müsste
der client entweder selber den kompletten inhalt per
api abfragen oder man zum Beispiel
durch eine serverseitige funktion dafür sorgen, das die wirklich komplett gelesen
werden muss (wie im Beispiel durch den char_length funktion).
Der fetch all sorgte hier bei
fb in ibexpert für die folgende page loads in der
tabelle mit 136000 blobs
Code:
select files.id, files.txt, files.removed, files.fn from files
=
Reads from disk to cache = 4.139
select files.id, files.txt, files.dat, files.removed, files.fn from files
=
Reads from disk to cache = 4.139
select files.id, files.txt, char_length(files.dat), files.removed, files.fn from files
=
Reads from disk to cache = 50.804
Wenn
mssql das aber immer ungefragt mitlädt wäre da die lösung ebenfalls, den blob
in eine andere tabelle auszulagern.