PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Nosql und Referentielle Integrität


Unfug
2013-05-09, 11:38:47
Schönen Guten Morgen,

Ich setze aktuell die MongoDB für ein privates Projekt ein und bin auf kleines designtechnisches Problem gestoßen.

Angenommen ich habe:

class Aufgabe
Kunde k


Die Aufgaben beinhalten also immer einen Kunden.

Jetzt kommt das Problem: Wenn ich den Kunden global updaten möchte (Name, Straße etc), dann ändert dieser sich ja nicht bei den vorhandenen Aufgaben. Es existiert ja keine Verbindung wie bei "Relationalen Datenbanken", sondern jeder Aufgabe wurde ein eigenes Objekt Kunde zugeordnet.

So...jetzt hab ich mir gedacht, dass ich jedem Kunde eine eindeutige ID zuordne und die Aufgaben Klasse wie folgt ändere

[code]
class Aufgabe
int KundenID
[code]

Somit hätte ich die Objekte getrennt und das ganze würde auch klappen. Das Problem: Ich finde, dass dieser Workaround Rotze ist. Eigentlich könnte man dann direkt einen OR Mapper für relationale DBs benutzen.

Vielleicht sehe ich den Wald vor lauter Bäumen nicht und es gibt ein wesentlich eleganteren Weg.

Gruß
Unfug

Update:
MongoDB beschreibt meinen Weg hier auch:
http://docs.mongodb.org/manual/reference/database-references/
Find ich persönlich aber nicht so schön, da ich auch DB unabhängig bleiben möchten.

robobimbo
2013-05-15, 21:07:58
phew, ich finde das ist auch eine designfrage, ob du die redundanz auch haben willst.

wenn du bei jeder aufgabe den kunden redundant speicherst, hast du auch auf der anderen seite historische daten gespeichert und verfügbar, dh. du könntest im nachhinein alle änderungen des kunden nachvollziehen, bzw. kannst du immer nachsehen wie die stammdaten des kunden zum zeitpunkt der erstellung der aufgabe waren.

ich denke gerade bei rechnungsadressen bzw. rechnungspositionen kann sowas auch durchaus gewollt sein - wie gesagt ist das eine designentscheidung. wenn du redundanzen vermeiden willst, unt immer nur mit aktuellsten daten arbeiten willst, dann wird kein ansatz über die ID die richtige sein (wobei du auch nachschauen kannst, mongo-db wird sicher eine eindeutige id pro datensatz sowieso generieren.

Marscel
2013-05-15, 21:40:41
Mal so rein aus Interesse, warum hast du dich in diesem Fall für eine NoSQL-Lösung entschieden?

Unfug
2013-05-15, 22:07:28
Danke für eure Antworten. Ich habe mir längere Zeit mehrmals Gedanken über ein mögliches Design gemacht. Wichtig für mich ist, dass die Klassen dem KISS (Keep it simple, stupid) Prinzip folgen.

Nach etlichen Gesprächen ist das Resultat, dass eine NoSQL dafür nicht geeignet ist. Die ganzen Workarounds sind...so lala.
Eigentlich sollte man direkt eine relationale Einsätzen.

Warum ich eine NoSQL genommen habe? Es war der Gedanke, sich nicht großartig die Integration zu kümmern. In einem vorherigen Projekt hab ich auch schon mal eine NoSQL eingesetzt, ohne ein derartiges Problem, und das war so schön einfach.
Mongo z.B. ist schnell aufzusetzen (einfach eine exe starten), Referenz hinzufügen, fertig.

Marscel
2013-05-16, 03:11:08
Ich weiß, die Einstiegsbarrieren dazu sind verführerisch niedrig. Aber mit dem ersten Verlangen nach einem Join sollte man sich überlegen, ob NoSQL die richtige Wahl war. :)

Unfug
2013-05-16, 20:10:14
Ich habe jetzt die Klasse, die für das Speichern und Laden der Datenbankobjekte zuständig ist derart erweitert, dass diese die zu speicherenden Objekte ausseinander nimmt und zusammenfügt.
Jede komplexe Struktur (also komplexer Datentyp) kommt dann in seine eigene Tabelle.

Hierfür musste ich eine WrapperKlasse bauen, die die speichernden Objekte aufnimmt. Ich habe quasi NoSQL in SQL gemacht. Völlig Banane. Aber ich wollte einfach wissen ob es klappt. Ich habe somit keinerlei Redundanz mehr in der DB und kann über die DBProxyKlasse auch referentielle Update, Delete etc Geschichten realisieren.

Daten in der DB sehen wie folgt aus:

MeinMongoDBObjekt
{
_id = 123123123
PropertyList
{
Kunde = 11232323213 // komplexes Property Hier steht die UniqueID aus der DB
}
originalObject
{
Name="Mustermann"
}
Adresse = null (in MongoDB ist der Value wert eigentlich leer, null nur hier für den Post)
originalType = "MeineAnwendung.Auftrag"


Wenn ich also nun ein Kunde zu einem Auftrag hinzufügen würde, dann wird nur die Referenz gespeichert und entsprechend zur Laufzeit aufgelöst.
(So wie bei einer SQL DB).
Das schöne ist, meine Klassen Auftrag, Kunde brauchen keinerlei Abhängigkeit zur MongoDB mehr, weil alles über Reflection gemacht wird. Ich kann alles ganz einfach halten.


Auftrag {
Kunde k;
String Beschreibung;
}