Struktur Frage

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Hallo,

ich bin gerade dabei ein kleines Spiel zu programmieren. Dabei soll es mehrere Forschungen geben. Diese sollten leicht erweiterbar durch neue Forschungszweige sein. Nun bin ich am überlegen, wie ich diese Forschungen und Forschungsfortschritte für jeden User speichere.

Es soll praktisch sowas hier werden:
Forschungsname, Fortschritt, User

Für jeden eine Tabelle kommt mir irgendwie komisch vor... was meint ihr?

Danke!
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Die größte Freiheit in Sachen Erweiterbarkeit erreichst Du mit dem EAV-Modell. Allerdings wachsen EAV-Tabellen relativ schnell (in Deinem Falle quasi mit Anzahl der User*Forschungen).

Ist die Erweiterbarkeit eher von untergeordneter Bedeutung, kann man das Design eigentlich immer weiter simplifizieren. Du könntest z.B. einzelne Tabelle für jede Forschung führen, oder sogar die gesamte Forschung in eine Tabelle mit Forschung als Attribute packen. Neue Forschungen könntest Du dann als neue Spalten genullt anfügen. In einem solchen Eintabellendesign müßtest Du dann allerdings die "Baumabhängigkeit" der einzelnen Forschungen extern mitführen, z.B. in einer zusätzlichen Tabelle nach dem Vater-Modell oder nested-sets-Modell. Sind die Entwicklungsabhängigkeiten nicht in einem Baum darstellbar, wird die Sache hier sehr kompliziert. Aus Datenbank-Sicht sind Eintabellenkonstrukte natürlich der Horror, Du mußt Dich hier allerdings fragen, welche Zugriffe am häufigsten sind.
Für jeden eine Tabelle kommt mir irgendwie komisch vor... was meint ihr?
Meinst Du hier eine neue Tabelle pro Forschung oder pro User? Pro Forschung kann durchaus sinnvoll sein, falls die Forschungen relativ konservativ sind, d.h. Du wenige Erweiterungen erwartest.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Bei einer Tabelle mit den drei Spalten Forschung, Fortschritt und User reicht doch eine für alle Benutzer. Allerdings scheint mir dies ein Fall zu sein, wo das Denken in Tabellen eher ein Nachteil ist und ich würde sagen, stelle dir ein User-Objekt vor, das ein dict mit Forschung auf Fortschritt enthält und speichere dieses dann als pickle oder als JSON-Struktur ab.

Code: Alles auswählen

{
  "name": "sma",
  "research": {
    "attack": 5,
    "defense": 3
  }
}
Persistenz der Daten würde ich so lange wie möglich als Implementierungsdetail sehen und als Datenmodell ein Netz aus Objekten annehmen und nicht eine Sammlung von Relationen (tabellarische Datensätze).

Stefan
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@sma:
Da stimme ich Dir zu. Dieses Problem ist relational nur mit deutlichem Zusatzaufwand darstellbar. Wobei Dein Ansatz einem Eintabellendesign mit blob oder varchar-Feld für das pickle/JSON entsprechen würde. (Sofern man das überhaupt in eine DB überträgt.)

@SchneiderWeisse:
Die relationale Auftröselung macht für Dich eigentlich nur Sinn, wenn Du hiervon einen Benefit erhältst und Du z.B. häufig Enwicklungsfortschritte vergleichbar machen willst (für Statistiken etc.) Die DB spielt Dir hier in die Hand. Das geht natürlich auch mit sma's Ansatz, wenngleich Du hier alle pickles holen und programmseitig auswerten mußt, ist der Ansatz doch viel transparenter und für gelegentliche Statistiken wahrscheinlich ausreichend.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Vielen Dank!

Das mit direktem abspeichern als Pickle hatte ich auch schon im Hinterkopf. Oder eben ein Tabelle, die - wie du gesagt hast - bei evtl. neuen Forschungszweigen per Spalte erweitert wird. Ich glaube das ist auch der bessere Weg, ist zwar etwas lästig das zu erweitern, aber von der Performance wird es schneller sein (seid ihr meiner Meinung?)...
Es wird wohl relativ viel auf die Forschungsfortschritte zugegriffen, was heißt das Performance im Vordergrund steht.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

SchneiderWeisse hat geschrieben:...Oder eben ein Tabelle, die - wie du gesagt hast - bei evtl. neuen Forschungszweigen per Spalte erweitert wird. Ich glaube das ist auch der bessere Weg, ist zwar etwas lästig das zu erweitern, aber von der Performance wird es schneller sein (seid ihr meiner Meinung?)...
Ich geh jetzt mal davon aus, daß das Spiel Server-Client basiert ist, und Du ein Protokoll zur Kommunikation gebrauchst. Dann stellt sich die Situation wie folgt dar:

-stateful protocol - Alle wichtigen Settings können zu Beginn eingelesen werden und sind später über irgendeinen Datentyp im RAM verfügbar. Hier ist der pickle-Weg im Vorteil, da selbst die schnellsten DBs nicht eine direkte RAM-Abfrage ausstechen können. Kostspieligere Einlese- und Schreibevorgänge kannst Du vernachlässigen, da die nur selten auftreten. (Das gilt im übrigen auch für ein "Einzelplatz"-Spiel, da Du hier immer stateful bist.)

-stateless protocol - Gilt im Prinzip für alle http-basierte Kommunikation. Hier ist der Aufwand abhängig davon, ob Du für jede Anfrage sowieso den kompletten Userdatensatz anfassen mußt, oder gezielte Einzelanfragen zulassen möchtest. Ist letzteres der Fall, so ist die relationale Auftrennung schneller, liegt ersteres vor, gewinnst Du "nur" die pickle/unpickle Zeit auf Kosten eines höheren Verwaltungsaufwandes der DB Deinerseits.

Das schneller oder langsamer kann man nicht pauschalisieren, eine gesparte Anfrage ist zwar per se schneller, der Gewinn kann aber durch eine hierdurch nötige komplexe Anfrage negiert werden.

Hoffentlich kannst Du aus dem Blafasel noch etwas für Dich herauslesen ;)
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Konnte ich...;) Es handelt sich um eine Server-Client Anwendung auf Basis von http und soll auch noch laufen wenn mehrere tausend User angemeldet sind, von daher ist RAM schlecht... Wird wohl mit der Tabelle gemacht werden.

Ich bedanke mich für die Tipps!

EDIT: Allerdings fällt mir gerade eine weitere Möglichkeit ein...

Table(name, user, value)

und dann einfach per WHERE user = xy and name = yx

Dann sind praktisch viele Einträge pro User in einer Tabelle für jeweils eine Forschung - was haltet ihr davon?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

EDIT: Allerdings fällt mir gerade eine weitere Möglichkeit ein...

Table(name, user, value)

und dann einfach per WHERE user = xy and name = yx
Wie wärs mit einer ID aus zwei Fremdschlüsseln (user, forschung)? Ist deutlich performanter als verschachtelte where-Klauseln.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

jop - bin nicht sonderlich datenbankbewandert... Kennt ihr ein gutes Buch, mit dem man so grundsätzlich Datenbankgeschichten lernt - die Anbindung an Python und Co. muss nicht im Buch dabei sein... Mir geht's da eher um's richtige Verständnis über Datenbanken.

Danke!
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Eine guten Überblick rund ums DB-Geschäft liefert das Buch Datenbanksysteme: Eine Einführung. (Das Buch ist allerdings weniger ein Tutorial als ein theoretischer Rundumschnitt.)

Willst Du in Python ein ORM einsetzen, würde ich Dir SQLAlchemy empfehlen, da dessen objektrelationales Mapping Dir mehr dem Datenbankler entgegenkommende Freiheiten gewährt als die meisten anderen.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Das benutze ich bereits, aber nicht das ORM, sondern die Expression Language. Genau um so einen theoretischen "Rundumschnitt" geht es mir. Danke!
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Was ich noch sagen wollte, Dein letzter Vorschlag ist quasi EAV-light ;)

Noch ein Tipp hierzu: Für mehrere gleichzeitig benötigte Werte ist es sinnvoll, nicht mehrere Abfragen nacheinander abzusetzen sondern zu einer zusammenzufassen. So hat die DB die Möglichkeit die Werte optimiert in "einem Rutsch" zu finden. (Das war Dir sicherlich klar.)
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

jerch hat geschrieben:EAV-light
Was ist das? (Ich kenne ja persönlich nur die Band EAV^^)
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

:o Ehm, siehe Link in obigem Post http://www.python-forum.de/post-131409.html#131409

EAV - gibts die eigentlich noch?
Antworten