SQL Anhänge in Datenbank speichern oder nicht?

CPU

Lieutenant
Registriert
Jan. 2006
Beiträge
704
Hallo Community,

um es vorab zu sagen: verwand mit meiner Frage ist ja die Frage, ob man Bilder in der Datenbank speichern soll und dann mit PHP "streamen" soll oder lieber im Dateisystem. Hier gibt es Vor- und Nachteile, die in diesem Artikel relativ gut beschrieben sind!

Mein Problem liegt aber etwas anders!

Bisher gibt es eine Datenbank, die Daten zu einem Einträg hält, und drei Netzlaufwerke, auf denen jeweils ein Ordner für jeden Eintrag (also mit ID als Ordnername) aus der Datenbank liegt und darin liegen ein Paar Worddokumente, Excel-Mappen, PDF-Dokumente und Bilder (c.a. <30 MB/p.a. 900 MB). Das die "Anhänge" zu diesen Daten in der Datenbank auf drei Netzlaufwerken verteilt liegen hat Berechtigungsgründe (nicht jeder darf auf alle drei Zugreifen, manche nur auf zwei und manche nur auf eines).

Das habe ich vor: nun einfach die Dokumente in der Datenbank zu speichern. Die Abfrage findet dann mit Java folgendermaßen statt: Java fragt - wenn der Benutzer auf der Eigenschaftsseite der Dokumente ist - eine Dokumentenliste ab (nur Dateinamen). Wenn ein Nutzer doppelt auf ein Dokument klickt, wird es ins temporäre Verzeichnis geladen, der Nutzer ändert und dann schließt der Nutzer das Dokument und wenn Änderungen vorgenommen wurden (z.B. Vergleich altes Änderungsdatum vs. neues Änderungsdatum o.ä.), dann fragt er den Benutzer, ob das Dokument in der Datenbank aktualisiert werden soll.

Vorteile:
bessere Verbindung zwischen Daten und Dateien, bessere und einfacherere Berechtigungen möglich, Berechtigungen können mit einem Mal gesetzt werden (nicht einzeln für Daten und Dateien) = erhöhter Sicherheit

Da ich mit BLOBs noch nicht so oft gearbeitet habe (mit Java Bilder in die DB schreiben und wieder lesen ist echt einfach), weiß ich nicht wie sich die Datenbank verhält.

1.) Wie verhält sich mein Vorhaben performancetechnisch im lokalen Netzwerk? Muss der Rechner, auf dem die MySQL-Datenbank läuft "kräftig" sein (bei ca. 10 Benutzern, die damit arbeiten)?

2.) Was passiert, wenn die Gesamtdatenmenge in der Datenbank wächst (eigentlich liegen 90% der Dokumente ja nur "in" der Datenbank, mit 10% wird ja ständig gearbeitet. Wie wirkt sich das aus?)?

3.) Wie ist das mit der Datei-Sicherheit (also nicht Diebstahlschutz)? Klar werden regelmäßig Datenbank-Backups gemacht. Doch ist die Datenbank dann anfälliger für Probleme? Geht sie schneller "kaputt"? Ist es irgendwie nachteiliger als wenn ich Daten in DB und Dateien in FS habe?

4.) Wie verhalten sich die Übertragungsgeschwindigkeiten im lokalen Netzwerk (10/100)? Gibt es da irgendwelche grawierdenden Nachteile?


So, das wär's erstmal. Eigentlich finde ich die Idee mit der Datenbank garnicht schlecht. Weil sonst eben die Verknüpfung von (Meta-)Daten und Dateien nur über eine Pfadangabe läuft und man dann Probleme hat, wenn die Berechtigungen anstendig (und auch einfach) gesetzt werden sollen oder wenn man den Windows-Explorer öffnen muss aus Java mit der Pfad-Angabe (Problem, wenn sich der Laufwerksbuchstabe ändert etc.). Irgendwie ist das sehr "unsauber" und kann viele Probleme verursachen.

Viele Grüße,
CPU
 
Wie verhält sich mein Vorhaben performancetechnisch im lokalen Netzwerk? Muss der Rechner, auf dem die MySQL-Datenbank läuft "kräftig" sein (bei ca. 10 Benutzern, die damit arbeiten)?
Ich rate mal in's blaue rein: das kommt auf die Dateigröße, bzw. Datenmenge an, mit welcher du arbeitest.

Wenn du die Daten einmal rausholst und auf dem Client zwischenspeicherst, solltest du damit keine Probleme haben.

Was passiert, wenn die Gesamtdatenmenge in der Datenbank wächst
Was erwartest du denn, was dann passiert? Viel dürfte es nicht sein - sofern du kein SELECT * FROM `table`; machst und alle Datensätze ausliest.

Gibt es da irgendwelche grawierdenden Nachteile?
Ich denke eher nicht. Ausser natürlich, dass du vorher 3 Slaves hattest (also 3*100MBit) und jetzt ggf. mit 1*100MBit auskommen musst.

Als kleine Anregung: hast du dir vorher mal überlegt, wieviel Datenmengen das sind, die so über's Netz gehen? Werden die Dateien oft gelesen/geschrieben? Sind es große Dateien?
Oder werden da einmal zu Arbeitsbeginn 5 MB ausgelesen und zum Arbeitsende 6 MB geschrieben?
 
Ich würde dir vorschlagen, dass du die Dokumente auf _einer_ Festplatte lagerst, und wenn jemand drauf zugreifen will ne Kopie in ein Netzwerklaufwerk machst, wo nur der betreffende Benutzer Rechte drauf hat.
 
Also ungefähr so?
- User U sieht Datei D
- Rechner kopiert Datei D auf Netzlaufwerk N
- U bekommt Fehlermeldung angezeigt, dass D auf Grund eines Rechteproblems ("Sie dürfen hier nicht zugreifen") nicht nach N kopiert werden konnte
- U ruft Admin A an und fragt, warum er keine Rechte hat dort was hinzukopieren - er wollte doch D gar nicht nach N kopieren sondern öffnen
- A erklärt lang und breit, dass U keine Rechte hat, D zu öffnen

?

Ich verstehe gerade den Sinn nicht ganz, dem User eine Datei anzubieten und diese dann (obwohl er keine Rechte hat) erstmal auf ein Netzlaufwerk kopieren zu wollen, auf das er keinen Zugriff hat.
 
Erstmal: vielen Dank für die Antworten! :)

IceMatrix schrieb:
Ich würde dir vorschlagen, dass du die Dokumente auf _einer_ Festplatte lagerst, und wenn jemand drauf zugreifen will ne Kopie in ein Netzwerklaufwerk machst, wo nur der betreffende Benutzer Rechte drauf hat.
Ja, aber: dann bin ich den Ganzen Tag am Laufen mit der Festplatte und muss die Rechte einkonfigurieren. So mit der Datenbank füge ich den Benutzer einmal meiner Anwendung hinzu und dann hat er die bestimmten Rechte und kann so über die Datenbank die Dateien problemlos bearbeiten oder nicht!

voodoo44 schrieb:
Ich denke eher nicht. Ausser natürlich, dass du vorher 3 Slaves hattest (also 3*100MBit) und jetzt ggf. mit 1*100MBit auskommen musst.
Oh, nein! Es gibt eine alte Kiste (Baujahr 2000), auf der Ubuntu mit Samba läuft. Und in Samba gibt es drei Shares, um eben die drei Berechtigungsstufen abzubilden (Chef darf alle drei Laufwerke sehen, einfacher Mitarbeiter nur zwei und Praktikant nur eins). Und dieser Samba-Server ist verbunden über ein 10/100-MBit Netzwerk mit 6 Client Rechnern (nicht 10!).

voodoo44 schrieb:
Ich rate mal in's blaue rein: das kommt auf die Dateigröße, bzw. Datenmenge an, mit welcher du arbeitest.
Kein Ahnung. Es werden Worddokumente produziert und PDF's Produziert (sehr selten größer 1 MB) und auf dem Netzlaufwerk abgelegt.

Ich will das ja in die MySQL-Datenbank packen (um die Berechtiungen schöner abzubilden und um die Dateien mit den Daten synchron zu halten).

Außerdem will ich dann die alte Ubuntu-Gurke ersetzen durch eine Buffalo Link Station Duo. Da das Ubuntu ja nur als Fileserver genutzt wird reicht auch so ein NAS aus, da das auch viel weniger Potential hat, um Probleme zu verursachen! Und auf dem läuft eben MySQL.

Noch ne' Frage: Kennt jemand das "Buffalo Link Station Duo" NAS? Wie ist der MySQL-Server? Die Ressourcefragen zielten hier hin: kann ich das auf diesem Gerät betreiben (also die Dateien in DB speichern), ohne dass mir das Ganze Ding abschmiert?

Und noch ne' Frage: also ihr glaubt schon, dass das eine Alternative zu dem Dateisystembasierten-Ansatz ist, oder?

Ich habe mal folgendes gemacht: MySQL gedownloaded, auf einer externen Festplatte entpackt, nach XAMPP "huge.ini" konfiguriert und dann mal 12 GB Bilder reinschreiben lassen. Während des Vorgangs habe ich dann mal ein Paar Selects gefahren und so, aber performancetechnisch war da nichts zu meckern. Und auch das Laden aus der Datenbank ging so (lokal) in 1 Sekunde von der Hand ...

Muss ich noch irgendetwas bei der Wahl der Engine beachten? Ich habe InnoDB (=Standard)?

Beste Grüße,
CPU
 
Mal eine (relativ dumme) Frage:
Hat das einen Grund, dass dort WORD-Dokumente erzeugt werden? Das klingt für mich eher so, als könne man für diese Sachen (PDF-Erstellung) auch mit diversen epub/docbook-Formaten arbeiten und dafür XML-Editoren nutzen - das lässt sich sogar noch viel schöner abbilden als olle Word-Dokumente (Frau ist technische Redakteurin, darum kam mir das grad so in den Sinn) -- dafür gibt es dann auch schon fertige "Serversoftware", die man nur mehr installieren müsste, an den Clients einrichte und fertig.

Ansonsten: Probier es doch einfach aus - dumpe dir ein paar Bilder, Wod-Dokumente etc. in eine MySQL-DB und dann lass ein paar Reads und Writes drüberlaufen.
Denk aber dran, dass ab dann allein du für RACE-Conditions etc. verantwortlich bist - das nimmt dir nicht mehr das FS/Word ab.
Persönlich würde ich eher beim Filesystem bleiben - alle Dateien in einen Share und in der DB speichern, welcher User in welchen Ordner schreiben darf.
Alternativ: Schonmal drüber nachgedacht, einfach ein SVN zu "missbrauchen"? Oder einen Sharepoint-Server aufzusetzen?

Bezüglich der Engine:
Steht dir das hier nicht an? http://www.kavoir.com/2009/09/mysql-engines-innodb-vs-myisam-a-comparison-of-pros-and-cons.html ;)
 
Hallo,

voodoo44 schrieb:
Mal eine (relativ dumme) Frage:
Hat das einen Grund, dass dort WORD-Dokumente erzeugt werden? Das klingt für mich eher so, als könne man für diese Sachen (PDF-Erstellung) auch mit diversen epub/docbook-Formaten arbeiten und dafür XML-Editoren nutzen - das lässt sich sogar noch viel schöner abbilden als olle Word-Dokumente (Frau ist technische Redakteurin, darum kam mir das grad so in den Sinn) -- dafür gibt es dann auch schon fertige "Serversoftware", die man nur mehr installieren müsste, an den Clients einrichte und fertig.
Das ist ein ganz normaler Betrieb, wo eben Rechnungen, Angebote etc geschrieben werden. Und das mit den Word-, PDF-Dokumen u.a. ist nicht meine Baustelle!

voodoo44 schrieb:
Ansonsten: Probier es doch einfach aus - dumpe dir ein paar Bilder, Wod-Dokumente etc. in eine MySQL-DB und dann lass ein paar Reads und Writes drüberlaufen.
Denk aber dran, dass ab dann allein du für RACE-Conditions etc. verantwortlich bist - das nimmt dir nicht mehr das FS/Word ab.
Also mit "RACE-Conditions" sind gleichzeitige Zugriffe auf die Datei gemeint? Aber InnoDB "implements row-level lock for inserting and updating" (Quelle: hier)!

voodoo44 schrieb:
Persönlich würde ich eher beim Filesystem bleiben - alle Dateien in einen Share und in der DB speichern, welcher User in welchen Ordner schreiben darf.
Was nützt den das, wenn in der DB steht, wer wo lesen und schreiben darf? Jeder Client muss sich ja dann per SMB verbinden und anmelden und das hat ja nichts mit der Datenbank zu tun.

voodoo44 schrieb:
Alternativ: Schonmal drüber nachgedacht, einfach ein SVN zu "missbrauchen"? Oder einen Sharepoint-Server aufzusetzen?
Am Ende soll eben so eine NAS-Kiste raus kommen! Und es soll so einfach wie möglich sein.

Also sind das jetzt berechtigte Bedenken? Irgendwie habe ich jetzt ein komisches Gefühl. So toll ich die Idee auch finde (und so toll sie vorallem die Architektur aufwertet).



Gruß,
CPU
 
Also mit "RACE-Conditions" sind gleichzeitige Zugriffe auf die Datei gemeint?
Ja, unter anderem. Die Frage ist, wie lange du den Datensatz sperren willst. Erstmal muss er ausgelesen werden - wenn du ihn ab da sperrst, kann kein anderer den Datensatz auslesen und bearbeiten. Das ist sowohl gut als auch schlecht ...

Was nützt den das, wenn in der DB steht, wer wo lesen und schreiben darf? Jeder Client muss sich ja dann per SMB verbinden und anmelden und das hat ja nichts mit der Datenbank zu tun.
Wenn du einen eigenen Client entwickelst, dann kannst du über diesen auch die Files auf den Client-PC übertragen. Warum willst du da unbedingt ein SMB haben? Wenn du eh nen Java-Client schreibst, kannst du die Daten auch direkt über den Client verwalten/anzeigen.

Kannst du mal detaillierter erklären, was du vorhast? Du willst Dateiein in ner SQL-DB ablegen - auf diese Zugreife und die in nen SMB packen?!
 
voodoo44 schrieb:
Wenn du einen eigenen Client entwickelst, dann kannst du über diesen auch die Files auf den Client-PC übertragen. Warum willst du da unbedingt ein SMB haben? Wenn du eh nen Java-Client schreibst, kannst du die Daten auch direkt über den Client verwalten/anzeigen.
Ja klar! Aber Du meintest doch, dass die Daten im FS liegen sollen und die Metadaten in der Datenbank. Dann gibt es in der Datenbank eine Pfadangabe zu der Datei, die dann über ein SMB-Share verfügbar ist. Und dann nimmt mein Java-Programm die Pfad-Angabe und öffnet die Datei über das mit dem Rechner (hoffentlich) verbundene Share.

voodoo44 schrieb:
Kannst du mal detaillierter erklären, was du vorhast? Du willst Dateiein in ner SQL-DB ablegen - auf diese Zugreife und die in nen SMB packen?!

METHODE 1:
Dateien liegen im Dateisystem in Ordnern. In der Datenbank stehen die Metadaten zu den Dateien und dabei ist eine Pfadangabe, wo die Datei auf einem Share liegt. Wenn die Datei geöffnet werden soll, dann liest das Programm den Pfad der Datei aus der Datenbank, hofft, das der Nutzer das entsprechende Zielshare verbunden hat und versucht dann die Datei zu öffnen. Dabei müssen dann die Rechte entsprechend konfiguriert werden, dass die Nutzer in allen drei Berechtigungsstufen liegen.

METHODE 2:
Die Dateien werden in der Datenbank zusammen mit den Metadaten abgespeichert. Wenn jemand eine Datei bearbeiten will, dann wird sie auf den lokalen Rechner aus der Datenbank geladen, dort vom Nutzer gändert und dann wieder hochgeladen in die Datenbank. Da es ja für das Programm bereits ein Berechtigungssystem gibt ist somit sichergestellt, dass die User nur an die Dateien dürfen, für die sie auch eine Berechtigung haben.

Ist das so verständlicher?

Gruß,
CPU
 
Ja, so ist es verständlicher. Aber warum muss der User für diese Vorgänge mit dem Samba-Share verbunden sein?

Ob du die Dateien aus der Datenbank ausliest und an den Client auf den PC sendest (hier bietet sich eine temporäre-Datei im Programmfolder an) oder ob du die Datei vom FS ausliest und dem Client auf den PC kopierst, sollte relativ egal sein. Bei einer sauberen Programmarchitektur kannst du beides durch Tausch einer Klasse in wenigen Sekunden ändern.

Und dann nimmt mein Java-Programm die Pfad-Angabe und öffnet die Datei über das mit dem Rechner (hoffentlich) verbundene Share.
Vermutlich schlecht ausgedrückt: dein Client soll das File nehmen und auf den Client-PC kopieren.

Hast du dir eigentlich schon Gedanken über den "Rückweg" gemacht?
 
Hey,

voodoo44 schrieb:
Ja, so ist es verständlicher. Aber warum muss der User für diese Vorgänge mit dem Samba-Share verbunden sein?.
Das Java Programm liest aus der Datenbank aus: "Dateien liegen unter Pfad /Dateien/<ID>" (also z.B. für Eintrag mit ID 454 gibt es auf F:\Dateien\454, auf G:\Dateien\454 und P:\Dateien\454 den Ordner mit den Dateien zu dem Eintrag aus der Datenbank. Auf den drei verschiedenen Shares eben wegen den Rechten; s.o.) und macht dann soetwas wie

Code:
Runtime.getRuntime().exec("explorer F:\Dateien\454");
Runtime.getRuntime().exec("explorer G:\Dateien\454");
Runtime.getRuntime().exec("explorer P:\Dateien\454");

und schon gehen je nach Berechtigung auch die Entsprechenden Explorer-Fenster auf! Das Problem ist jetzt nur, wenn z.B. P vorher nicht verbunden wurde kommt Schrott raus!

voodoo44 schrieb:
Ob du die Dateien aus der Datenbank ausliest und an den Client auf den PC sendest (hier bietet sich eine temporäre-Datei im Programmfolder an) oder ob du die Datei vom FS ausliest und dem Client auf den PC kopierst, sollte relativ egal sein.
Um die Datei aus dem FS auszulesen, sollte ich dann jCifs verwenden, oder was? Dann verbinde ich mich im Programm mit jCifs mit dem Remote-Laufwerk?

Also bei dieser ganzen Verbindugsgeschichte kann schon auch viel schief gehen. Da finde ich den Ansatz mit der Datenbank schöner.

Aber ich glaube, dass ich noch nicht ganz verstanden haben, wie Du - voodoo44 - meinst, dass es funktionieren soll.

Also nochmal; Szenario: User (=Mitarbeiter) schaut sich Details zu Vorgang 454 an und möchte jetzt die Dateien sehen und eine auswählen. Folgende Freigaben gibt es:
Code:
//SERVER/Freigabe_P/Dateien (ZUGRIFF: ALLE)
 [DIR] ...
 [DIR] 453
 [DIR] 454
   [DIR] Phase 2
     [FILE] Plan für Phase 2.doc
   [FILE] Anschreiben.doc
   [FILE] Katalog.pdf
   [FILE] Ein Bild.jpeg
 [DIR] ...

//SERVER/Freigabe_G/Dateien (ZUGRIFF: Mitarbeiter, Chef)
 [DIR] ...
 [DIR] 453
 [DIR] 454
   [FILE] Rechnung.jpeg
   [FILE] Bestätigung.pdf
 [DIR] ...

//SERVER/Freigabe_F/Dateien (ZUGRIFF: Chef)
 [DIR] ...
 [DIR] 453
 [DIR] 454
   [FILE] Geheim.jpeg
 [DIR] ...

So dann müsste ich ihm jetzt eine Auswahl der Dateien auf zwei Laufwerken mit den entsprechenden Dateien geben. Und wie soll ich das Deiner Meinung nach anstellen, voodoo44?

Gruß,
CPU
 
Vermutlich reden wir ein wenig aneinander vorbei.

Soweit ich das verstanden habe, willst du einen Java-Client bauen. Dieser Java-Client kann 3 Sachen: Daten aus einer Datenbank auslesen, Daten von einer (externen) Platte lesen und Daten zu dieser externen Platte schreiben. Entweder lässt du das als Java-Applet im Browser laufen oder du schreibst einen Client und einen Server.

User - Startet das Programm
Client - sendet DB-Abfrage: welche Files darf der User sehen?
Client - präsentiert dem User die Files, die er ansehen/bearbeiten darf
User - wählt File aus
Client - lädt Datei runter (/tmp/ ... wherever) und öffnet sie mit dem entsprechenden Viewer (Word, Acrobat, whatever)
User - bearbeitet Datei, speichert sie
Client - überwacht im Hintergrund das Verhalten der Datei - bei Änderungen werden diese an den Server übermittelt
Server - speichert Daten (ob in DBMS oder FS ist egal)
User - schließt Datei, öffnet ggf. über Client neue Datei

Ist es so verständlich, wie ich das meine?

Faktisch brauchst du aber folgendes:
- einen User (;) )
- einen Client
- einen Server

Ob auf dem Server ein kleiner Java-Dienst läuft, der entsprechende Anfragen (Word-Dokumente speichern) entgegen nimmt oder ob dort der SQL-Server läuft, welcher die Datenfelder zugeschoben bekommt, ist relativ egal.
 
voodoo44 schrieb:
Vermutlich reden wir ein wenig aneinander vorbei.
Es schein mir auch so! :D

voodoo44 schrieb:
Soweit ich das verstanden habe, willst du einen Java-Client bauen. Dieser Java-Client kann 3 Sachen: Daten aus einer Datenbank auslesen, Daten von einer (externen) Platte lesen und Daten zu dieser externen Platte schreiben.
Nein!

Es drei Freigaben, auf denen Dateien liegen ind Ordnern gesammlelt. Und jeder Ordner ist nach einer ID benannt, was bedeutet, dass die beinhalteten Dateien zur dem Datensatz aus der Datenbank mit entsprechender ID gehören. Also hat jeder Datensatz aus der Datenbank "Anhänge" auf den Freigaben.

Das Programm zeigt dem Nutzer die Daten an und eine Liste von Dateien die dazu gören ("Anhänge") und dieser kann die Dateien bearbeiten!

Das ist das Szenario. Und ich werde jetzt den Dateisystembasiertenweg gehen (Dateien und Daten in der Datenbank bleiben getrennt). Trotzdem werde ich die Sache mit der Datenbank im Hinterkopf behalten: ist ja nicht schlecht!

Beste Grüße,
CPU
 
Zurück
Oben