定义用户分析的Web服务(dekstop应用程序)

Bag*_*onè 6 mysql database analytics desktop-application database-normalization

目前的情况
我有一个桌面应用程序(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个数据字段,但这似乎非常浪费.

对这种模型有什么想法吗?也许像谷歌分析?请指教...

技术: DB是在phpMyAdmin下运行的MySQL.

免责声明: 有一个类似的帖子,它引起我的注意服务,如DeskMetricsTracker鸟,或尝试将谷歌分析嵌入到C++本机应用程序,但我宁愿自己的服务,更好地了解如何设计这个有点模型.

谢谢!

Aam*_*mir 2

这似乎是一个数据库规范化问题。

我还假设您还有一个名为events存储所有事件的表。

此外,我假设您必须具有以下数据属性(为了简单起见):window_name, source_id, user_action, index

为了实现标准化,我们需要下表:

events
data_attributes
attribute_types
Run Code Online (Sandbox Code Playgroud)

每个表的结构如下:

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    |                |
+-------+------------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)

这个想法是,您必须填充attribute_types所有可能的类型。然后,对于每个新事件,您将在表中添加一个条目events以及表中的相应条目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}
Run Code Online (Sandbox Code Playgroud)

将表示为:

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 |
+----+----------+----------------+-------------------+-----------------+
Run Code Online (Sandbox Code Playgroud)

要为此数据编写查询,您可以使用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
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

+-------------------+----------------+-------------------+
| 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                |
+-------------------+----------------+-------------------+
Run Code Online (Sandbox Code Playgroud)