noSQL - É uma opção válida para jogos baseados na web? [fechadas]

20

Por uma oportunidade e tédio, um amigo e eu decidimos fazer um jogo baseado na web. Este é o primeiro 'jogo' que eu vou fazer, já que geralmente eu programa aplicativos da web no django.

Optei por usar a mesma estrutura para o jogo, mas não tenho muita certeza sobre o armazenamento de dados, pois não posso prever requisitos futuros e problemas relacionados ao banco de dados. Ultimamente, o movimento noSQL está ganhando força e eu gostaria de explorar essa área.

Portanto, tenho as seguintes perguntas:

  • Um armazenamento de dados noSQL (baseado em documentos, como o MongoDB) seria adequado para um jogo baseado na Web?
  • Quais são os problemas que podem surgir usando um RDBMS convencional, como o MySQL?
  • Como garantir a consistência dos dados entre usuários com o MongoDB, durante o jogo ou em eventos programados, como tarefas cron?

Resumo do jogo: jogo de aventura típico, com o jogador lutando contra monstros e ganhando itens e tal.

  • Alguns dados são estáticos em todos os jogadores: itens, armas, poções, mapas etc.
  • Alguns dados vinculados ao player: inventário, métricas (estatísticas), progresso etc.
  • Um jogador pode precisar conhecer as estatísticas e o estado de outro jogador
  • Tarefas agendadas serão executadas em determinado intervalo de tempo
Pran
fonte
11
Um problema com alguns bancos de dados noSQL é que eles não podem fazer consultas imprevisíveis no momento do "design" de maneira rápida em grandes conjuntos de dados como logs de eventos: gamedev.stackexchange.com/q/4465/450 Lembre-se de que os bancos de dados noSQL exigem o mesmo técnicas contra injeção de consulta normal do que os bancos de dados normais.
Hendrik Brummermann
11
@nhnb: Uma boa maneira de reafirmar seu argumento é "usar um banco de dados relacional para dados de relação e usar um banco de dados de objetos / documentos para dados de objetos / documentos". Infelizmente, acho que a maioria das pessoas não tem experiência ou passa muito tempo pensando em modelagem, o que leva a projetos ruins, independentemente da escolha deles.
2
Em resposta à sua pergunta "O NoSQL é uma opção válida para jogos baseados na Web?" Eu acredito que a resposta é sim. Os bancos de dados NoSQL foram usados ​​anteriormente para jogos baseados na Web (como o FarmVille) e oferecem muita flexibilidade. O principal ponto de discórdia para esta pergunta parece ser "o que é melhor (NoSQL ou SQL)?". Cada sistema tem prós e contras, mas ambos são opções perfeitamente legítimas. Se você estiver procurando por uma lista detalhada das vantagens de um sistema em relação ao outro, poderá fazer uma visita ao Programmers StackExchange. :)
Ari Patrick

Respostas:

21

Um banco de dados noSQL seria adequado para um jogo baseado na Web?

Absolutamente! De um modo geral, os bancos de dados não relacionais (como o MongoDB) são muito melhores para jogos, pois são mais flexíveis na maneira como modelam dados, além de serem mais eficientes que os bancos de dados relacionais (como SQL) - tornando-os "ganha-ganha" escolha.

Quais são os problemas que podem surgir usando um RDBMS convencional?

Existem duas grandes desvantagens no uso de bancos de dados relacionais:

  • Falta de flexibilidade na maneira como você modela dados
  • atuação

A falta de flexibilidade na maneira como você modela os dados é uma grande desvantagem, porque o uso de um banco de dados relacional obriga a modelar dados para atender às necessidades do banco de dados, em vez do banco de dados que acomoda as necessidades do modelo. Por exemplo, considere criar o modelo para armazenar itens em um jogo usando um banco de dados relacional e decida o seguinte modelo:

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

Agora considere como você precisaria modificar o modelo para atender, faça o seguinte:

  • Adicionar um novo tipo de item
  • Crie uma arma com vários tipos de armas
  • Crie um item de poção que também possa ser usado como arma

Certamente todas essas ações são factíveis, mas você não será a pessoa mais feliz enquanto estiver realizando, e provavelmente se perguntará: "existe uma solução melhor para o que eu quero fazer?", Quando você poderia projetar um modelo muito mais flexível em um banco de dados não relacional.

Nota: Se você não estiver familiarizado com o modo como os bancos de dados baseados em documentos armazenam informações, verifique este link antes de continuar. O modelo apresentado abaixo foi projetado para usar uma lógica semelhante à apresentada no artigo mencionado.

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

Existem muitos artigos bons sobre o desempenho dos bancos de dados NoSQL x SQL, mas aqui está um que fornece exemplos de aplicativos para que você possa executar seus próprios testes: MongoDB x SQL Server 2008 Performance Showdown

Como asseguro a consistência dos dados entre os usuários do MongoDB?

O MongoDB suporta operações atômicas de leitura / gravação em entidades de dados únicas (documentos), portanto, os resultados da consulta do MongoDB devem sempre ser precisos com o que é armazenado no banco de dados.

Edit: Exemplo NoSQL fornecido de banco de dados de itens

Ari Patrick
fonte
No exemplo que você escreveu usando o sql, como você o modelaria em alto nível usando o nosql?
Pran
4
-1, sua resposta mostra apenas dados estáticos. Todo o debate sobre SQL vs. NoSQL para bancos de dados de jogos envolve dados altamente dinâmicos. A melhor coisa a fazer seria mostrar uma transação NoSQL que negocia algo entre dois jogadores - uma ocorrência muito comum, e a maioria dos jogos erra, independentemente do tipo escolhido.
3
@Ari: Há muito mais dados estáticos, mas ninguém se importa com a taxa de transferência para gravações, porque ninguém escreve para ela - sem gravações, sem transações, sem ACID, sem perguntas reais sobre o banco de dados, mesmo que você as armazene em um. É fácil responder a essa pergunta - basta mantê-la na memória. Certamente "Como podemos carregar dados estáticos mais rapidamente?" é uma pergunta interessante, mas não acho que esteja relacionada a questões de SQL vs. NoSQL. - Quanto às operações com vários documentos, isso significa que seu banco de dados teria um documento com, por exemplo, todos os participantes?
2
@Ari: Por favor, não confunda NoSQL, que é uma idéia, e MongoDB, que é um banco de dados específico. No meu último trabalho, enviamos dois jogos em um banco de dados NoSQL e obtivemos excelente simultaneidade com baixa latência. Mas nosso banco de dados NoSQL também suporta transações com vários documentos com bloqueio no nível do campo. NoSQL não é uma "coisa" única como SQL, apenas se refere a qualquer banco de dados que não use SQL (e geralmente não use esquemas relacionais).
5
Apenas os meus US $ 0,02, mas "sem desempenho" não são uma desvantagem do RDBMS. É uma desvantagem de armazenar dados não relacionais em um RDBMS, não ajustar seu RDBMS, não entender o que seu SQL está fazendo, não indexar etc. etc. etc. Se você tiver dados relacionais, verá que os RDBMSs são incrivelmente otimizados.
22611 Robbie
19

Algumas palavras defendem os bancos de dados SQL.

1 - Se você possui banco de dados SQL, pode trabalhar com seus dados não apenas por chave primária. A maioria das consultas no MMO passa por PK, mas quando você precisa encontrar todos os usuários com nível> 30, o que você fará no mundo NoSQL?

2 - Se você possui linguagem SQL, pode criar "hotfixes" para reparar dados quebrados. Por exemplo: "atualize player_items set flag = 0 onde item_type_id = 100". Como você pode corrigir isso no NoSQL? Eu acho que você terá que fazer um script que analise todos os seus dados ...

3 - Os bancos de dados SQL não são tão lentos quanto você imagina. Meus colegas criam o jogo MMO baseado na Web, que faz 5000 transações por segundo no MySQL. Não é o suficiente para você? Caso contrário, você pode usar o sharding para dimensionar seu banco de dados.

4 - O SQL possui restrições de chave estrangeira e coisas boas, o que o ajudará a encontrar erros no seu código.

NoSQL não é uma bala de prata. Ele resolve apenas alguns problemas e traz muitos problemas novos. Então, meu conselho - pense duas vezes antes de escolher o NoSQL.

Andrey Frolov
fonte
11
Todos esses são ótimos motivos para evitar o NoSQL até que você realmente precise dele. Especialmente # 3. A menos que você já tenha zilhões de usuários (e se recuse a compartilhar algo), provavelmente será muito mais produtivo com o MySQL.
ojrac
5
1. Você usaria: "para x em db.user.find ({" level ": {" $ gt ": 30}})" 2. Tecnicamente, o que você escreveu também é um script, então eu estou não tenho certeza qual é o seu ponto. 3. É MUITO possível criar um MMO usando SQL e, de fato, muitos MMOs foram desenvolvidos usando a tecnologia. A tecnologia NoSQL é relativamente nova e já foi adotada por serviços como Amazon, Google e Facebook por seu desempenho e flexibilidade. 4. No NoSQL, você precisa escrever suas próprias restrições, mas esse é simplesmente o custo da flexibilidade adicional.
Ari Patrick
2
Eu concordo com sua afirmação de pensar duas vezes. Isso é parcialmente o que estou fazendo aqui com esta pergunta :)
Pran
10
SQL não é uma bala de lasca. NoSQL não é uma bala de prata. Pense duas vezes antes de usar qualquer tecnologia.
Stonemetal
5
Em relação a 3, o problema não é tanto o SQL ser lento , mas o SQL estar atrasado . De um modo geral, os bancos de dados SQL obtêm excelente taxa de transferência às custas da latência. Para um jogo baseado na Web, é provavelmente o que você deseja! Para um jogo em rede em tempo real, provavelmente não é, e a maioria dos MMOs "semelhantes a WoW" que usam SQL usam uma camada de cache à sua frente que remove a maioria dos benefícios do SQL, e é por isso que o NoSQL é um grande avanço para eles.
18

A resposta é sim, é uma opção válida, mas não, provavelmente não é uma ótima ideia .

Existem dois grandes problemas com o SQL que o NoSQL tenta solucionar quando se trata de jogos.

O primeiro é a latência ou atraso. Em um sentido, os bancos de dados SQL são incrivelmente rápidos, processando milhares de transações ou mais em décimos de segundo. Em outro sentido, eles são incrivelmente lentos, porque o processamento de apenas algumas transações pode levar a mesma quantidade de tempo. Para a maioria dos usos de banco de dados, isso não importa, mas os jogos têm um componente em tempo real; portanto, não se trata apenas de quantas transações você pode fazer por segundo, mas do tempo médio necessário para responder a uma transação de banco de dados.

Essa latência é um grande problema para jogos em tempo real. Muitos desenvolvedores que precisam de bancos de dados grandes (geralmente para MMOs) criam uma camada de cache que fica entre o banco de dados e os servidores de jogos, a fim de evitar essas paralisações e, em seguida, liberam o cache periodicamente. O problema? Você acabou de apresentar os principais motivos para usar um banco de dados - atomicidade, consistência, isolamento e durabilidade .

Mas esse problema não se aplica a jogos da web. Você já possui uma conexão de alta latência entre o jogador e o jogo, para obter a taxa de transferência que o SQL fornece, além dos benefícios de um software conhecido e maduro.

O segundo problema, no entanto, se aplica a você, e essa é a incompatibilidade de impedância objeto-relacional . Jogos lidam com objetos, bancos de dados lidam com linhas. Se você tiver sorte, um objeto pode ser transformado em uma linha apenas listando seus campos, mas na maioria das vezes os objetos são hierárquicos e você precisa achatá-los de alguma forma para colocá-los em linhas.

Bancos de dados baseados em documentos, como CouchDB e MongoDB, resolvem esse problema promovendo o documento para o objeto de nível superior, em vez de linha ("documento" nesse caso é sinônimo de "objeto"). Mas, ao fazer isso, eles perdem muitos dos benefícios dos bancos de dados SQL. A taxa de transferência é muito menor e os algoritmos de bloqueio se tornam muito mais complicados.

A boa notícia é que já existem muitos mapeamentos objeto-relacionais (ORM) ferramentas de disponíveis para qualquer idioma que você esteja usando. Eles permitem traduzir entre objetos na memória e linhas no banco de dados de forma bastante transparente. Essas ferramentas geralmente não são apropriadas para jogos em tempo real de larga escala, porque podem apresentar os piores aspectos de desempenho dos bancos de dados SQL e NoSQL. Mas tudo bem para um jogo na Web - na pior das hipóteses, quando você encontra problemas de desempenho, pode voltar a fazer transações da maneira antiga. O problema de latência não o prejudica e o aumento da taxa de transferência ajuda você.

Finalmente, para enfatizar um argumento que já fiz em outro lugar : não se trata de dados estáticos do jogo. Não estou falando das descrições dos itens ou dos danos ou sprites da arma ou qualquer coisa aqui. Quero dizer os dados reais e mutáveis ​​do jogo, como o que está no inventário de um jogador ou quais são suas estatísticas. Tudo o que você precisa para os dados estáticos é um armazenamento de dados. Talvez a coisa mais fácil de fazer seja usar o mesmo banco de dados que o armazenamento de dados para isso, porque você tem um ótimo ORM; talvez você só precise do sistema de arquivos. São dois problemas separados, e uma resposta não precisa (e provavelmente não vai) se encaixar nos dois casos.

Comunidade
fonte
11
+1 Obrigado pela comparação das duas opções. Além disso, você faz um bom argumento dizendo que os dados estáticos não devem estar no banco de dados.
Pran
11
No entanto, acho que você não menciona um dos principais profissionais (bem, prós ou contras, dependendo da perspectiva) do No SQL, que é sem esquema, o que permite armazenar dados altamente dinâmicos. Na verdade, vou usar uma mistura de ambos no meu projeto atual com o PostgreSQL para coisas que se encaixam perfeitamente no modelo relacional e o Mongo para coisas semi-estáticas que não. (por exemplo, um log que pode ser usado para gerar uma repetição, onde relacionalmente eu teria que ter uma coluna que armazena uma PK de uma de muitas outras tabelas ou uma tabela com nomes genéricos de colunas, por exemplo, param1 param2)
Davy8
11
@ Davy88: noSQL não é necessariamente sem esquema, e ter um banco de dados "altamente dinâmico" não é realmente uma vantagem. Se tudo o que você tem é sopa de dados, não é possível fazer indexação, não é possível bloquear em nível de campo e até consultas simples ficam repletas de perguntas sobre o que acontece se uma chave não existir.
@ user744, o que essas coisas que você menciona realizam?
expiredninja
5
  • Um armazenamento de dados noSQL (baseado em documentos, como o MongoDB) seria adequado para um jogo baseado na Web?

Eu aconselho a dar uma olhada no couchdb

Sua interface é baseada em javascript, portanto, ela se mistura muito bem com jogos baseados em HTML5 / javascript.

Ele também pode trabalhar 'off-line' (fazendo uma cópia local do banco de dados) e depois sincronizar-se com o servidor posteriormente (você pode usá-lo em masmorras instanciadas, por exemplo)

  • Quais são os problemas que podem surgir usando um RDBMS convencional, como o MySQL?

O principal problema seria que os bancos de dados sem sql lidam de maneira bem diferente dos bancos de dados relacionais. Fazer a troca mental pode ser difícil.

Por exemplo, veja como " consultas " são feitas no couchdb. Tudo é feito em javascript.

  • Como garantir a consistência dos dados entre usuários com o MongoDB, durante o jogo ou em eventos programados, como tarefas cron?

O processo de 'sincronização' de bancos de dados é chamado de replicação na linguagem do couchdb. Você também verá muito o termo consistência . Existem vários serviços internos que lidam com replicação e consistência. Veja, por exemplo, o processo de replicação incremental .

egarcia
fonte
Sim, eu também ouvi falar do couchdb, de fato, mesmo no site do mongodb, eles geralmente fazem comparação com ele. Eu acho que preciso pesquisar sobre couchdb vs mongodb.
Pran
2

Dependendo do que você tem no seu jogo, você pode acabar usando os dois e conectando-os através dos modelos do seu jogo. Por exemplo, o player poderia e deveria estar no RDB (informações de login), mas o inventário / armazenamento variável do jogador poderia ir para o noSQL, para que o seu módulo do player login()usasse RDB e fetchInventory()noSQL pela chave primária.

Mapas, por exemplo, devem ser salvos no NoSQL (coordenadas => array de objetos diferentes, por exemplo). Não imagino salvar o que uma área contém no RDB (exceto uma string serializada que você precisa desserializar totalmente para ler parte de? Mais CPU e RAM perdida!) bem, você ainda pode salvar áreas no RDB, por exemplo, a área "cidade X" contém os seguintes cordinados / bloco ([3,4], [8,7] ...)

você poderia e provavelmente deveria usar os dois e dar uma olhada no armazenamento volátil, como o memcache, que você pode precisar ou em alguns dados temporários (seria mais rápido do que usar o disco rígido, com certeza! e economiza bastante CPU, mas com certeza não RAM)

então no final>

depende do que você quer ter no seu jogo! cheerz

Ronan Dejhero
fonte
quais recursos você acha que o arrastariam mais para o NoSQL ou a camada de persistência, como eu gostaria de pensar nisso?
expiredninja
11
talvez um sistema de coordenadas, se o jogo for baseado em gps, algo que talvez precise de pesquisa avançada. Basicamente, se você é bom com MySQL, em seguida, cumpri-lo, é possível usá-lo como um nosql bem
Ronan Dejhero