noSQL - czy jest to prawidłowa opcja dla gry internetowej? [Zamknięte]


20

Z okazji i nudy postanowiliśmy wspólnie z przyjacielem stworzyć grę internetową. To jest pierwsza „gra”, którą stworzę, ponieważ zwykle programuję aplikacje internetowe w Django.

Zdecydowałem się na użycie tej samej struktury dla gry, ale nie jestem całkowicie pewien co do przechowywania danych, ponieważ nie mogę przewidzieć przyszłych wymagań i problemów związanych z DB. Ostatnio ruch noSQL zyskuje na sile i chciałbym zbadać ten obszar.

Dlatego mam następujące pytania:

  • Czy magazyn danych noSQL (oparty na dokumentach, taki jak MongoDB) byłby odpowiedni dla gry internetowej?
  • Jakie problemy mogą wystąpić przy użyciu konwencjonalnego RDBMS, takiego jak MySQL?
  • Jak zapewnić spójność danych ubezpieczeniowych między użytkownikami MongoDB, podczas gry lub w czasie, np. W pracy crona?

Przegląd gry: Typowa gra przygodowa, w której gracz walczy z potworami i zdobywa przedmioty.

  • Niektóre dane są statyczne dla wszystkich graczy: przedmioty, broń, mikstura, mapy itp.
  • Niektóre dane powiązane z odtwarzaczem: ekwipunek, dane (statystyki), postęp itp.
  • Gracz może potrzebować poznać statystyki i stan innego gracza
  • Zaplanowane zadania będą uruchamiane w określonych odstępach czasu


1
Problem z niektórymi bazami danych noSQL polega na tym, że nie mogą one szybko wykonywać zapytań nieprzewidzianych w czasie projektowania na ogromnych zestawach danych, takich jak dzienniki zdarzeń: gamedev.stackexchange.com/q/4465/450 Należy pamiętać, że bazy danych noSQL wymagają tego samego techniki przeciw iniekcji zapytań normalne niż normalne bazy danych.
Hendrik Brummermann

1
@nhnb: Jednym z fajnych sposobów na odtworzenie punktu jest „użycie relacyjnej bazy danych dla danych relacji i użycie bazy danych obiektu / dokumentu dla danych obiektu / dokumentu”. Niestety nie sądzę, że większość ludzi ma doświadczenie lub spędza dużo czasu na myśleniu o modelowaniu, co prowadzi do złych projektów bez względu na to, który wybiorą.

2
W odpowiedzi na pytanie „Czy NoSQL jest prawidłową opcją dla gier internetowych?” Uważam, że odpowiedź brzmi tak. Bazy danych NoSQL były wcześniej używane w grach internetowych (takich jak FarmVille) i oferują dużą elastyczność. Głównym punktem spornym tego pytania wydaje się być „co jest lepsze (NoSQL lub SQL)?”. Każdy system ma zalety i wady, ale oba są całkowicie uzasadnionymi opcjami. Jeśli szukasz szczegółowej listy zalet jednego systemu w stosunku do drugiego, możesz zapłacić programiście StackExchange vist. :)
Ari Patrick

Odpowiedzi:


21

Czy baza danych noSQL byłaby odpowiednia dla gry internetowej?

Absolutnie! Ogólnie rzecz biorąc, nierelacyjne bazy danych (takie jak MongoDB) są znacznie lepsze dla gier, ponieważ są bardziej elastyczne w sposobie modelowania danych, a jednocześnie są bardziej wydajne niż relacyjne bazy danych (takie jak SQL) - co czyni je „korzystnymi dla wszystkich” wybór.

Jakie problemy mogą wystąpić przy użyciu konwencjonalnego RDBMS?

Istnieją dwie główne wady korzystania z relacyjnych baz danych:

  • Brak elastyczności w sposobie modelowania danych
  • Występ

Brak elastyczności w sposobie modelowania danych jest poważną wadą, ponieważ użycie relacyjnej bazy danych zmusza do modelowania danych w celu dopasowania do potrzeb bazy danych, a nie bazy danych uwzględniającej potrzeby modelu. Rozważ na przykład, że tworzysz model przechowywania przedmiotów w grze za pomocą relacyjnej bazy danych i decydujesz się na następujący model:

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

Teraz zastanów się, jak trzeba zmodyfikować model, aby spełnić następujące czynności:

  • Dodaj nowy typ elementu
  • Stwórz broń z wieloma rodzajami broni
  • Utwórz przedmiot mikstury, który może być również używany jako broń

Z pewnością wszystkie te działania są wykonalne, ale nie będziesz najszczęśliwszą osobą podczas ich wykonywania i prawdopodobnie będziesz się zastanawiać: „czy istnieje lepsze rozwiązanie tego, co chcę zrobić?”, Kiedy możesz zaprojektuj znacznie bardziej elastyczny model w nierelacyjnej bazie danych.

Uwaga: jeśli nie wiesz, jak bazy danych oparte na dokumentach przechowują informacje, sprawdź ten link przed kontynuowaniem. Przedstawiony poniżej model zaprojektowano z wykorzystaniem logiki podobnej do przedstawionej we wspomnianym artykule.

db.itemTypes

name: Weapon
types: Sharp

name: Potion
types: HP, Mana

db.items

name: Short Sword
weapon
    type: Sharp (db.itemTypes reference)
    damage: 5

name: Healing Elixer
potion
    type:  HP (db.itemTypes reference)
    modifier: 5

name: Mana Drainer
potion
    type:  Mana (db.itemTypes reference)
    modifier: -5  

name:  Healing Potion Sword
potion
    type: HP (db.itemTypes reference)
    modifier: 10
weapon
    type: Sharp (db.itemTypes reference)
    damage: 15

Istnieje wiele dobrych artykułów na temat wydajności baz danych NoSQL w porównaniu z bazami SQL, ale tutaj jest jeden z przykładów aplikacji umożliwiających wykonywanie własnych testów: MongoDB vs. SQL Server 2008 Performance Showdown

Jak zapewnić spójność danych wśród użytkowników MongoDB?

MongoDB obsługuje operacje atomowe do odczytu / zapisu na pojedynczych jednostkach danych (dokumentach), więc wyniki zapytania z MongoDB powinny zawsze być dokładne z tym, co jest przechowywane w bazie danych.

Edycja: podany przykład bazy danych pozycji NoSQL


W przykładzie, który napisałeś przy użyciu sql, w jaki sposób, na wysokim poziomie, modelowałbyś go przy użyciu nosql?
Pran

4
-1, twoja odpowiedź pokazuje tylko dane statyczne. Cała debata na temat SQL vs. NoSQL dla baz danych gier obejmuje wysoce dynamiczne dane. Najlepiej byłoby pokazać transakcję NoSQL, która handluje czymś pomiędzy dwoma graczami - bardzo częstym zjawiskiem, a jedna większość gier popełniła błąd, niezależnie od wybranego przez siebie typu.

3
@Ari: Jest o wiele więcej danych statycznych, ale nikt nie dba o przepustowość zapisu, ponieważ nikt nie pisze - nie zapisuje, nie ma transakcji, nie ma ACID, nie ma prawdziwego pytania do bazy danych, nawet jeśli zdarzy się, że je zapiszesz w jednym. Na to pytanie łatwo odpowiedzieć - po prostu zachowaj je w pamięci. Z pewnością „Jak możemy szybciej ładować dane statyczne?” jest interesującym pytaniem, ale nie sądzę, żeby miało to związek z pytaniami SQL vs. NoSQL. - Czy w przypadku operacji na wielu dokumentach oznacza to, że baza danych zawierałaby jeden dokument zawierający np. Wszystkich graczy?

2
@Ari: Proszę nie mylić NoSQL, który jest pomysłem, i MongoDB, która jest szczególną bazą danych. W mojej ostatniej pracy wysłaliśmy dwie gry do bazy danych NoSQL i uzyskaliśmy doskonałą współbieżność przy niskim opóźnieniu. Ale nasza baza danych NoSQL obsługiwała również transakcje wielodokumentowe z blokowaniem na poziomie pola. NoSQL nie jest pojedynczą „rzeczą” jak SQL, po prostu odnosi się do dowolnej bazy danych, która nie korzysta z SQL (i zwykle nie używa schematów relacyjnych).

5
Tylko moje 0,02 $, ale „brak wydajności” nie jest wadą RDBMS. Wadą jest przechowywanie nierelacyjnych danych w RDBMS, brak dostrajania RDBMS, niezrozumienie tego, co robi Twój SQL, brak indeksowania itp. Itd. Itd. Jeśli masz dane relacyjne, okaże się, że RDBMS są niesamowicie zoptymalizowane.
Robbie

19

Kilka słów broni baz danych SQL.

1 - Jeśli masz bazę danych SQL, możesz pracować z danymi nie tylko za pomocą klucza podstawowego. Większość zapytań w MMO przechodzi przez PK, ale kiedy musisz znaleźć wszystkich użytkowników z poziomem> 30, co zrobisz w świecie NoSQL?

2 - Jeśli masz język SQL, możesz utworzyć „poprawki” w celu naprawy uszkodzonych danych. Na przykład: „update player_items set flag = 0 gdzie item_type_id = 100”. Jak możesz to naprawić w NoSQL? Myślę, że będziesz musiał stworzyć skrypt, który przeanalizuje wszystkie twoje dane ...

3 - Bazy danych SQL nie są tak wolne, jak myślisz. Moi koledzy tworzą internetową grę MMO, która dokonuje 5000 transakcji na sekundę w MySQL. Czy to ci nie wystarcza? Jeśli nie, możesz użyć shardingu do skalowania bazy danych.

4 - SQL ma ograniczenia klucza obcego i takie dobre rzeczy, które pomogą ci znaleźć błędy w kodzie.

NoSQL nie jest srebrną kulą. Rozwiązuje tylko kilka problemów i przynosi wiele nowych problemów. Więc moja rada - zastanów się dwa razy, zanim wybierzesz NoSQL.


1
Są to wszystkie świetne powody, aby unikać NoSQL, dopóki go nie potrzebujesz. Zwłaszcza # 3. O ile nie masz już zylionów użytkowników (i nie odmawiasz niczego), prawdopodobnie będziesz o wiele bardziej produktywny dzięki MySQL.
ojrac

5
1. Użyłbyś: "dla x w db.user.find ({" level ": {" $ gt ": 30}})" 2. Technicznie, to, co napisałeś, jest również skryptem, więc jestem nie jestem do końca pewien, o co ci chodzi. 3. BARDZO możliwe jest utworzenie MMO przy użyciu SQL, a tak naprawdę wiele MMO zostało opracowanych przy użyciu tej technologii. Technologia NoSQL jest dość nowa i została już przyjęta przez serwisy takie jak Amazon, Google i Facebook ze względu na jej wydajność i elastyczność. 4. W NoSQL trzeba pisać własne ograniczenia, ale to po prostu koszt dodatkowej elastyczności.
Ari Patrick,

2
Zgadzam się z twoim stwierdzeniem myślenia dwa razy. To częściowo robię tutaj z tym pytaniem :)
Pran

10
SQL nie jest pociskiem odłamkowym. NoSQL nie jest srebrną kulą. Pomyśl dwa razy, zanim użyjesz jakiejkolwiek technologii.
stonemetal

5
Odnośnie 3, problem nie jest tak dużo, że SQL jest powolny , ale że SQL jest laggy . Ogólnie rzecz biorąc, bazy danych SQL uzyskują doskonałą przepustowość kosztem opóźnień. W przypadku gry internetowej prawdopodobnie tego właśnie chcesz! W przypadku gry sieciowej w czasie rzeczywistym prawdopodobnie tak nie jest, a większość MMO „przypominających WoW”, które używają SQL, używają przed nią warstwy buforującej, która usuwa większość zalet SQL, dlatego NoSQL jest dużym krokiem naprzód im.

18

Odpowiedź brzmi: tak, to ważna opcja, ale nie, to prawdopodobnie nie jest świetny pomysł .

Istnieją dwa główne problemy z SQL, które NoSQL próbuje rozwiązać, jeśli chodzi o gry.

Pierwszym z nich jest opóźnienie lub opóźnienie. W pewnym sensie bazy danych SQL są niezwykle szybkie, przetwarzając tysiące transakcji lub więcej w dziesiątych części sekundy. W innym sensie są niezwykle powolne, ponieważ przetworzenie zaledwie kilku transakcji może zająć tyle samo czasu. W przypadku większości zastosowań baz danych nie ma to znaczenia, ale gry zawierają komponent czasu rzeczywistego, więc nie chodzi tylko o liczbę transakcji na sekundę, ale o średni czas potrzebny na odpowiedź na transakcję w bazie danych.

Opóźnienie to jest poważnym problemem w przypadku gier w czasie rzeczywistym. Wielu programistów, którzy potrzebują dużych baz danych (zwykle dla MMO), buduje warstwę buforowania, która znajduje się między bazą danych a serwerami gry, aby uniknąć tych opóźnień, a następnie okresowo opróżnia pamięć podręczną. Problem? Właśnie wyrzuciłeś główne powody korzystania z bazy danych - atomowość, spójność, izolacja i trwałość .

Ale ten problem nie dotyczy gier internetowych. Masz już połączenie z odtwarzaczem i grą o dużym opóźnieniu, więc równie dobrze możesz uzyskać przepływność zapewnianą przez SQL, a także zalety dojrzałego, dobrze znanego oprogramowania.

Drugi problem dotyczy ciebie i to niedopasowanie impedancji relacyjnej względem obiektu . Gry zajmują się obiektami, bazy danych zajmują się rzędami. Jeśli masz szczęście, obiekt można przekształcić w wiersz, po prostu wymieniając jego pola, ale w większości przypadków obiekty są hierarchiczne i musisz je w jakiś sposób spłaszczyć, aby umieścić je w rzędach.

Bazy danych oparte na dokumentach, takie jak CouchDB i MongoDB, rozwiązują ten problem, promując dokument do obiektu najwyższego poziomu, a nie wiersza („dokument” w tym przypadku jest synonimem „obiektu”). Ale robiąc to, tracą wiele zalet baz danych SQL. Przepustowość jest znacznie niższa, a algorytmy blokowania stają się znacznie bardziej skomplikowane.

Dobra wiadomość jest taka, że istnieje już wiele mapowania obiektowo-relacyjnego (ORM) narzędzi dla dowolnego używanego języka. Pozwalają na dość przejrzyste tłumaczenie między obiektami w pamięci i wierszami w bazie danych. Narzędzia te na ogół nie są odpowiednie dla dużych gier w czasie rzeczywistym, ponieważ mogą prezentować najgorsze aspekty wydajności baz danych SQL i NoSQL. Ale jest to w porządku dla gry internetowej - w najgorszym przypadku, gdy napotkasz problemy z wydajnością, możesz wrócić do robienia transakcji w staromodny sposób. Problem opóźnień Cię nie boli, a zwiększona przepustowość pomaga.

Wreszcie, aby pokusić się o stwierdzenie, które omówiłem gdzie indziej : nie chodzi o statyczne dane gry. Nie mówię tu o twoich opisach przedmiotów, obrażeniach zadawanych przez ciebie broni, sprajtach itp. Mam na myśli prawdziwe, zmienne dane gry, takie jak to, co znajduje się w ekwipunku gracza lub jakie są jego statystyki. Wszystko, czego potrzebujesz do danych statycznych, to magazyn danych. Może okazuje się, że najłatwiej jest do tego celu użyć tej samej bazy danych, co magazyn danych, ponieważ masz świetną ORM; może potrzebujesz systemu plików. To dwa osobne problemy, a jedna odpowiedź nie musi (i prawdopodobnie nie będzie) pasować do obu przypadków.


1
+1 Dzięki za porównanie obu opcji. Ponadto, masz rację mówiąc, że dane statyczne nie powinny znajdować się w bazie danych.
Pran

1
+1 Jednak wydaje mi się, że nie wspominasz o jednym z głównych plusów (no, pro lub con w zależności od perspektywy) No SQL, to znaczy, że jest bez schematu, co pozwala na przechowywanie bardzo dynamicznych danych. Właściwie zamierzam użyć kombinacji obu w moim bieżącym projekcie z PostgreSQL do rzeczy, które ładnie pasują do modelu relacyjnego, i Mongo do rzeczy półstatycznych, które nie. (na przykład dziennik, którego można użyć do wygenerowania powtórki, gdzie relatywnie musiałbym mieć albo kolumnę, która przechowuje PK z jednej z wielu innych tabel, albo tabelę z ogólnymi nazwami kolumn, np. param1 param2)
Davy8

1
@ Davy88: noSQL niekoniecznie jest pozbawiony schematu, a posiadanie „wysoce dynamicznej” bazy danych nie jest naprawdę plusem. Jeśli wszystko, co masz, to zupa danych, nie możesz indeksować, nie możesz blokować na poziomie pola, a nawet proste zapytania są pełne pytań o to, co się stanie, jeśli klucz nie istnieje.

@ user744, co robią te, o których wspominasz?
expiredninja

5
  • Czy magazyn danych noSQL (oparty na dokumentach, taki jak MongoDB) byłby odpowiedni dla gry internetowej?

Radzę rzucić okiem na couchdb

Jego interfejs jest oparty na javascript, więc będzie dobrze komponował się z grami opartymi na HTML5 / javascript.

Jest również w stanie pracować w trybie „off-line” (tworzenie lokalnej kopii bazy danych), a następnie zsynchronizować się później z serwerem (możesz to wykorzystać na przykład w instancjach lochów)

  • Jakie problemy mogą wystąpić przy użyciu konwencjonalnego RDBMS, takiego jak MySQL?

Głównym problemem byłoby to, że bazy danych bez SQL obsługują całkiem inaczej niż relacyjne bazy danych. Dokonanie zmiany mentalnej może być trudne.

Na przykład spójrz na to, jak „ zapytania ” są wykonywane w couchdb. Wszystko odbywa się w javascript.

  • Jak zapewnić spójność danych ubezpieczeniowych między użytkownikami MongoDB, podczas gry lub w czasie, np. W pracy crona?

Proces „synchronizowania” baz danych nazywa się replikacją w języku lingo couchdb. Bardzo często zobaczysz termin spójność . Istnieje kilka wbudowanych usług, które zajmują się replikacją i spójnością. Zobacz na przykład proces przyrostowej replikacji .


Tak, słyszałem też o couchdb, w rzeczywistości nawet na stronie internetowej mongodb, często porównują go. Myślę, że muszę zbadać couchdb kontra mongodb.
Pran

2

W zależności od tego, co masz w grze, możesz użyć obu i połączyć je za pomocą modeli w grze. Na przykład odtwarzacz może i powinien znajdować się w RDB (dane logowania), ale zasoby magazynu / zmiennych odtwarzacza mogą przejść do noSQL, więc moduł gracza może login()używać RDB i fetchInventory()używać noSQL przy użyciu klucza podstawowego.

Na przykład mapy lepiej zapisywać w NoSQL (na przykład współrzędne => tablica różnych obiektów). Nie wyobrażam sobie zapisywania tego, co zawiera obszar w RDB (poza serializowanym ciągiem, który należy całkowicie odserializować, aby odczytać jakąś część? Więcej procesora i pamięć RAM zmarnowana!) cóż, nadal można zapisać obszary w RDB, na przykład obszar „miasto X” zawiera następujące cordinaty / blok ([3,4], [8,7] ...)

możesz i prawdopodobnie powinieneś użyć obu tych elementów i zajrzeć do niestabilnej pamięci, takiej jak memcache, której możesz potrzebować lub jakieś dane tymczasowe (na pewno byłoby to szybsze niż używanie dysku twardego! i oszczędza dużo procesora, ale na pewno nie RAM)

więc w końcu>

zależy to od tego, co chcesz mieć w swojej grze! Cheerz


jakie funkcje, według ciebie, wciągnęłyby cię bardziej w NoSQL lub warstwę trwałości, tak jak lubię o tym myśleć?
expiredninja

1
może system współrzędnych, jeśli twoja gra jest oparta na GPS, co może wymagać zaawansowanego wyszukiwania. w zasadzie, jeśli jesteś dobry w MySQL, to trzymaj się go, czy można go również użyć jako nosql
Ronan Dejhero
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.