Dynamic columns allow one to store different sets of columns for each row in a
table. It works by storing a set of columns in a blob and having a small set
of functions to manipulate it. Dynamic columns should be used when it is not
possible to use regular columns. A typical use case is when one needs to store
items that may have many different attributes (like size, color, weight, etc),
and the set of possible attributes is very large and/or unknown in advance. In
that case, attributes can be put into dynamic columns.

Dynamic Columns Basics
----------------------

The table should have a blob column which will be used as storage for dynamic
columns:

create table assets (
 item_name varchar(32) primary key, -- A common attribute for all items
 dynamic_cols  blob  -- Dynamic columns will be stored here
);

Once created, one can access dynamic columns via dynamic column functions:

Insert a row with two dynamic columns: color=blue, size=XL

INSERT INTO assets VALUES 
 ('MariaDB T-shirt', COLUMN_CREATE('color', 'blue', 'size', 'XL'));

Insert another row with dynamic columns: color=black, price=500

INSERT INTO assets VALUES
 ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500));

Select dynamic column 'color' for all items:

SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) 
 AS color FROM assets;
+-----------------+-------+
| item_name       | color |
+-----------------+-------+
| MariaDB T-shirt | blue  |
| Thinkpad Laptop | black |
+-----------------+-------+

It is possible to add and remove dynamic columns from a row:

-- Remove a column:
UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, "price") 
WHERE COLUMN_GET(dynamic_cols, 'color' as char)='black';

-- Add a column:
UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years')
WHERE item_name='Thinkpad Laptop';

You can also list all columns, or get them together with their values in JSON
format:

SELECT item_name, column_list(dynamic_cols) FROM assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB T-shirt | `size`,`color`            |
| Thinkpad Laptop | `color`,`warranty`        |
+-----------------+---------------------------+

SELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

Dynamic Columns Reference
-------------------------

The rest of this page is a complete reference of dynamic columns in MariaDB

Dynamic Columns Functions
-------------------------

COLUMN_CREATE
-------------

COLUMN_CREATE(column_nr, value [as type], [column_nr, value 
 [as type]]...);
COLUMN_CREATE(column_name, value [as type], [column_name, value 
 [as type]]...);

Return a dynamic columns blob that stores the specified columns with values.

The return value is suitable for

* 
storing in a table
further modification with other dynamic columns functions

The as type part allows one to specify the value type. In most cases, this is
redundant because MariaDB will be able to deduce the type of the value.
Explicit type specification may be needed when the type of the value is not
apparent. For example, a literal '2012-12-01' has a CHAR type by default, one
will need to specify '2012-12-01' AS DATE to have it stored as a date. See the
Datatypes section for further details. Note also MDEV-597.

Typical usage:

-- MariaDB 5.3+:
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE(1 /*column id*/, "value");
-- MariaDB 10.0.1+:
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");

COLUMN_ADD
----------

COLUMN_ADD(dyncol_blob, column_nr, value [as type], 
 [column_nr, value [as type]]...);
COLUMN_ADD(dyncol_blob, column_name, value [as type], 
 [column_name, value [as type]]...);

Adds or updates dynamic columns.

* 
dyncol_blob must be either a valid dynamic columns blob (for example,
COLUMN_CREATE returns such blob), or an empty string.
column_name specifies the name of the column to be added. If dyncol_blob
already has a column with this name, it will be overwritten.
value specifies the new value for the column.  Passing a NULL value will cause
the column to be deleted.
as type is optional. See #datatypes section for a discussion about types.

The return value is a dynamic column blob after the modifications.

Typical usage:

-- MariaDB 5.3+:
UPDATE tbl SET dyncol_blob=COLUMN_ADD(dyncol_blob, 1 /*column id*/, "value") 
 WHERE id=1;
-- MariaDB 10.0.1+:
UPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, "column_name", "value") 
 WHERE id=1;

Note: COLUMN_ADD() is a regular function (just like CONCAT()), hence, in order
to update the value in the table you have to use the UPDATE ... SET
dynamic_col=COLUMN_ADD(dynamic_col, ....) pattern.

COLUMN_GET
----------

COLUMN_GET(dyncol_blob, column_nr as type);
COLUMN_GET(dyncol_blob, column_name as type);

Get the value of a dynamic column by its name. If no column with the given
name exists, NULL will be returned.
