Jak modelować wiele „zastosowań” (np. Broń) dla ekwipunku użytkowego / obiektu / przedmiotów (np. Katana) w relacyjnej bazie danych

10

Pracuję więc nad rozszerzeniem wykorzystania przedmiotów na stronie www.ninjawars.net i nie jestem pewien, jak elastycznie przedstawiać je w relacyjnej bazie danych, z której korzystamy.

Być może szczekam na niewłaściwym drzewie, więc możesz sugerować w innych kierunkach, ale obecnie myślę, że każdy element powinien mieć relacyjne „tagi”.

Na przykład Katana jest obecnie wierszem w bazie danych „przedmiotów”. Aby uczynić go bronią i rzeczą do trzymania, myślałem, że będę miał bazę danych „cech” i tabelę item_traits, która po prostu się między nimi połączy.

// 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

Nie jestem do końca pewien, jak wymodelować dodatkowe dane, które się pojawią (np. Obrażenia, które wyrządzi miecz, typ uszkodzenia itp.).

Nie jestem też szczególnie szczęśliwy, że cały przedmiot będzie przechowywany w więcej niż jednym miejscu, np. Aby utworzyć kopię przedmiotu o innej nazwie, np. „Krótkim mieczem”, musiałbym skopiować z wiele tabel, aby utworzyć zduplikowany element.

Czy istnieje lepszy sposób na rozłożenie tego, czego mi brakuje?

Edycja: Powinienem zauważyć, że mam już bazę danych postgresql używaną na stronie, dlatego chcę jej używać do przechowywania danych.

Edycja: Dodałem odpowiedź dotyczącą implementacji, na którą obecnie patrzę.

Kzqai
źródło

Odpowiedzi:

10

Będę łagodnie nie zgadzać się ze wszystkimi i powiem, że podejście relacyjne jest tutaj rozsądne. Interesujące jest to, że przedmioty mogą mieć wiele ról. Głównym problemem będzie to, że odwzorowanie między tym układem relacyjnym a układem OO w kodzie nie będzie wydawać się „naturalne”, ale myślę, że po stronie bazy danych wiele ról można wyrazić w czysty sposób (bez dziwnego kodowania lub redundancji, po prostu łączy) .

Pierwszą rzeczą, którą należy podjąć, jest to, jaka część danych jest specyficzna dla elementu i ile jest dzielona przez wszystkie elementy danego typu.

Oto co bym zrobił, gdyby wszystkie dane były specyficzne dla elementu:

// 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  | ...

W tym projekcie każdy element znajduje się w tabeli Przedmioty, wraz z atrybutami, które mają wszystkie (lub większość) przedmiotów. Każda dodatkowa rola, jaką może odgrywać przedmiot, to osobny stół.

Jeśli chcesz użyć go jako broni, poszukaj go w tabeli broni. Jeśli tam jest, to nadaje się jako broń. Jeśli go nie ma, nie można go użyć jako broni. Istnienie zapisu mówi ci, czy to broń. A jeśli tam jest, przechowywane są tam wszystkie atrybuty specyficzne dla broni. Ponieważ te atrybuty są przechowywane bezpośrednio zamiast w jakiejś zakodowanej formie, będziesz mógł wykonywać z nimi zapytania / filtry. (Na przykład, na stronie metryki gry możesz chcieć agregować graczy według typu obrażeń od broni, a możesz to zrobić z niektórymi złączeniami i grupami według typu obrażeń).

Przedmiot może mieć wiele ról i może istnieć w więcej niż jednym stole dla poszczególnych ról (w tym przykładzie zarówno broń, jak i oświetlenie).

Jeśli jest to po prostu boolean typu „czy można to utrzymać”, umieściłbym to w tabeli Przedmioty. Może warto tam umieścić w pamięci podręcznej „czy to broń” itp., Abyś nie musiał sprawdzać broni i innych tabel ról. Dodaje jednak nadmiarowość, dlatego należy zachować ostrożność, aby zachować synchronizację.

Zalecenie Ari, aby mieć dodatkową tabelę według typu, może być również zastosowane w tym podejściu, jeśli niektóre dane nie będą się różnić dla poszczególnych pozycji. Na przykład, jeśli obrażenia od broni nie różnią się w zależności od przedmiotu, ale role wciąż różnią się w zależności od przedmiotu, możesz podzielić dzielone atrybuty broni na tabelę:

// 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

Innym podejściem byłoby, gdyby role odgrywane przez przedmioty nie różniły się w zależności od przedmiotu, ale tylko od rodzaju przedmiotu. W takim przypadku umieścisz item_type w tabeli Items i możesz przechowywać właściwości takie jak „czy to broń” i „czy można ją trzymać” oraz „czy to światło” w tabeli ItemTypes. W tym przykładzie sprawiam, że nazwy przedmiotów nie różnią się w zależności od przedmiotu:

// 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

Jest prawdopodobne, że typy przedmiotów i typy broni nie zmieniają się w trakcie gry, więc możesz po prostu załadować te tabele do pamięci raz i wyszukać te atrybuty w tabeli skrótów zamiast z łączeniem z bazą danych.

amitp
źródło
+1. To jedyna odpowiedź, która używa relacyjnej bazy danych jako relacyjnej bazy danych. Wszystko inne niż to lub inna skrajność sugestii bloba Neverminda i samo użycie DB jako magazynu danych, to okropne plany.
+1 Ale te podejścia wydają się być mało elastyczne. Przepraszam, jeśli zabrzmią niekonsekwentnie, ale chcę móc stworzyć struktury bazy danych dla elementów zasadniczo raz ... ... a następnie kodować więcej funkcji dla elementów, tworzyć więcej wstawek do bazy danych dla elementów, ale nie muszę zmieniać baza danych ponownie w przyszłości (oczywiście z nielicznymi wyjątkami).
Kzqai
Jeśli chcesz, aby relacyjna baza danych wiedziała o twoich polach i zoptymalizowała ich reprezentację, musisz je gdzieś dodać. To jest jak typy statyczne. Jeśli chcesz, aby Twój kompilator wiedział o twoich polach i zoptymalizował ich reprezentację, musisz zadeklarować typy. Alternatywą jest podejście dynamicznie typowane, używane przez niektóre bazy danych dokumentów lub w pewien sposób kodujące dane w relacyjnej bazie danych. Baza danych nie będzie wiedziała, jakie są pola, ani nie będzie w stanie zoptymalizować ich przechowywania, ale zyskasz pewną elastyczność.
amitp
4

Niestety, w takich sytuacjach relacyjne bazy danych (takie jak SQL) są niewystarczające, a nierelacyjne bazy danych (takie jak MongoDB ) przodują. Biorąc to pod uwagę, nie jest niemożliwe modelowanie danych w relacyjnej bazie danych, a ponieważ wydaje się, że twoja baza kodów jest już zależna od SQL, oto model, z którym bym poszedł:

Zamiast tworzyć element i korzystać z tabeli, utwórz tabelę i tabelę referencyjną „[item] _type” dla każdego typu elementu.

Oto kilka przykładów:

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

To rozwiązanie zapewnia wiele długoterminowej elastyczności i skalowalności, zmniejsza (jeśli nie eliminuje) zmarnowane miejsce i jest samo dokumentujące (w przeciwieństwie do „item_use_data”). Wymaga to nieco większej konfiguracji po stronie programisty, ale moim zdaniem jest to najbardziej eleganckie rozwiązanie dostępne w sytuacjach, w których musisz użyć relacyjnej bazy danych do przechowywania danych. Ogólnie rzecz biorąc, nierelacyjne bazy danych są znacznie lepsze do tworzenia gier, ponieważ są bardziej elastyczne w sposobie modelowania danych, a jednocześnie są bardziej wydajne niż bazy danych oparte na SQL - co czyni je wyborem „win-win”.

Edycja 1: Poprawiono błąd w polu potion_type_id

Edycja 2: Dodano więcej szczegółów na temat nierelacyjnych i relacyjnych baz danych, aby zapewnić dodatkową perspektywę

Ari Patrick
źródło
Tak naprawdę nie widzę dużej elastyczności w tym systemie. Na przykład, gdybym chciał szklaną fiolkę, która mogłaby być używana jako broń i być „ostra” ... ... nie miałbym szczęścia. Ponadto dla każdego nowego typu elementu musiałbym faktycznie stworzyć dla niego strukturę bazy danych. Nawet jeśli będzie tylko jeden lub dwa tego typu.
Kzqai,
Punkty, które poruszasz, są bardzo ważne i podkreślają dodatkowe przykłady, dlaczego relacyjne bazy danych nie są odpowiednie dla tej konkretnej sytuacji. Przedstawiony przeze mnie model pokazuje jedynie najlepszy sposób ułożenia danych w taki sposób, aby zachować pamięć i zachować funkcjonalność SQL. Aby przechowywać przedmioty różnego typu, najlepszym sposobem przedstawienia danych w tym modelu byłoby utworzenie tabeli potion_weapon z odpowiednimi właściwościami mikstury i broni. Ponownie, to rozwiązanie NIE jest idealne, ale jest najbardziej eleganckim rozwiązaniem podczas korzystania z relacyjnej bazy danych.
Ari Patrick,
@Ari: Nie zamierzano lekceważyć, ale jego problemem jest właśnie to, dlaczego podejście relacyjne jest ważniejsze, nie mniej. Powszechnie wiadomo, że bazy danych NoSQL (lub NoRel) doskonale nadają się do dużych odczytów, rozproszonych / bardzo dostępnych danych lub źle zdefiniowanych schematów. Ten przypadek jest po prostu klasycznym skojarzeniem wiele do wielu, a dbs, takie jak Mongo, nie robią tego tak dobrze, jak RDBMS. Zobacz stackoverflow.com/questions/3332093/…
alphadogg
@alphadogg Jak to jest relacja wiele do wielu? W bazie danych broń zna typy broni, ale typy broni nie muszą wiedzieć o broni, z którą są powiązane. Jeśli z jakiegoś powodu chcesz poznać wszystkie bronie określonego typu, po prostu napisz zapytanie, które iteruje zbiór dokumentów o broni.
Ari Patrick
@Ari: W pytaniu PO jedna broń może mieć wiele rodzajów, a jeden typ może być powiązany z wieloma broniami. Na przykład miksturę i miecz można trzymać. Miecz jest zarówno do trzymania, jak i do broni.
alphadogg
3

Po pierwsze, zrzuć podejście do dziedziczenia obiektowego i przejdź do systemu opartego na komponentach .

Gdy to zrobisz, układ SQL staje się nagle znacznie łatwiejszy. Dla każdego typu elementu masz jedną tabelę ze wspólnym numerem identyfikacyjnym. Jeśli potrzebujesz przedmiotu nr 17, poszukaj „ID przedmiotu 17” w każdej tabeli. Każda tabela z kluczem jest dodawana do komponentu.

Twoja Tabela Przedmiotów zawiera wszystkie wymagane dane dotyczące przedmiotów (nazwa, cena sprzedaży, waga, rozmiar, wszystko inne, które są wspólne dla wszystkich przedmiotów.) Twoja Tabela Broni zawiera wszystkie odpowiednie dane dotyczące broni, twoja Tabela Mikstur zawiera wszystkie odpowiednie dane w przypadku mikstur tabela zbroi zawiera wszystkie odpowiednie dane dla zbroi. Chcesz napierśnika, jest to pozycja w Przedmiotu i pozycja w Zbroi. Chcesz półki na miecze, którą możesz wypić, po prostu umieść wpis w każdym stoliku, i tak dalej.

Pamiętaj, że ten sam wzór nie jest szczególnie specyficzny dla przedmiotu - możesz go użyć do stworzenia, strefy, wszystkiego, czego możesz chcieć. Jest zaskakująco wszechstronny.

ZorbaTHut
źródło
2

Używanie SQL było poważnym błędem. Absolutnie NIE nadaje się do przechowywania statycznych danych projektowych gier.

Jeśli nie możesz odejść od SQL, rozważenie przechowywania elementów w serializowanym pliku. To znaczy

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

Oczywiście jest to brzydkie i wyrzuca wszystkie „drobiazgi” SQL przez okno, ale czy naprawdę ich potrzebujesz ? Najprawdopodobniej i tak odczytasz wszystkie swoje dane przedmiotów na początku gry i nigdy SELECTprzez nic innego item_id.

Nieważne
źródło
3
Ponieważ (z mojego zrozumienia) gra jest wieloosobowa i obsługuje PvP, istnieje prawdopodobieństwo, że większość informacji o grze nie jest przechowywana na kliencie. Jeśli jest to dokładne, to za każdym razem, gdy dane są odczytywane z tabeli, będzie musiał zostać zdezrializowany, zanim będzie zdalnie użyteczny. W rezultacie ten format sprawia, że ​​zapytania o ich właściwości są BARDZO drogie; na przykład: jeśli chcesz odzyskać wszystkie przedmioty typu „broń”, musisz pobrać każdy przedmiot, deserializować każdy z nich, a następnie ręcznie przefiltrować według typu „broń”, zamiast uruchamiać proste zapytanie .
Ari Patrick,
1
Z mojego doświadczenia wynika, że ​​wszystkie przedmioty są wczytywane do pamięci podręcznej w początkowej fazie gry. Tak więc deserializujesz je tylko raz przy starcie i później nie korzystasz z bazy danych. Jeśli tak nie jest w tym przypadku, to zgadzam się, że przechowywanie serializowanych obiektów jest złym pomysłem.
Nevermind,
Hmmm, jedyne, co pozostawia mi interfejs - wymagany - w celu edycji danych, co byłoby niewygodne.
Kzqai,
2

W zależności od tego, ile cech prawdopodobnie będziesz potrzebować, możesz użyć prostej maski bitowej dla obiektów o różnych bitach odpowiadających różnym cechom:

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

Następnie możesz wykonać proste testy bitowe, aby sprawdzić, czy obiekt może być użyty do określonej funkcji.

Tak więc „szklana butelka” może mieć wartość 101111, co oznacza, że ​​można ją trzymać, może być używana jako broń, łatwo pęka, można ją wyrzucić i może zawierać płyny.

Każdy edytor utworzony dla elementów może następnie mieć prosty zestaw pól wyboru, aby włączyć / wyłączyć cechy obiektu.

Muttley
źródło
1
Podoba mi się ten pomysł, ponieważ pozwala on przedmiotowi zachować własne cechy i nie wiem, czy będę musiał przeszukiwać bazę danych w poszukiwaniu cech, ale tak naprawdę nie jestem pewien, jak to zrobić w kontekście relacyjnym.
Wydaje
Wydaje mi się jednak, że maskowanie bitów jest bardziej przydatne w przypadku określonej liczby cech?
Kzqai,
Bardzo tak. Co się stanie, jeśli wykorzystasz swój ostatni „bit”? Jak łatwo jest zwiększyć typ danych, aby uzyskać bit i przenikać to przez warstwę aplikacji, lub dodać kolumnę i zrobić to samo? Czy Twój silnik bazy danych jest dobrze dostosowany do indeksowania operacji bitowych? W relacyjnej bazie danych najlepiej zachować atomowość z kolumnami danych. Nie zbijaj wielu domen w jedną kolumnę. Nie możesz czerpać korzyści z platformy.
alphadogg
1
Jeśli chcesz tabelę odnośników w DB dla cech (prawdopodobnie dobrym pomysłem, ponieważ możesz wtedy dynamicznie dodać je do dowolnego edytora), to będzie po prostu mieć coś takiego: id, maska ​​bitowa, opis. 1,1, „Holdable”; 2,2 „Broń”; 3,4, „Breakable” itd. Jeśli chodzi o ustaloną liczbę, tak, to prawda. Ale jeśli używasz 64-bitowej int, powinieneś mieć duży zakres.
Muttley,
1

W naszym projekcie mamy item_attributes dla różnych „dodatkowych danych”, które może mieć element. Przedstawiono coś takiego:

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

Następnie mamy tabelę atrybutów, która wygląda tak:

id |   name       | description
1    attackspeed    AttackSpeed:

Ari Patrick ma rację, ostatecznie relacyjne bazy danych nie są do tego stworzone. Minusem jest to, że mamy dość skomplikowane procedury generowania nowych przedmiotów (wykonywane za pomocą zewnętrznego narzędzia - które bardzo polecam, nie próbuj ręcznie dodawać tych elementów, tylko się pomylisz)

Inną dostępną opcją jest używanie języka skryptowego do tworzenia szablonów elementów, a następnie można je łatwo analizować i używać do tworzenia nowych elementów. Oczywiście nadal musisz zapisać dane pozycji w bazie danych, ale w tym momencie nie musisz się martwić o specyfikę tworzenia nowych elementów, możesz po prostu skopiować stary plik skryptu, zmienić niektóre informacje i jesteś dobry iść.

Szczerze mówiąc, jeśli mielibyśmy przerobić sposób tworzenia nowych elementów statycznych, prawdopodobnie zastosowalibyśmy znacznie prostsze podejście przy użyciu szablonów skryptów elementów.

Kyle C.
źródło
1

To typowa relacja wiele do wielu, nic zbyt ezoterycznego dla jakiejkolwiek zdolnej relacyjnej bazy danych. Masz wiele cech dla jednego obiektu, a każda cecha może być używana przez jeden lub więcej różnych typów obiektów. Modeluj trzy relacje (tabele), przy czym jedna jest relacją powiązania i gotowe. Właściwe indeksowanie zapewni szybkie odczytywanie danych.

Ułóż ORM w kodzie i powinieneś mieć bardzo mało problemów z przechodzeniem między DB a oprogramowaniem pośrednim. Wiele ORM jest w stanie również automatycznie generować klasy, przez co stają się jeszcze bardziej „niewidoczne”.

Jeśli chodzi o bazy danych NoSQL, nie ma powodu, dla którego nie można tego zrobić. Obecnie modne jest dopingowanie tej technologii w szmatach handlowych i blogach, ale pojawiają się one z mnóstwem własnych problemów: stosunkowo niedojrzałe platformy, idealne do prostych, rzadko zmienianych odczytów (jak jeden do wielu twits w profilu), ale słaba dla złożonych dynamicznych odczytów lub aktualizacji, słaba obsługa łańcucha narzędzi, redundantne dane i towarzyszące im problemy z integralnością itp. Jednak oferują atrakcyjność lepszej skalowalności, ponieważ unikają w różnym stopniu możliwości transakcyjnych i ich kosztów ogólnych oraz łatwiejszych modeli dystrybucji / replikacji .

Zwykłym hobgoblinem relacyjnych baz danych vs baz danych NoSQL jest wydajność. Różne RDMBS mają różne stopnie obciążenia, co czyni je mniej preferowanymi do skalowania do poziomów Facebooka lub Twittera. Jednak jest bardzo mało prawdopodobne, że napotkasz te problemy. Nawet wtedy proste systemy serwerowe oparte na SSD mogą sprawić, że debata na temat wydajności będzie bezużyteczna.

Wyjaśnijmy: większość baz danych NoSQL to fundamentalnie dystrybuowane tabele skrótów, które ograniczą cię w taki sam sposób, jak w przypadku kodu skrótu w twoim kodzie, tj. nie wszystkie dane dobrze pasują do tego modelu. Model relacyjny jest znacznie potężniejszy do modelowania relacji między danymi. (Problemem jest fakt, że większość RDBMS to starsze systemy, które są źle dostrojone do wymagań popularnego 0,0001% internetu, a mianowicie Facebooka i in.)

alphadogg
źródło
Jeśli zamierzasz się do nich odnosić zbiorowo, nie zawracaj sobie głowy mówieniem o bazach danych. NoSQL nie jest jednostką, którą można w znaczący sposób omówić, jest bezużytecznym odniesieniem do masy, które używają fanbois SQL w celu zastosowania błędnej logiki, że jeśli jedna baza danych tej zdefiniowanej grupy nie ma żadnej cechy, to wszystkie one nie mają tej cechy.
aaaaaaaaaaaa
NoSQL to termin, który pchacze NoSQL postanowili dostosować. Nie wiem dlaczego, nie jest zbyt opisowy. Ale to nie jest jakiś pejoratyw. Po pracy z kilkoma myślę, że ich opis alphadogg jest uczciwy.
Być może mój komentarz był nieco ostry, ale nie znoszę tej nazwy i grupowania, niemożliwa jest kwalifikowana debata na temat drobniejszych szczegółów różnych systemów baz danych, gdy ludzie zachowują ten uproszczony widok świata.
aaaaaaaaaaaa
@eBusiness: Uważam twój komentarz za zabawny, biorąc pod uwagę, że to obóz anty-RDBMS, jeśli istnieje, sam namaścił swoją grupę technologii jako „NoSQL”. Trzeba przyznać, że wielu z nich chciałoby, aby ta nazwa była przestarzała, z perspektywy czasu. Zwłaszcza, że ​​wielu z nich w końcu nakłada warstwy SQL na swoje fizyczne implementacje. Jeśli chodzi o mówienie o nich, nie wziąłem twojego komentarza za szorstki lub mam grubą skórę, twój wybór! :) Mam na myśli, że można mówić o Tea Party, dlaczego nie grupa baz danych NoSQL?
alphadogg
To sprawiedliwe, zdaję sobie sprawę, że relacja jest bardzo liczna dla wielu. Rzeczą, która powstrzymuje mnie przed stworzeniem go w prawdziwie znormalizowanym stylu, jest myśl, że „rzeczy”, które utworzą przedmiot, zostaną rozłożone na co najmniej dwóch stołach. Myślę, że nie podoba mi się pomysł, że nie mogę tworzyć atomowych wstawek.
Kzqai,
0

W tym miejscu uważam, że bardziej przydatne są nowoczesne mapery OR, takie jak Entity Framework 4 i jego pierwsza funkcja kodu (CTP) . Po prostu piszesz klasy i relacje między nimi w zwykłym kodzie i nawet bez ozdabiania ich lub ręcznego uruchamiania narzędzi, EF wygeneruje dla ciebie magazyn kopii zapasowych w formacie SQL, z wymaganymi tabelami linków i wszystkim ... naprawdę uwalnia kreatywność imo ^^

Oskar Duveborn
źródło
Cóż, najpierw utworzę kod i klasy, a wszystko to w kodzie ... ... po prostu muszę to przetłumaczyć na istniejącą strukturę bazy danych.
Kzqai,
0

Oto, co teraz rozważam:

Ponieważ każda „cecha” w zasadzie i tak wymaga zmian w kodzie, postanowiłem po prostu zachować cechy (i wszelkie wymagane dane domyślne) w samym kodzie (przynajmniej na razie).

Na przykład $traits = array('holdable'=>1, 'weapon'=>1, 'sword'=>array('min_dam'=>1, 'max_dam'=>500));

Następnie elementy otrzymują w bazie danych pole „trait_data”, które użyje json_encode()funkcji do zapisania w formacie JSON.

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]}}}"

Planuje się, że przedmioty odziedziczą wszystkie domyślne statystyki z ich cech nadrzędnych i będą miały tylko cechy zastępowania, które określają różnice w stosunku do tego, co cechy ustawiono jako domyślne.

Minusem pola cech jest to, że chociaż mógłbym ręcznie edytować część json ... ... to nie będzie tak łatwo ani bezpiecznie zrobić z danymi znajdującymi się w bazie danych.

Kzqai
źródło
1
Co się stanie, gdy wprowadzisz nową cechę? Jak często to się zdarza? Jaki byłby dalszy wpływ na obciążenie związane z konserwacją kodu? Porównaj to z przechowywaniem ich jako wielu do wielu, dzięki czemu instancje obiektów są dynamicznie budowane (poprzez wybór ORM) w celu przechowywania tych danych.
alphadogg
Dzięki, to dobra uwaga, dodawanie nowych cech nie będzie trywialne. Dodałeś do mojego paraliżu analizy. : p
Kzqai
Przepraszam, ale to dość krytyczne. Musisz to przemyśleć. Modeluj w myślach to, co musisz zrobić, gdy trzeba zaktualizować niektóre bronie, aby dodać nową cechę, aby ulepszenie gry mogło działać.
alphadogg
-1

Jest to trochę zuchwałe i nie daje żadnych gwarancji, że jest to dobry projekt DB; moje lekcje DB były jakiś czas temu i nie przychodzą mi szybko do głowy. Ale jeśli gwarantowane jest, że przedmioty zawierają, powiedzmy, mniej niż 10 przedmiotów, możesz nadać każdemu przedmiotowi pole atrybut1, pole atrybut2 itd. Aż do atrybutu10. Wyeliminowałoby to potrzebę korzystania z tabeli atrybutów wiele do wielu kosztem ograniczenia liczby atrybutów.

Patrząc wstecz na to, jestem pewien, że to okropny projekt, ale oznacza to, że możesz trzymać się wygodnej relacyjnej bazy danych i nie musisz wchodzić na nieznane terytorium. Od Ciebie zależy, czy kompromis jest tego wart.

Gregory Avery-Weir
źródło
To okropny projekt, nigdy tego nie rób. Lepiej byłoby po prostu nie korzystać z bazy danych.
ZorbaTHut
-1

Nevermind dał dobrą odpowiedź, ale zastanawiam się, czy potrzebujesz do tego bazy danych? Przechowywanie wszystkich danych w zwykłym pliku i ładowanie ich do programu podczas uruchamiania wydaje się być najmądrzejszym sposobem na zrobienie tego.

Edytować:
, w środowisku bezstanowym opartym na żądaniach lepiej przechowywać dane w bazie danych. Zapisz dane w pliku i napisz fragment kodu, aby przekształcić go w bazę danych typu sugerowanego przez Nevermind.

Alternatywnie, jeśli liczba obiektów nie jest zbyt duża, deklarowanie partii dosłownie w pliku kodu może być najszybszą metodą.

aaaaaaaaaaaa
źródło
Err, mam już bazę danych w użyciu i zintegrowaną z resztą strony.
Kzqai,