现在的情况
我有一个桌面应用程序(C Win32),我希望匿名跟踪用户的使用情况分析(操作,点击,使用时间等)
跟踪是通过指定的Web服务完成的,用于特定操作(安装,卸载,单击),所有内容都由我的团队编写并存储在我们的数据库中.
需要
现在我们使用各种数据添加更多使用类型和事件,因此我们需要定义服务.
我希望为所有使用类型提供单一的通用服务,而不是为每个操作提供大量不同的Web服务,这些服务能够接收不同的数据类型.
例如:
>“button_A_click”事件,包含1个字段的数据:{window_name(string)}
>“show_notification”事件,包含3个字段的数据:{source_id(int),user_action(int),index(int)}
题
我正在寻找一个优雅的&存储这种不同数据的便捷方式,以后我可以轻松查询.
我能想到的替代方案:
>将每种使用类型的不同数据存储为JSON / XML对象的一个字段,但是为这些字段提取数据和编写查询将非常困难
>为每条记录提供额外的N个数据字段,但这似乎非常浪费.
对这种模型有什么想法吗?也许像谷歌分析?请指教…
免责声明:
有一个similar post,它引起我的注意服务,如DeskMetrics和Tracker bird,或尝试将谷歌分析嵌入到C本机应用程序,但我宁愿自己的服务,并更好地了解如何设计这种模型.
谢谢!
我还假设您还有一个名为events的表,其中将存储所有事件.
此外,我将假设您必须具有以下数据属性(为简单起见):window_name,source_id,user_action,index
要实现规范化,我们需要以下表格:
events
data_attributes
attribute_types
这就是每个表的结构:
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 | |
+-------+------------------+------+-----+---------+----------------+
我们的想法是,您必须使用所有可能的类型填充attribute_types.然后,对于每个新事件,您将在事件表中添加一个条目,并在data_attributes表中添加相应的条目,以将该事件映射到具有适当值的一个或多个属性类型.
例:
"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}
将表示为:
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 |
+----+----------+----------------+-------------------+-----------------+
要编写此数据的查询,可以使用MysqL中的COALESCE函数为您获取值,而无需检查哪些列为NULL.
这是我破解的一个简单示例:
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
产生以下输出:
+-------------------+----------------+-------------------+
| 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 |
+-------------------+----------------+-------------------+