This seems like a database normalization problem.
I also assume that you also have a table called events where all events will be saved.
Also, I'm going to assume that you have the following data attributes (for simplicity): window_name, source_id, user_action, index
To achieve normalization, we need the following tables:
events data_attributes attribute_types
Here's how each of the tables should be structured:
mysql> describe events; +------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | NO | PRI | NULL | auto_increment | | event_type | varchar(255) | YES | | NULL | | +------------+------------------+------+-----+---------+----------------+ mysql> describe data_attributes; +-----------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | NO | PRI | NULL | auto_increment | | event_id | int(11) | YES | | NULL | | | attribute_type | int(11) | YES | | NULL | | | attribute_name | varchar(255) | YES | | NULL | | | attribute_value | int(11) | YES | | NULL | | +-----------------+------------------+------+-----+---------+----------------+ mysql> describe attribute_types; +-------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+------------------+------+-----+---------+----------------+ | id | int(11) unsigned | NO | PRI | NULL | auto_increment | | type | varchar(255) | YES | | NULL | | +-------+------------------+------+-----+---------+----------------+
The idea is that you will need to fill attribute_types all possible types that you have. Then, for each new event, you add an entry to the events table and the corresponding entries in the data_attributes table to map this event to one or more attribute types with the corresponding values.
Example:
"button_A_click" event, has data with 1 field: {window_name "Dummy Window Name"} "show_notification" event, has data with 3 fields: {source_id: 99, user_action: 44, index: 78}
will display as:
mysql> select * from attribute_types; +----+-------------+ | id | type | +----+-------------+ | 1 | window_name | | 2 | source_id | | 3 | user_action | | 4 | index | +----+-------------+ mysql> select * from events; +----+-------------------+ | id | event_type | +----+-------------------+ | 1 | button_A_click | | 2 | show_notification | +----+-------------------+ mysql> select * from data_attributes; +----+----------+----------------+-------------------+-----------------+ | id | event_id | attribute_type | attribute_name | attribute_value | +----+----------+----------------+-------------------+-----------------+ | 1 | 1 | 1 | Dummy Window Name | NULL | | 2 | 2 | 2 | NULL | 99 | | 3 | 2 | 3 | NULL | 44 | | 4 | 2 | 4 | NULL | 78 | +----+----------+----------------+-------------------+-----------------+
To write a query for this data, you can use the COALESCE function in MySQL to get the value for you without checking which of the NULL columns.
Here is a quick example that I hacked:
SELECT events.event_type as `event_type`, attribute_types.type as `attribute_type`, COALESCE(data_attributes.attribute_name, data_attributes.attribute_value) as `value` FROM data_attributes, events, attribute_types WHERE data_attributes.event_id = events.id AND data_attributes.attribute_type = attribute_types.id
Which gives the following result:
+-------------------+----------------+-------------------+ | event_type | attribute_type | value | +-------------------+----------------+-------------------+ | button_A_click | window_name | Dummy Window Name | | show_notification | source_id | 99 | | show_notification | user_action | 44 | | show_notification | index | 78 | +-------------------+----------------+-------------------+