Modellieren mehrerer "Verwendungen" (z. B. Waffe) für verwendbares Inventar / Objekt / Gegenstände (z. B. Katana) in einer relationalen Datenbank


10

Daher arbeite ich daran, die Verwendung von Elementen auf www.ninjawars.net zu erweitern , und ich bin mir nicht ganz sicher, wie ich sie in der von uns verwendeten relationalen Datenbank flexibel darstellen kann.

Ich belle vielleicht den falschen Baum an, also zögern Sie nicht, Vorschläge in andere Richtungen zu machen, aber derzeit denke ich, dass jedes Element relationale "Tags" haben sollte.

Beispielsweise ist ein Katana derzeit eine Zeile in der Datenbank "Elemente". Um daraus eine Waffe und eine haltbare Sache zu machen, dachte ich, ich hätte eine Datenbank mit "Merkmalen" und eine item_traits-Tabelle, die einfach zwischen ihnen verknüpft ist.

// Objects and their basic data

item_id | item
1 | Naginata


// Things that objects can do

trait_id | trait
1 | weapon
2 | holdable

// How those objects do those things, e.g. powerfully, weakly, while on fire

_item_id | _trait_id | item_trait_data
1 | 1 | damage: 5, damage_type: sharp, whatever, etc

Ich bin mir nicht sicher, wie ich die zusätzlichen Daten modellieren soll (z. B. den Schaden, den ein Schwert anrichten wird, den Schadenstyp usw.).

Ich bin auch nicht besonders glücklich darüber, dass der gesamte Gegenstand an mehr als einem Ort gespeichert wird, z. B. um eine Kopie eines Gegenstands mit einem anderen Namen zu erstellen, wie z. B. ein "Kurzschwert", von dem ich kopieren müsste mehrere Tabellen, um das doppelte Element zu erstellen.

Gibt es eine bessere Möglichkeit, dieses vermisste Zeug auszulegen?

Bearbeiten: Ich sollte nur beachten, dass ich bereits eine Postgresql-Datenbank auf der Site verwendet habe, weshalb ich sie für meine Datenspeicherung verwenden möchte.

Bearbeiten: Ich habe eine Antwort für die Implementierung hinzugefügt, die ich gerade betrachte.

Antworten:


10

Ich werde mit allen leicht anderer Meinung sein und sagen, dass der relationale Ansatz hier vernünftig ist. Interessant ist hier, dass Elemente mehrere Rollen haben können. Das Hauptproblem wird sein, dass sich die Zuordnung zwischen diesem relationalen Layout und einem OO-Layout im Code nicht "natürlich" anfühlt, aber ich denke, auf der Datenbankseite können mehrere Rollen sauber ausgedrückt werden (ohne seltsame Codierungen oder Redundanz, nur Verknüpfungen). .

Als Erstes müssen Sie entscheiden, wie viele Daten objektspezifisch sind und wie viele von allen Elementen eines bestimmten Typs gemeinsam genutzt werden.

Folgendes würde ich tun, wenn alle Daten artikelspezifisch sind:

// ITEMS table: attributes common to all items
item_id | name        | owner         | location             | sprite_id | ...
1       | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663      | ...

// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1       | 5      | sharp       | 13         | ...

// LIGHTING table: attributes for items that serve as lights
item_id | radius   | brightness | duration | ...
1       | 3 meters | 50         | 8 hours  | ...

In diesem Design befindet sich jedes Element in der Elementtabelle, zusammen mit Attributen, die alle (oder die meisten) Elemente haben. Jede zusätzliche Rolle, die ein Gegenstand spielen kann, ist eine separate Tabelle.

Wenn Sie es als Waffe verwenden möchten, schlagen Sie es in der Waffentabelle nach. Wenn es da ist, kann es als Waffe verwendet werden. Wenn es nicht da ist, kann es nicht als Waffe verwendet werden. Die Existenz der Aufzeichnung sagt Ihnen, ob es sich um eine Waffe handelt. Und wenn es da ist, werden alle seine waffenspezifischen Attribute dort gespeichert. Da diese Attribute direkt anstatt in einer codierten Form gespeichert werden, können Sie Abfragen / Filter mit ihnen ausführen. (Für die Metrikseite Ihres Spiels möchten Sie beispielsweise Spieler nach Waffenschadenart aggregieren, und dies können Sie mit einigen Verknüpfungen und einem Gruppentyp nach Schadenstyp tun.)

Ein Gegenstand kann mehrere Rollen haben und in mehr als einer rollenspezifischen Tabelle vorhanden sein (in diesem Beispiel sowohl Waffe als auch Beleuchtung).

Wenn es nur ein Boolescher Wert wie "Ist das haltbar?" Ist, würde ich ihn in die Tabelle "Elemente" einfügen. Es kann sich lohnen, "Ist dies eine Waffe" usw. zwischenzuspeichern, damit Sie die Waffen und andere Rollentabellen nicht nachschlagen müssen. Es fügt jedoch Redundanz hinzu, sodass Sie darauf achten müssen, dass es synchron bleibt.

Die Empfehlung von Ari, eine zusätzliche Tabelle pro Typ zu erstellen, kann auch bei diesem Ansatz verwendet werden, wenn einige Daten nicht pro Element variieren. Wenn beispielsweise der Waffenschaden nicht pro Gegenstand variiert, die Rollen jedoch immer noch pro Gegenstand variieren, können Sie gemeinsam genutzte Waffenattribute in einer Tabelle zusammenfassen:

// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1       | 13         | light_saber

// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber    | 5      | energy

Ein anderer Ansatz wäre, wenn die Rollen, die von Elementen gespielt werden, nicht nach Element, sondern nur nach Elementtyp variieren. In diesem Fall würden Sie den item_type in die Items-Tabelle einfügen und die Eigenschaften wie "Ist es eine Waffe?" Und "Ist es haltbar?" Und "Ist es ein Licht?" In einer ItemTypes-Tabelle speichern. In diesem Beispiel mache ich auch, dass Artikelnamen nicht pro Artikel variieren:

// ITEMS table: attributes per item
item_id | item_type    | owner         | location
1       | light_saber  | 14 (Tchalvek) | 381 (Tchalvek house)

// ITEMTYPES table: attributes shared by all items of a type
item_type   | name        | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663      | true        | true      | true

// WEAPONTYPES table: attributes for item types that are also weapons
item_type   | damage | damage_type
light_saber | 5      | energy

Es ist wahrscheinlich, dass sich Gegenstandstypen und Waffentypen während des Spiels nicht ändern. Sie können diese Tabellen also nur einmal in den Speicher laden und diese Attribute in einer Hash-Tabelle anstatt mit einem Datenbank-Join nachschlagen.


+1. Dies ist die einzige Antwort, die eine relationale Datenbank als relationale Datenbank verwendet. Alles andere als dieses oder das andere Extrem von Neverminds Blob-Vorschlag und nur die Verwendung der Datenbank als Datenspeicher sind schreckliche Pläne.

+1 Aber diese Ansätze scheinen irgendwie unflexibel. Ich entschuldige mich, wenn ich inkonsistent klinge, aber ich möchte in der Lage sein, die Datenbankstrukturen für Elemente im Wesentlichen einmal zu erstellen ... ... und dann mehr Funktionen für Elemente zu codieren, mehr Einfügungen in die Datenbank für Elemente vorzunehmen, aber nicht ändern zu müssen die Datenbank in Zukunft wieder (natürlich mit seltenen Ausnahmen).
Kzqai

Wenn Sie möchten, dass die relationale Datenbank Ihre Felder kennt und deren Darstellung optimiert, müssen Sie sie irgendwo hinzufügen. Es ist wie bei statischen Typen. Wenn Ihr Compiler Ihre Felder kennen und deren Darstellung optimieren soll, müssen Sie Typen deklarieren. Die Alternative ist ein dynamisch typisierter Ansatz, der von einigen Dokumentendatenbanken verwendet wird oder bei dem Ihre Daten auf irgendeine Weise in die relationale Datenbank codiert werden. Die Datenbank kennt die Felder nicht und kann ihren Speicher nicht optimieren, aber Sie erhalten etwas Flexibilität.
Amitp

4

Leider sind in solchen Situationen relationale Datenbanken (wie SQL) nicht ausreichend und nicht relationale Datenbanken (wie MongoDB ) zeichnen sich aus. Abgesehen davon ist es nicht unmöglich, die Daten in einer relationalen Datenbank zu modellieren. Da Ihre Codebasis anscheinend bereits von SQL abhängig ist, ist hier das Modell, mit dem ich gehen würde:

Anstatt ein Element zu erstellen und eine Tabelle zu verwenden, erstellen Sie für jeden Elementtyp eine Tabelle und eine Referenztabelle "[item] _type".

Hier einige Beispiele:

weapon_type_id | weapon_type
1 | sharp

weapon_id | weapon| weapon_type_id | damage
1 | Short Sword | 1 | 5

potion_type_id | potion_type
1 | HP
2 | Mana

potion_id | potion| potion_type_id | modifier
1 | Healing Elixer | 1| 5
2 | Mana Drainer | 2| -5

Diese Lösung bietet Ihnen viel langfristige Flexibilität und Skalierbarkeit, reduziert (wenn nicht eliminiert) verschwendeten Speicherplatz und ist selbstdokumentierend (im Gegensatz zu "item_use_data"). Es erfordert etwas mehr Setup beim Entwickler, aber meiner Meinung nach ist es die eleganteste verfügbare Lösung für Situationen, in denen Sie eine relationale Datenbank zum Speichern Ihrer Daten verwenden müssen. Im Allgemeinen sind nicht relationale Datenbanken für die Spieleentwicklung viel besser geeignet, da sie flexibler Daten modellieren und gleichzeitig leistungsfähiger sind als SQL-basierte Datenbanken. Dies macht sie zu einer "Win-Win" -Wahl.

Bearbeiten 1: Ein Fehler mit dem Feld potion_type_id wurde behoben

Bearbeiten 2: Es wurden weitere Details zu nicht relationalen und relationalen Datenbanken hinzugefügt, um eine zusätzliche Perspektive bereitzustellen


Ich sehe nicht wirklich viel Flexibilität in diesem System. Wenn ich zum Beispiel eine Glasphiole wollte, die als Waffe verwendet werden kann und "scharf" ist, hätte ich Pech. Außerdem müsste ich für jeden neuen Elementtyp tatsächlich eine Datenbankstruktur dafür erstellen. Selbst wenn es nur einen oder zwei dieser Art geben würde.
Kzqai

Die Punkte, die Sie ansprechen, sind sehr gültig und zeigen zusätzliche Beispiele dafür, warum relationale Datenbanken für diese spezielle Situation nicht gut geeignet sind. Das von mir vorgestellte Modell zeigt lediglich, wie die Daten am besten so angeordnet werden können, dass Speicherplatz erhalten bleibt und die SQL-Funktionalität erhalten bleibt. Um Gegenstände verschiedener Art zu speichern, können Sie diese Daten unter diesem Modell am besten darstellen, indem Sie eine potion_weapon-Tabelle mit den entsprechenden Trank- und Waffeneigenschaften erstellen. Auch diese Lösung ist NICHT ideal, aber die eleganteste Lösung bei Verwendung einer relationalen Datenbank.
Ari Patrick

@Ari: Keine Respektlosigkeit beabsichtigt, aber sein Problem ist genau, warum der relationale Ansatz mehr Gültigkeit hat, nicht weniger. Es ist bekannt, dass NoSQL- (oder NoRel-) Datenbanken sich hervorragend für Lesevorgänge mit hohem Volumen, verteilte / hochverfügbare Daten oder schlecht definierte Schemata eignen. Dieser Fall ist einfach eine klassische Viele-zu-Viele-Assoziation, und DBs wie Mongo tun dies nicht so gut wie ein RDBMS. Siehe stackoverflow.com/questions/3332093/…
alphadogg

@alphadogg Wie ist das eine Viele-zu-Viele-Beziehung? In der Datenbank kennen Waffen die Waffentypen, aber die Waffentypen müssen nicht wissen, mit welchen Waffen sie verbunden sind. Wenn Sie aus irgendeinem Grund alle Waffen eines bestimmten Waffentyps kennen möchten, schreiben Sie einfach eine Abfrage, die die Sammlung der Waffendokumente durchläuft.
Ari Patrick

@Ari: In der Frage des OP kann eine Waffe viele Typen haben und ein Typ kann mit vielen Waffen verknüpft sein. Zum Beispiel sind ein Trank und ein Schwert haltbar. Ein Schwert ist sowohl haltbar als auch waffenfähig.
Alphadogg

3

Speichern Sie zunächst den objektorientierten Vererbungsansatz und entscheiden Sie sich für ein komponentenbasiertes System .

Sobald Sie dies getan haben, wird das SQL-Layout plötzlich viel einfacher. Sie haben eine Tabelle für jeden Komponententyp mit einer gemeinsamen ID-Nummer. Wenn Sie Artikel Nr. 17 möchten, suchen Sie in jeder Tabelle nach "Artikel-ID 17". Jede Tabelle mit einem Schlüssel wird mit einer Komponente versehen.

Ihre Gegenstandstabelle enthält alle erforderlichen Daten für Gegenstände im Allgemeinen (Name, Verkaufspreis, Gewicht, Größe, alles andere, was von allen Gegenständen geteilt wird). Ihre Waffentabelle enthält alle geeigneten Daten für Waffen, Ihre Trank-Tabelle enthält alle geeigneten Daten Für Tränke enthält Ihre Rüstungstabelle alle entsprechenden Daten für die Rüstung. Willst du einen Brustpanzer, das ist ein Eintrag in Item und ein Eintrag in Armor. Willst du einen Schwerthelm, den du trinken kannst, stellst du einfach einen Eintrag in jeden Tisch und bam, du bist fertig.

Denken Sie daran, dass dasselbe Muster nicht besonders objektspezifisch ist - Sie können es für Kreaturen, Zonen und alles andere verwenden, was Sie möchten. Es ist überraschend vielseitig.


2

Die Verwendung von SQL war Ihr schwerwiegender Fehler. Es ist absolut NICHT zum Speichern statischer Spieldesigndaten geeignet.

Wenn Sie sich nicht von SQL entfernen können, würde ich in Betracht ziehen, Elemente in einer serialisierten Datei zu speichern. Dh

item_id (int) | item (BLOB)
1             | <binary data>

Natürlich, das ist hässlich und wirft alle SQL „Nettigkeiten“ aus dem Fenster, aber Sie wirklich brauchen sie? Höchstwahrscheinlich lesen Sie alle Ihre Artikeldaten zu Beginn des Spiels trotzdem und niemals SELECTdurch etwas anderes als item_id.


3
Da das Spiel (nach meinem Verständnis) im Mehrspielermodus gespielt wird und PvP unterstützt, besteht die Wahrscheinlichkeit, dass die meisten Spielinformationen nicht auf dem Client gespeichert werden. Wenn dies korrekt ist, müssen Daten jedes Mal, wenn sie aus der Tabelle gelesen werden, deserialisiert werden, bevor sie aus der Ferne nützlich sind. Infolgedessen macht dieses Format das Abfragen von Elementen aufgrund ihrer Eigenschaften SEHR teuer. Beispiel: Wenn Sie alle Elemente vom Typ "Waffe" abrufen möchten, müssen Sie jedes Element abrufen, jedes deserialisieren und dann manuell nach dem Typ "Waffe" filtern, anstatt eine einfache Abfrage auszuführen .
Ari Patrick

1
Nach meiner Erfahrung werden alle Elemente zu Beginn des Spiels ohnehin in den In-Memory-Cache eingelesen. Sie deserialisieren sie also nur einmal beim Start und verwenden die Datenbank danach überhaupt nicht mehr. Wenn dies in diesem Fall nicht der Fall ist, stimme ich zu, dass das Speichern von serialisierten Objekten eine schlechte Idee ist.
Nevermind

Hmmm, das einzige ist, dass ich eine Schnittstelle habe, die erforderlich ist, um die Daten zu bearbeiten, was unpraktisch wäre.
Kzqai

2

Abhängig davon, wie viele Merkmale Sie wahrscheinlich benötigen, können Sie eine einfache Bitmaske für Objekte verwenden, deren unterschiedliche Bits unterschiedlichen Merkmalen entsprechen:

000001 = holdable
000010 = weapon
000100 = breakable
001000 = throwable
010000 = solids container
100000 = liquids container

Anschließend können Sie einfache Bittests durchführen, um festzustellen, ob ein Objekt für eine bestimmte Funktion verwendet werden kann.

"Glasflasche" kann also einen Wert von 101111 haben, was bedeutet, dass sie haltbar ist, als Waffe verwendet werden kann, leicht zerbricht, man sie werfen kann und Flüssigkeiten enthalten kann.

Jeder Editor, den Sie für Elemente erstellen, kann dann über einfache Kontrollkästchen verfügen, um Merkmale für ein Objekt zu aktivieren / deaktivieren.


1
Ich mag die Idee, weil sie es einem Element ermöglicht, seine eigenen Merkmale zu speichern, und ich weiß nicht, dass ich die Datenbank nach den Merkmalen durchsuchen muss, aber ich bin mir nicht sicher, wie ich das zum Laufen bringen soll in einem relationalen Kontext. Ich denke, dass jedes Bit den inkrementellen IDs der Merkmale in der Datenbank zugeordnet werden würde ...
Kzqai

Ich denke, Bitmasking ist für eine feste Anzahl von Merkmalen nützlicher?
Kzqai

Besonders gern. Was passiert, wenn Sie Ihr letztes "Bit" aufgebraucht haben? Wie einfach ist es, den Datentyp zu erhöhen, um Bit zu gewinnen und dieses durch Ihre App-Ebene zu sickern, oder eine Spalte hinzuzufügen und dasselbe zu tun? Ist Ihre spezielle Datenbank-Engine für die Indizierung von Bitoperationen gut abgestimmt? In einer relationalen Datenbank ist es am besten, mit Datenspalten atomar zu bleiben. Fassen Sie nicht mehrere Domänen in einer Spalte zusammen. Sie können die Vorteile der Plattform nicht nutzen.
Alphadogg

1
Wenn Sie eine Nachschlagetabelle in der Datenbank für die Merkmale wünschen (wahrscheinlich eine gute Idee, da Sie sie dann dynamisch zu jedem Editor hinzufügen können), dann hätte sie nur so etwas: ID, Bitmaske, Beschreibung. 1,1, "Holdable"; 2,2, "Waffe"; 3,4, "Breakable" usw. In Bezug auf die feste Anzahl ist dies wahr. Wenn Sie jedoch ein 64-Bit-Int verwenden, sollten Sie über ausreichend Spielraum verfügen.
Muttley

1

In unserem Projekt haben wir item_attributes für die verschiedenen "zusätzlichen Daten", die ein Artikel haben kann. Es ist ungefähr so ​​angelegt:

item_id | attribute_id    | attribute_value | order 
1        25 (attackspeed)       50             3    

Dann haben wir eine Attributtabelle, die so aussieht:

id |   name       | description
1    attackspeed    AttackSpeed:

Ari Patrick hat jedoch Recht, letztendlich sind relationale DBs nicht dafür gemacht. Der Nachteil ist, dass wir einige ziemlich komplexe Verfahren haben, um neue Elemente zu generieren (über ein externes Tool - was ich sehr empfehle. Versuchen Sie nicht, diese manuell hinzuzufügen, Sie werden sich nur verwirren).

Die andere Option, die Sie haben, ist die Verwendung einer Skriptsprache zum Erstellen der Elementvorlagen. Anschließend können Sie diese einfach analysieren und zum Erstellen neuer Elemente verwenden. Natürlich müssen Sie die Artikeldaten immer noch in der Datenbank speichern, aber an diesem Punkt müssen Sie sich nicht mehr um die Besonderheiten beim Erstellen neuer Artikel kümmern. Sie können so ziemlich nur eine alte Skriptdatei kopieren, einige Informationen ändern und Sie sind gut gehen.

Ehrlich gesagt, wenn wir die Erstellung neuer statischer Elemente wiederholen würden, würden wir wahrscheinlich einen viel einfacheren Ansatz mit Skriptelementvorlagen wählen.


1

Dies ist eine typische Viele-zu-Viele-Beziehung, die für eine leistungsfähige relationale Datenbank nicht allzu esoterisch ist. Sie haben viele Merkmale für ein Objekt, und jedes Merkmal kann von einem oder mehreren verschiedenen Objekttypen verwendet werden. Modellieren Sie drei Relationen (Tabellen), von denen eine eine Assoziationsrelation ist, und Sie sind fertig. Durch eine ordnungsgemäße Indizierung können Sie schnell Daten lesen.

Überlagern Sie Ihren Code mit einem ORM, und es sollten nur sehr wenige Probleme zwischen DB und Middleware auftreten. Viele ORMs können die Klassen auch selbst automatisch generieren und werden so noch "unsichtbarer".

Für die NoSQL-Datenbanken gibt es keinen Grund, warum Sie dies nicht tun können. Es ist derzeit in Mode, für diese Technologie in Handelslappen und Blogs zu jubeln, aber sie haben eine Reihe eigener Probleme: relativ unreife Plattformen, ideal für einfache, selten geänderte Lesevorgänge (wie ein bis viele Twits in einem Profil), aber Schlecht für komplexe dynamische Lese- oder Aktualisierungsvorgänge, schlechte unterstützende Toolchain, redundante Daten und die damit verbundenen Integritätsprobleme usw. Sie bieten jedoch den Vorteil einer besseren Skalierbarkeit, da sie in unterschiedlichem Maße Transaktionsfunktionen und deren Overhead vermeiden und Modelle für Verteilung / Replikation einfacher sind .

Der übliche Hobgoblin zwischen relationalen Datenbanken und NoSQL-Datenbanken ist die Leistung. Verschiedene RDMBS haben unterschiedliche Overhead-Grade, wodurch sie für die Skalierung auf die Ebenen von Facebook oder Twitter weniger bevorzugt werden. Es ist jedoch sehr unwahrscheinlich, dass Sie mit diesen Problemen konfrontiert werden. Selbst dann können einfache SSD-basierte Serversysteme die Leistungsdebatte unbrauchbar machen.

Lassen Sie uns klar sein: Die meisten NoSQL-Datenbanken sind grundsätzlich verteilte Hash-Tabellen und beschränken Sie auf die gleiche Weise wie eine Hash-Tabelle in Ihrem Code, d. H. Nicht alle Daten passen gut in dieses Modell. Das relationale Modell ist viel leistungsfähiger für die Modellierung von Beziehungen zwischen Daten. (Der verwirrende Faktor ist, dass die meisten RDBMS Legacy-Systeme sind, die schlecht auf die Anforderungen der beliebten 0,0001% des Webs abgestimmt sind, nämlich Facebook et al.)


Wenn Sie gemeinsam auf sie verweisen, sollten Sie nicht einmal über Datenbanken sprechen. NoSQL ist keine Entität, die sinnvoll diskutiert werden kann. Es ist eine nutzlose Massenreferenz, die SQL-Fanbois verwenden, um die fehlerhafte Logik anzuwenden, dass, wenn einer Datenbank dieser definierten Gruppe eine Funktion fehlt, allen diese Funktion fehlt.
aaaaaaaaaaaa

NoSQL ist der Begriff, den NoSQL-Drücker angepasst haben. Ich weiß nicht warum, es ist nicht sehr beschreibend. Aber es ist keine abwertende Wirkung. Nachdem ich mit mehreren zusammengearbeitet habe, denke ich, dass Alphadoggs Beschreibung von ihnen fair ist.

Vielleicht war mein Kommentar ein bisschen hart, trotzdem hasse ich diesen Namen und diese Gruppierung. Es ist unmöglich, eine qualifizierte Debatte über die Feinheiten verschiedener Datenbanksysteme zu führen, wenn die Leute diese vereinfachte Weltanschauung beibehalten.
aaaaaaaaaaa

@eBusiness: Ich finde Ihren Kommentar amüsant, da es das Anti-RDBMS-Lager ist, falls es eines gibt, das seine Gruppe von Technologien als "NoSQL" selbst gesalbt hat. Zugegeben, viele von ihnen möchten, dass dieser Name im Nachhinein veraltet ist. Zumal viele von ihnen endlich SQL über ihre physischen Implementierungen legen. Ich habe Ihren Kommentar nicht als hart empfunden, oder ich habe eine dicke Haut, Ihre Wahl! :) Ich meine, man kann über die Tea Party sprechen, warum nicht die NoSQL-Gruppe von Datenbanken?
Alphadogg

Das ist fair, ich erkenne, dass die Beziehung total viele zu viele ist. Das, was mich davon abhält, es in einem wirklich normalisierten Stil zu erstellen, ist der Gedanke, dass das "Zeug", aus dem ein Gegenstand bestehen würde, dann auf mindestens zwei Tische verteilt wird. Ich mag die Idee nicht, keine atomaren Inserts erstellen zu können, denke ich.
Kzqai

0

Hier finde ich modernere OP-Mapper wirklich nützlich, wie Entity Framework 4 und seine (CTP) Code-First-Funktion . Sie schreiben einfach die Klassen und ihre Beziehungen in regulären Code und ohne sie zu dekorieren oder manuell auszuführen, generiert EF den Backing Store im SQL-Format für Sie, mit den erforderlichen Verknüpfungstabellen und allem ... es setzt wirklich Kreativität frei ^^


Nun, ich werde den Code und die Klassen und all das erst im Code erstellen ... ... muss das erst in die vorhandene Datenbankstruktur übersetzen.
Kzqai

0

Folgendes überlege ich mir jetzt:

Da jedes "Merkmal" ohnehin Änderungen im Code erfordert, habe ich beschlossen, die Merkmale (und alle erforderlichen Standarddaten) (zumindest für den Moment) im Code selbst zu belassen.

Z.B $traits = array('holdable'=>1, 'weapon'=>1, 'sword'=>array('min_dam'=>1, 'max_dam'=>500));

Anschließend erhalten Elemente ein Feld "trait_data" in der Datenbank, das die json_encode()Funktion verwendet, um im JSON-Format gespeichert zu werden.

item_id | item_name | item_identity | traits
1 | Katana | katana | "{"holdable":1,"weapon":1,"sword":{"min_dam":1,"max_dam":1234,"0":{"damage_type":"fire","min_dam":5,"max_dam":50,"type":"thrown","bob":{},"ids":[1,2,3,4,5,6,7]}}}"

Es ist geplant, dass Elemente alle Standardstatistiken von ihren übergeordneten Merkmalen erben und nur Override-Merkmale aufweisen, die Unterschiede zu den als Standard festgelegten Merkmalen angeben.

Der Nachteil des Merkmalsfeldes ist, dass ich den JSON-Teil zwar von Hand bearbeiten kann, aber es mit Daten in der Datenbank nicht wirklich einfach oder sicher ist.


1
Was passiert, wenn Sie ein neues Merkmal einführen? Wie oft könnte das passieren? Was wären die nachgelagerten Auswirkungen auf Ihre Code-Wartungs-Workload? Im Gegensatz zum Speichern als Viele-zu-Viele-Verfahren, bei dem Ihre Objektinstanzen dynamisch aufgebaut werden (über die von Ihnen gewählte ORM), um diese Daten zu speichern.
Alphadogg

Danke, das ist ein guter Punkt. Das Hinzufügen neuer Eigenschaften wird nicht trivial sein. Sie haben zu meiner Analyse Lähmung hinzugefügt. : p
Kzqai

Entschuldigung, aber das ist ziemlich kritisch. Sie müssen es nur durchdenken. Modellieren Sie die Übung in Ihrem Kopf darüber, was Sie tun müssen, wenn einige Waffen aktualisiert werden müssen, um eine neue Eigenschaft hinzuzufügen, damit Ihre Spielverbesserung funktionieren kann.
Alphadogg

-1

Das ist ein bisschen hackig, und ich kann nicht garantieren, dass es ein gutes DB-Design ist. Meine DB-Klassen sind schon eine Weile her und fallen mir nicht so schnell ein. Wenn jedoch garantiert wird, dass Elemente weniger als 10 Elemente enthalten, können Sie jedem Element ein Attribut1-Feld und ein Attribut2-Feld usw. bis zu Attribut10 zuweisen. Es würde Ihre Notwendigkeit für die Viele-zu-Viele-Elementattributtabelle auf Kosten der Begrenzung der Anzahl von Attributen beseitigen.

Wenn ich zurückblicke, bin ich mir ziemlich sicher, dass es ein schreckliches Design ist, aber es bedeutet, dass Sie bei einer komfortablen relationalen Datenbank bleiben können und nicht Neuland betreten müssen. Es liegt an Ihnen, zu entscheiden, ob sich der Kompromiss lohnt.


Das ist schreckliches Design, mach es niemals. Sie sind besser dran, wenn Sie keine Datenbank verwenden.
ZorbaTHut

-1

Nevermind gab eine gute Antwort, aber ich frage mich, brauchen Sie dafür überhaupt eine Datenbank? Das Speichern aller Daten in einer einfachen Datei und das Laden in das Programm beim Start scheint die intelligenteste Methode zu sein.

Bearbeiten:
Richtig, in einer zustandslosen anforderungsgesteuerten Umgebung sollten Sie die Daten besser in einer Datenbank aufbewahren. Schreiben Sie Ihre Daten in eine Datei und schreiben Sie einen Code, um daraus eine Datenbank des vom Typ Nevermind vorgeschlagenen Typs zu machen.

Wenn die Anzahl der Objekte nicht zu groß ist, kann es die schnellste Methode sein, das Los buchstäblich in einer Codedatei zu deklarieren.


Ähm, ich habe bereits eine Datenbank in Betrieb und in den Rest der Site integriert.
Kzqai
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.