Efficient Bukkit multi-plugin Mongo database design

NOTE: I know this is not a “Bukkit” or Minecraft related website, but I believe the awesome people here will have more knowledge of database design with Mongo than the kids do on the Minecraft forums. Thank you for your time and your assistance!

I am needing advice on how to solve a Mongo database design issue. As such, I have multiple plugins that need to read/write to Mongo. Each plugin uses a “main” or core plugin to communicate with MongoDB. Each plugin holds data related to that particular plugin. Questions and code references provided below.

Plugin Setup Example:

Core Plugin:

  • MongoDB Access.
  • Utility Classes.
  • Shared classes among all plugins.
  • This plugin is used on all servers.

Minigame Plugin:

  • Contains a variety of games.
  • Each game within the plugin needs to save game specific statistics
    (kills, times played, etc).
  • Will continue to be expanded to have more games and more data to save.
  • This plugin is not used on all servers.

Some future plugin:

  • Will need to save data that is currently unknown but will be designed
    in the future.

Some questions regarding the design for this specific setup:

  1. Should all data for each current plugin and future plugins and
    features use one specific Mongo database document?
  2. Should each plugin have it’s own document?
  3. As features expand and new data needs to be saved and retrived, how
    do I prevent NullPointerExceptions due to old profiles not
    containing new data (for instance a new minigame release)?

My original thoughts were to pack everything into one single profile document. However not all data in the document would be needed for ever server. So my next idea was to refactor the current setup and separate my database design into multiple documents based on each plugin. However this seems clunky and my lack of experience shows. I am looking for an intelligent design based around my current circumstances. Multiple plugins with constantly evolving sets of data.

My code for reference:

My current profile read/write code: https://pastebin.com/HExiVi5d
My profile data class: https://pastebin.com/8fX6X6b7

ok man, I think I don’t understood your question, first, can u tell us what do you want to achieve, I think also, your problems comes from the design, for example what do you want to achieve with that mongo db conecction, you may know that opening and closing connections to db is to much process consuming, you should think a better way to accomplish what you want, in this case how the game you have has to communicate with mongo, and are you sure mongo is the better option, what about others DBMS?

Okay, thanks for your detailled description, but I’m not sure either, if I got your problem right.

  1. Sounds like “plugins” are the classes that do your caching on application side. Seems like you want to save and load the plugin data per plugin, so you probably want to have one document for each plugin in a shared database. Alternatively, you can use a database per plugin, or even a mongodb per plugin. Depending on how you want to seperate your plugins/games, you can chose either one. My first try would be to have an id per plugin and save it in one shared collection. Caution: If you want to be “fast”, there are different approaches with different kinds of consistency you can do with mongo…whole topic for itself.

  2. Answered with 1)?

  3. Your in-application loaded profile instance has to be updated from time to time. How you model your data is crucial for backwards compatibility or api changes. long story short: If you add new fields to your model, add default values whenever possible. Depending on the deserialization framework (or json mapper), you can add an init method you call by yourself/automatically. There are severl other ideas on how to handle versioning (that’s the word you have to google for), depending on what problems reagrding versioning you want to solve. For example http://bethecoder.com/applications/tutorials/json/google-gson/versioning.html .

i see same question from you on stackoverflow ^^ (no answer and some kid give minus)

short - brutal trick:

  • Make 1 big field like 256-512 byte and manually pack unpack different data in it:
    “2 bytes kills, 1 byte Score, 2 byte Money”
    per Game Data, or per player Data (MMO) - use it where you want)
    Short – brutal - same DB size for different Versions of client and server (while in bounds of field limit)

p.s I may say little disappointed – we have at least 3 ppl who working with DB(experts) and make for living with it.
But they don’t care (or too Greedy to help for free XD)

But I don’t XDDDD
There are so many, so I even not care…