DMS: Die Datenbank

Ganz zu Beginn überlegte ich mir eine Datenbankstruktur. Mein Plan war, dass ich alle Dokumente als Blob in einer MySQL Datenbank ablegen würde. Hier gibt es verschiedene Meinungen zu: Die einen sagen: „Absolut nicht akzeptabel. Dateien gehören im Dateisystem abgelegt!!!“ und die anderen „Kann man ja mal machen…“.

Die Vor- und Nachteile sind eigentlich relativ gut aufzuwiegen. Für die Speicherung in der MySQL Datenbank spricht natürlich die gute Anpassbarkeit der Berechtigungen sowie die relativ einfache Abfrage der Daten aus der Datenbank.

Dagegen spricht: Die Datenbank wird mit der Zeit sehr groß. Unter Umständen kann MySQL auch an seine Grenzen stoßen (die ich übrigens später noch anmerken werden – ich bin nämlich auch darauf gestoßen).

Gegen das Speichern als Dateien sprach hingegen, dass ich mir keine Gedanken machen wollte, wie ich den Zugriff auf die Daten selbst einschränke. Wenn es ein Filesystem gibt in dem die Daten liegen, muss ich sehen, dass die Daten nicht z.B. über eine URL abrufbar sind und versteckt bleiben.

Ich entschied mich daher meine zukünftigen Dokumente im PDF Format als base64 decodierten in eine Blob-Tabelle abzulegen. Nur nebenbei: Das macht auch das Backup relativ einfach. Es wird halt nur recht groß.

Mein erster Schritt war also mir meine Datenbankstruktur zu überlegen:
Welche Tabellen brauche ich? Welche Inhalte sollen die Tabellen haben?

Ich begann mit der Tabelle für die Benutzer:

Tabelle: user

Die Usertabelle ist recht einfach und überschaubar aufgebaut. 

In der ersten Version gab es eigentlich nur einige wenige Spalten:

  • id: für die interne ID
  • login: Loginname
  • firstname: Vorname
  • lastname: Nachname
  • email: E-Mailadresse
  • password: Password als Hash
  • lastLoginIP: IP des letzten Logins
  • lastLoginDate: Datum des letzten Logins
  • disabled: Account aktiv oder nicht?

Das wars auch schon mal. In der Zwischenzeit habe ich die Tabelle noch um einiges ergänzt, aber dazu später mehr.

Ich brauchte dann natürlich auch eine Tabelle für meine Dokumente. Hier überlegte ich mir wie es am besten wäre und wie es sinnvoll sein könnte.

Ich wählte ein Konstrukt aus zwei verschiedenen Tabellen:

Tabelle: documents

Hier werden die hauptsächlichen Inhalte und Metadaten des jeweiligen Dokuments gespeichert:

  • id: für die interne ID
  • uid: die Benutzer-ID
  • name: Name des Dokumentes
  • fileName: Dateiname des Dokuments
  • fileDate: Datum des Dokuments
  • fileUploadDate: Datum des Uploads
  • categorie: Kategorie
  • description: Beschreibung des Dokuments

Auch hier an und für sich, sehr überschaubar gehalten. Aber auch hier gab es im Laufe der Zeit die eine oder kleine Änderung und Anpassung.

Dazu gibt es noch die

Tabelle: documentsAttachment

Sie beinhaltet schlussendlich die Datei mit dem Dokument (in dem Fall PDF) an sich.

  • id: für die interne ID
  • uid: die Benutzer-ID
  • documentID: die Dokument-ID
  • mimeTyp: Der Typ des Dokuments
  • attachment: Inhalt der Datei als base64 String.

Auch bis hierher: Kein Hexenwerk. Diese Tabelle hat sich übrigens in den ganzen Anpassungen von mir bisher auch nicht weiter geändert.

Tabelle: categories

Die Kategorien sind ebenfalls nicht besonders schwierig aufgebaut:

  • id: für die interne ID
  • uid: für die Benutzer-ID
  • name: Name der Kategorie
  • description: Beschreibung der Kategorie
  • deletable: Kann die Kategorie gelöscht werden?
  • deletableDisabled: Die Löschmöglichkeit deaktivieren
  • parentCategorie: Die Elternkategorie

Zu den Einstellungen ob eine Löschung erlaubt ist und ob die Löschung der Löschung erlaubt ist, komme ich später noch einmal im Detail und was der Sinn dahinter sein soll.

Tabelle: aliasMapping

Diese Tabelle stellt einen Zusammenhang zwischen dem Absender einer E-Mail bzw. eines Dokumentes und dem Empfänger dar. Auf die Funktion gehe ich später auch noch einmal genauer ein.

  • id: für die Interne ID
  • uid: für die Benutzer-ID
  • sender: E-Mailadresse des Absenders
  • descript: Beschreibung
  • type: Typ der E-Mail die eingeliefert wird

Ihr seht also, dass die Tabellenstruktur gar nicht so kompliziert aufgebaut ist. Als Wichtig empfinde ich, dass die jede Tabelle seine eigene interne ID erhält, auch wenn das z.B. bei dem aliasMapping oder der Tabelle documentsAttachment gar nicht unbedingt nötig gewesen wäre. Auch fand ich es wichtig, die übergreifenden Spalten (wie z.B. uid) immer gleich zu benennen. Das verhindert später Verwirrungen.

Ansonsten habe ich die Datenbank allgemein noch mit den Relations ausgestattet (eigentlich alle soweit mittels CASCADE) um z.B. einfach zu verhindern, dass wenn ein User gelöscht wird, in den anderen einzelnen Tabellen Daten der User-ID weiterhin vorhanden bleiben. So reicht später z.B. auch nur ein query, wenn ein User gelöscht werden soll – und zwar direkt auf die user Tabelle und muss nicht auf andere Tabellen ausgedehnt werden. Zieht man das konsequent durch, lässt sich das ganze später immer schön um weitere Tabellen erweitern und man muss z.B. die Funktionen für die Löschung eines Benutzer nicht weiter anfassen. Das passiert dann alles Datenbankseitig.

Hier gehts weiter: Dokumentenmanagement: Das Aussehen

Schreibe einen Kommentar