Estou criando um banco de dados sozinho
Eae galera esse é meu primeiro post no TabNews, criei a conta hoje e achei incrível o site então vou compartilhar um projeto meu audacioso.
Ideia inicial
O banco de dados originalmente era pra ser somente para games, eu estava desenvolvendo meu game(e ainda estou) e precisava de um banco de dados pra guardar o XP, nível do jogador, armas liberada e etc, porém em um jogo é todo muito dinâmico, por exemplo tem armas/itens que são liberados quando você atinge um nível específico, ou compra com dinheiro ou xp, ou então é liberada quando você faz alguma coisa, e, depois de analisar os alguns bancos percebi que fazer tudo isso seria extramamente complicado, mas pior do que isso seria trabalhoso demais em bancos SQL por exemplo, fazer toda a relação das tabelas, eu originalmente optei por bancos de dados como o Mongo, Firebase e tentei usar o RavenDB(não é muito conhecido mas curti bastante o RavenDB), eu queria poder ter mais liberdade pra poder mexer, assim como eu me sentia na Unity3D, onde eu conseguia personalizar muita coisa, criar componentes e tudo mais, então eu tive uma ideia(maluca) de fazer um banco de dados mais dinâmico, e com isso surgiu a ideia do RazorDB que era o nome original, nele você teria um usuario e para adquirir um item ao seu usuario, você teria que cumprir uma condição como por exemplo ter uma quantidade x de XP, em outras palavras o banco gerenciaria essa parte pra você, e faria relações que normalmente teria em um jogo, o problema era que essa condições eram apenas JSON onde você só colocava que se algo fosse maior ou menor que outro algo poderia adquirir e tudo mais, era extramamente limitado, e mais do que isso o banco parecia meio sem graça e se eu fizesse dessa maneira teria que me sujeitar a outros bancos de dados pra outras coisas de qualquer jeito, então tive uma ideia melhor.
ByteRunnerDB
Criei um projeto do zero em C++ chamado ByteRunnerDB, eu tava um pouco enferrujado em c/c++, fazia muito tempo que não programava nessa linguagem, tive que relembrar muita coisa(mas muita coisa mesmo), depois de muita luta, sacríficio e ajuda do ChatGPT eu consegui adicionar uma biblioteca chamada Mono no meu projeto C++, com ela eu poderia fazer o que queria, que era dar mais opções para o banco, como o Mono você pode carregar e executar código C# em tempo de execução, então você pode criar por exemplo uma função chamada Hello() e chamar ela no C++, mas mais do que isso, você pode procurar por classes, namespaces, instanciar classe, alterar as propriedades da classe, listar os atributos os metodos e muito mais e com isso posso carregar os scripts/Dlls C# e assim chamar funções C# para eventos no banco de dados, por exemplo, você pode criar um script que impede que um dado seja inserido se ele não for um email válido, ou então desconectar uma conexão com o banco se ela tiver um IP específico(bloquear no caso).
Detalhes de como funciona
Você cria um script que herda a classe RunnerBehaviour e nela você cria funções com nomes e parâmetros específicos para ser chamada pelo C++ como a função OnReceiveData, por exemplo, que é chamada quando o banco recebe qualquer dado que seja(que normalmente é json), então você pode receber dados específicos para serem tratados pelo seu script C# e fazer o que você quiser como por exemplo, você pode receber um dado que diz que um jogador X cumpriu um desafio e agora ele pode acessar X item do jogo, legal né?(Pra mim pelo menos é KKKKKKK), o banco é divido em storages (que vou entrar em detalhes mais abaixo), minha ideia é que você possa se inscrever em eventos de storages como por exemplo quando um dado é deletado, ou modificado, tem muitas outras ideias, graças a muita luta e dedicação, ja consegui fazer isso, agora no momento estou trabalhando com as operações do banco de dados e nos eventos, mas o evento de OnReceiveData por exemplo ja testei e funcionou direitinho(Pulei da cadeira e muito quando deu certo), como podem ver me inspirei muita na Unity pra fazer isso.
Como o banco guarda os dados?
Então eu fiquei muito pensativo nessa parte ja que bancos de dados tem que lidar com enormes quantidades de dados, e, ao guardar, ler, atualizar e deletar esses dados, enormes quantidades de dados tem que ser movidos ou modificadas dependendo do algoritmo, e eu queria que fosse rápido, eu não estou satisfeito com a solução que encontrei mas por agora me parece boa(por enquanto, queria saber a opinião de vocês), o banco guarda os dados em formato JSON, eu não queria guardar os dados em um JSON gigante pois quanto mais dados mais iria demorar o Parse, então depois de pesquisar um pouco e perguntar algumas coisa pro ChatGPT pra me tirar algumas dúvidas decidi fazer o seguinte, os dados são salvos em um arquivo que por enquanto chamo de byteRun, nessa arquivo vai sendo adicionado os bytes JSON da sequinte forma:
[4 bytes(tamanho do ID do documento json), 4 Bytes(tamanho do documento JSON),bytes do ID do documento, bytes do documento json]
Eu fiz dessa forma pois assim quando for deletar um documento com um ID específico, não vai ser necessário dar parse no JSON ele vai percorer pelo arquivo mais rápido já que o ID esta separado do documento JSON(no documento JSON também tem um campo com ID). Além disso os arquivos tem um tamanho máximo que pode ser alterado em um arquivo json que vai ficar na pasta do projeto, isso significa que em cada storage vão existir varios arquivos .byteRun que vão ter um tamanho máximo, assim quando um novo dado for apagado ou modificado não vai ser necessario mover todos os dados, e sim uma parte deles, mas ainda sim tem muito o que fazer sobre esse assunto.
Estrutura da pasta de projeto
A pasta do projeto contém os scripts C# que você vai usar, um arquivo runner-project.json na raíz do projeto e outras pastas que vão ser as storages que você vai criar, os dados das storages vão pra essas pastas, então diferente do MYSQL por exemplo que guarda os dados em lugar que ele escolhe(se eu não estiver enganado, por favor não me xinguem se eu errei :( ), o ByteRunner guarda os dados nessas pastas dessa storages assim se você precisar mover o banco, teoricamente seria quase um CTRL-C,CTRL-V sem a necessidade de importar nada só mover a pasta mesmo, mas não estou confiando nisso e estou pensando seriamente em deixar uma opção pra escolher onde guardar as storages. Além disso estou trabalhando pra colocar uma ambiente de desenvolvimento pra recompilar os scripts e recarrega-los quando você os altera com seu editor de código.
Claro que isso é so o inicio e penso que muita coisa vai mudar ao longo do desenvolvimento e tem muita coisa pra se pensar, ja que chamar funções C# pra rodar antes de um dado ser inserido, alterado ou deletado pode custar desempenho, além disso tem muitos outros problemas pra resolver mas apesar da dificuldade quero continuar, quem sabe o projeto da certo e muita gente usa? Além de que estou me divertindo muito fazendo isso!
E ai o que acharam? vou deixar o git do projeto já que a intenção é ser open source mesmo, não liguem a bagunça no código viu eu sou meio atrapalhado(e com isso quero dizer: não me humilhem pelo meu código programadores mais experientes, po favô).
Github: ByteRunnerDB