Skip to content
Andrew Geweke edited this page Dec 11, 2013 · 1 revision

When storing JSON data in the database, flex_columns will compress that data if all of the following are true:

  • The column is declared as BINARY, VARBINARY, BLOB, or anything else ActiveRecord recognizes as a binary column type. This is because you simply cannot store compressed data in a text column reliably; compressed data can contain all possible sequences of bytes, and text columns may, in general, disallow certain sequences of bytes. Also, it's pointless to index or query compressed data anyway, so why bother?
  • The binary column has not had its header disabled (using :header => false) for the flex column in question. We need the header to tell us whether the data is compressed or not.
  • The compressed version of the data, with header, is no more than 95% as long as the uncompressed data. There are advantages in human readability to having uncompressed data, so let's not compress it unless there's an actual benefit.
  • Compression is not disabled (using :compress => false) for the flex column in question.
  • The uncompressed data is at least 200 bytes long. (This threshold can be changed by passing an integer to the :compress option for the flex column.) JSON shorter than this often won't compress much at all, or the compressed version will actually be longer than the uncompressed version. We don't want to pay the price for attempting to compress data if it's highly unlikely that it will be a net win.

If, for some reason, you need to access flex-column data without using this gem, it's easy to distinguish compressed data. Binary columns get a header (unless it's disabled) of FC:01, (the 01 is the version number of the flex-column data), followed by either 0, for uncompressed data, or 1, for compressed data. Compressed data is simply GZipped data, and can be decompressed using code like the following Ruby:

input = StringIO.new(data, "r")
reader = Zlib::GzipReader.new(input)
reader.read
Clone this wiki locally