Vor ein paar Jahren habe ich eine Blog-Engine erstellt. Ihr Zweck ist es, Blog-Artikel zu hosten und für jeden Artikel die verschiedenen Versionen, einige Metadaten, Besuchsstatistiken usw. zu speichern.
Dies könnte als eine Reihe von Tabellen gespeichert werden, aber wenn Sie versuchen, ein Modell zu erstellen, wächst es sehr schnell auf ein Dutzend Tabellen, wenn nicht sogar mehr. Einige SQL-Abfragen könnten mit vielen join
s hässlich werden , und ... nun, Sie bekommen das Bild.
Das Problem dabei ist, dass es eine zentrale Sache gibt - einen Blog-Artikel - und all diese Dinge rund um den Artikel, was ihn für eine dokumentbasierte Datenbank gut geeignet macht. Mit MongoDB war das Modellieren der Datenbank extrem einfach: Eine Sammlung enthält die Blog-Artikel, und eine zweite winzige Sammlung enthält die Liste der Benutzer, die Artikel schreiben dürfen. Jedes Dokument in der ersten Sammlung würde alle Informationen enthalten, die ich zum Anzeigen eines Artikels benötige, sei es der Name des Autors oder die Tags.
Stellen Sie sich jetzt ein ganz anderes Projekt vor. Es gibt einige Benutzer, die Zeug schreiben und die von anderen Benutzern geschriebenen Sachen teilen können. Auf einer Seite eines Benutzers würden Sie sowohl Dinge finden, die dieser Benutzer geschrieben hat, als auch die, die er geteilt hat. Es gibt eine Einschränkung: Wenn jemand das, was er in der Vergangenheit geschrieben hat, bearbeitet, wird die Änderung überall dort angezeigt, wo der ursprüngliche Text geteilt wurde.
Bei einem dokumentbasierten Ansatz ist es schwierig, das Dokument zu finden. Ein Benutzer vielleicht? Nun, das ist ein guter Anfang. Ein Benutzerdokument würde alle Dinge enthalten, die dieser Benutzer geschrieben hat. Aber was ist mit den Dingen, die sie geteilt hat?
Ein möglicher Weg ist, diese Dinge in dasselbe Dokument zu schreiben. Das Problem bei diesem Ansatz ist, dass die Anwendung jedes Benutzerdokument in der Datenbank durchgehen sollte, um jedes Vorkommen des alten Eintrags zu bearbeiten, wenn jemand einen Eintrag bearbeitet. Datenduplizierung nicht mitgezählt.
Eine Alternative wäre, im Benutzerdokument nur die Liste der von diesem Benutzer freigegebenen Einträge (mit der ID des verwiesenen Benutzers und des Eintrags) zu speichern. Jetzt tritt jedoch ein anderes Problem auf: Wenn ein Benutzer Tausende von Einträgen von Tausenden von Benutzern freigegeben hat, müssen Tausende von Dokumenten geöffnet werden, um diese Einträge zu erhalten.
Oder wir können unsere Sammlung um die Einträge selbst herum modellieren, wobei sich jeder Eintrag auf seinen Autor bezieht und eine Liste der Benutzer enthält, die ihn geteilt haben. Auch hier können Leistungsprobleme auftreten, wenn Sie alle Dokumente durchgehen müssen, um die von einem bestimmten Benutzer veröffentlichten Dokumente anzuzeigen.
Wie viele Tabellen würden Sie benötigen, wenn Sie eine relationale Datenbank verwenden würden? Richtig, drei. Es wäre einfach zu modellieren und auch einfach zu verwenden.