【问题标题】:Best practice - logging events (general) and changes (database)最佳实践 - 记录事件(一般)和更改(数据库)
【发布时间】:2010-05-09 12:23:01
【问题描述】:

记录网站上的所有活动以及数据库更改方面需要帮助

要求:

  • 应该在数据库中
  • 应该可以通过发起者(用户名/会话 ID)、事件(活动类型)和事件参数轻松搜索

我可以想到一种数据库设计,但要么它涉及很多表(每个事件一个),因此我可以将事件的每个参数记录在一个单独的字段中,或者它涉及一个带有通用字段的表(7 int numeric和 7 种文本类型)并将所有内容记录在一个带有事件类型字段的表中,以确定将哪些参数写入何处(并希望我不需要超过 7 个某种类型的字段,或者 8 个或 9 个或我选择的任何数字)。 ..

条目示例(通常的东西):

[username] login failed @datetime
[username] login successful @datetime
[username] changed password @datetime, estimated security of password [low/ok/high/perfect]  @datetime
[username] clicked result [result number] [result id] after searching for [search string] and got [number of results] @datetime
[username] clicked result [result number] [result id] after searching for [search string] and got [number of results]  @datetime
[username] changed profile name from [old name] to [new name]  @datetime
[username] verified name with  [credit card type] credit card  @datetime
datbase table [table name] purged of old entries @datetime via automated process

等等……

所以之前有人处理过这个问题?有任何最佳做法/可以分享的链接

我已经看到它使用上面提到的通用解决方案完成了,但不知何故,这与我从数据库设计中学到的东西背道而驰,但是正如您所见,需要跟踪的事件的绝对数量(每个用户都能够看到这个信息)让我很头疼,但我确实更喜欢每桌一个事件的解决方案,而不是通用的解决方案。

有什么想法吗?

编辑:另外,在某处可能有此类(可能)事件的权威列表吗?

thnx

堆栈溢出说:您提出的问题看起来很主观,可能会被关闭。
我的回答:可能是主观的,但这与我在设计数据库/编写代码时遇到的问题直接相关,所以我欢迎任何帮助。我还尝试将想法缩小到 2 个,因此希望其中一个会占上风,除非已经有针对此类事情的既定解决方案。

【问题讨论】:

  • Stackoverflow 说,仅因为您在标题中写了“最佳实践”,这不是对您的问题的分析:)
  • 是的,我想,但只是想确保我没有被误解。谢谢

标签: database-design events logging


【解决方案1】:
  1. 就插入/删除/更新而言,记录数据库更改,就最佳实践而言,通常由主表上的触发器将条目写入审计表(每个真实表一个审计表,相同的列 + when/what/who 列)。

  2. 作为通用列表的事件列表不存在。这实际上是您的应用程序/框架/环境/业务需求的功能。就最佳实践而言,最好确定您的事件类型列表是 100% 平坦、2 级层次结构(类型/子类型 - 这通常是最好的方法)还是 N 级层次结构(更难/更少实施高效,但非常灵活,并为适当的企业活动管理提供了非常好的可能性 - 我参与了所有 3 个方案的实施,所以我从实践中说出来 BTW。

  3. 您不需要 1 个表中的 7 个通用 int 字段来存储事件详细信息。而是使用标签值对表:

    EVENT_TYPES: (event_type, event_subtype, description, subtype_attr1, ...) 事件:(event_id、event_type、event_subtype、timestamp、attrib1、...) EVENT_DETAILS:(event_id、tag、int_value、varchar_value、float_value)。

    EVENT_DETAILS 可以归一化为 EVENT_DETAILS_INT、EVENT_DETAILS_VARCHAR、EVENT_DETAILS_FLOAT ……如果您愿意,但不是真的需要。

    EVENTS 表中的attrib1-atttribN 是适用于所有/大多数事件的通用属性,例如用户标识、主机名、pid 等...

    EVENT_TYPES 是一个描述各种事件类型/子类型的表。

    根据您决定第 2 点的方式,此表可能存储类型的平面列表、类型/子类型映射列表(如我的示例中所示)或父类型/子类型的层次结构(您需要 2 个表即,一个用于类型的父/子映射,一个用于每种类型的类型属性)。

    您可能需要另一个辅助表 EVENT_TYPE_ATTRIBUTES 将事件类型映射到 EVENT_DETAILS 的有效标记。


示例

事件:[用户名]在搜索[搜索字符串]后点击结果[结果编号][结果id]得到[结果数量]@datetime

这将产生与此类似的数据(不是实际的 SQL 语法,请告我 :):

EVENT_TYPES: (USER_ACTION, USER_CLICK, "用户点击了某些东西") 事件:(12345,“USER_ACTION”,“USER_CLICK”,@datetime,“[用户名]”, “app_name”,“pid”...) EVENT_DETAILS:几行: (12345, "result_number", 33, NULL, NULL) // 或者在没有 NULL 的情况下进入 EVENT_DETAILS_INT? (12345,“result_id”,919292,NULL,NULL) (12345,“search_string”,NULL,“我如何在 DB 中记录事件”,NULL)

【讨论】:

  • 对不起,我想我有点明白你的想法,我确实喜欢它,只是不确定表 0 和表 1。例如,如果我有一个事件:[username] 在搜索 [search string] 并得到 [number of results] @datetime 后点击了结果 [result number] [result id] 你能更新你的答案吗?我没有得到事件类型和事件子类型,尤其是要输入的内容和子类型的内容,因此表 0 的内容是表 1 的内容。感谢您提供的看起来非常优雅的解决方案。
  • TYPE 可能是 USER_ACTION,SUBTYPE 可能是 USER_CLICK。但这真的真的取决于你的问题领域,只有你才能真正确定。
  • EVENTS 表将获得一个条目 (12345, "USER_ACTION","USER_CLICK", "[username]", "app_name", "pid"...) 并且 EVENT_DETAILS 将包含如下行(12345, "result_number", 33), (12345, "result_id", 919292) 等等...... - 希望
  • THNX 这么详细的信息!!
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 2010-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多