Serialize a BlockSnapshot into MySQL

I want to store a BlockSnapshot in a MySQL Table. As slim as possible.
My current attempt is something like:

[MySQL Table Columns]
TINYINT world_id
INT x
INT y
INT z
SMALLINT block_id
SMALLINT variant_id

My problem are the block_id and the variant_id.
Is there an easy way to convert a BlockType into an id?
And especially:
Since Sponge uses Traits to manage the blockvariants how can i serialize them in a slim way? :smiley:

They are Strings, you need to store it as a varchar or similar

shure, but varchar are a lot of wasted bytes… thats the point of my question :confused:

Edit: I don’t think minecraft-anvil stores those blocks as Strings either ^^

I’m at least 30% sure recent MySQL servers implemented a JSON column type.

There’s no other way AFAIK. You could store it as integers if you maintain a mapping of int <=> string IDs, but that would take up additional space (but less if you have thousands of blocksnapshot entries). IMO it’s not worth it.

The anvil file format stores block types as integers, yes, but those integers are mapped to strings inside the game. I think the integers will be removed completely at some point. FML based servers store an integer to string mapping within the level.dat, and it is not guaranteed to be the same mapping for any two worlds.

And how can i serialize a BlockTrait? I can get its name and value but i can’t create one with that, can i? ^^

If you think its worth you can define column type as enum or integer type.
(Its worth to mention that enums in mysql are extremly retarded)

Why are you so worried about the space? In todays world almost noone really cares about size of the database. Disk space is the cheapest thing you can afford, and sql databases with good indexing are very fast even when they have to work with very large data tables.

1 Like

Well, i am not a professional and am currently running on a host that gives me 10GB disk space (expandable on request).
I once ran out of disk space on my Server and lost data… Maybe its some kind of trauma XD
Also i want to store as many BlockChanges as i can (i am doing a logblock/prism kind of plugin atm)! :smiley:
Aaaand i am a perfectionist! ^^

What I recommend doing: Load up Sponge in IDE and throw a debug point in a ChangeBlockEvent listener like so:

@Listener
public void onChange(ChangeBlockEvent event) {
  for (BlockTransaction transaction : event.getTransactions()) {
    final DataContainer container = transaction.toContainer();
    // Put a breakpoint here!
    System.out.println(container);
  }
}

When you’ve put your breakpoint, launch either the server or client in debug mode and then read what the DataContainer spits out for you. There’s seriously a lot of information that we provide that can’t be stored as integers or numbers anymore.

I’d recommend using a NOSQL Database (e.g. MongoDB) to store Blockchanges etc.
That way you don’t have to worry about new columns when you encounter new data.

I found this:
blockState.toContainer().getInt(new DataQuery("UnsafeMeta")).orElse(0)
And i will use it!! You cant Stop me!!! I’ve decided: I will do it the BAD WAY!! Muhahahha.

Ok srsly now:
I know you guys are totally right and i definitly shouldn’t do that, but i am so stubborn! :smiley:
Ill probably get punished for this soon. ^^

PS.: don’t hate me plz :slight_smile:

1 Like