Original von Phoenix1988
Ich glaube aber du hast mich generell teilweise missverstanden. Da ich keine relationale DB nutze gibt es keine Tabellen, die ganze DB besteht aus Graphen. Die Graphendatenbank ist dementsprechend darauf ausgelegt hochperformant Graphen zu bearbeiten und zum Beispiel Wege zu finden, wobei der A*-Algorithmus selbst in Java implementiert ist und per lazy-select entsprechende Knoten erhält. Auch bei tausenden Knoten ist eine Wegfindung so kein Problem.
Ich schau mir die Sache unter dem Gesichtspunkt der Performance an. Meine Empfehlung ist es zuerst zu evaluieren, ob du dein Universum nicht im Speicher halten kannst und dann darauf deine selbst geschriebenen Algorithmen abzusetzen (sei es nun für kürzeste Wege oder Umgebungssuche). Dieser Vorschlag klammert die Persistenz völlig aus...
Ich hab mir jetzt mal schnell Neo4J angeschaut und gesehen, dass das Ziel ist die Graphen komplett im Speicher zu halten...was bei dir ja sicherlich machbar ist...insofern passt das ja...
Das eine Wegfindung bei tausent Knoten kein Problem ist wage ich mal zu bezweifeln...ausser du peilst nur wenige gleichzeitige Benutzer an. Ich habe in meinem Spiel ebenfalls ständige Suchen auf Graphen für die Gegner-KI zu laufen und das zieht ab einer bestimmten Anzahl gleichzeitiger Zugriffe schon an der Performance...vielleicht mal ein Lasttest mit JMeter laufen lassen. Ich hab allerdings auch keine Ahnung, wie gross der Ausschnitt sein wird, den deine User jeweils von der Karte sehen werden und wie häufig diese Anfragen an deinen Graphen haben...bei mir sind es sehr viele pro Aktion.
Da ich keine relationale DB nutze
Wo speicherst du für einen Benutzer die Anzahl an Schiffen, Produktionsanlagen, Verteidigungsanlagen, ... (was auch immer man so in deinem Spiel produzieren/kaufen kann...)? Ich bin nicht davon ausgegangen, dass das alles als Properties in deinem Graphen hängt...und wenn es doch da drinnen hängt (z.B. wie buhrmi vorgeschlagen hat)...wie gross können diese Daten pro User werden und ist dann immernoch sichergestellt, dass der komplette Graph im Speicher gehalten werden kann...wenn nicht wird neo4j dank des Lazy Loadings krass inperformant (auch trotz LRU Cache, wenn genügend viele Benutzer gleichzeitig online sind)...aber zu dem Thema gibts in der Doku von neo4j ja einiges zu lesen und ich hab auch keine Ahnung, auf was für einer Kiste du dein Spiel laufen lassen willst.
Auch wenn es für mich nicht relevant ist, warum verzichtest du auf die erste Normalform und speicherst serialisierte Listen ab?
Weil man irgendwann merkt, dass die Normalfomen kein so heiliger Gral sind, wie es einem im Studium gepredigt wird....genausowenig wie ACID...besonders, wenn man irgendwann an den Punkt kommt, wo es einfach nur um Performance geht...da sind dann auch Redundanzen wieder ok oder columns mit zusammengesetzten Werten...natürlich nur, wenn man auch weiss, was die Konsequenzen sind.. :)
Ich bin davon ausgegangen, das nur eine Liste von Ids gespeichert wird und Abfragen wie: "Kennt Benutzer A das System a73h?" oder "Welche Benutzer kennen das System a73h?" nicht relevant sind, ich also diese Daten nicht in strukturierter Form in der Datenbank brauche, weil ich eh wenn dann immer alle (für einen Benutzer) brauche. Ansonsten würde es halt ne weitere Relation für deinen User geben.
Wenn du alternativRouten und Blockierungen als Requirements hast, dann kommt man natürlich an nem vollen Graphen nicht vorbei...das mit neo4J gefällt mir, besonders, dass die gängigen Algorithmen gleich mitgeliefert werden in der Graph-algo Komponente.
Bis denne...
Maxx