【问题标题】:database design to count distinct values数据库设计以计算不同的值
【发布时间】:2018-07-10 09:09:12
【问题描述】:

我想跟踪我的应用程序中的不同方面。这些方面由客户端报告给服务器。客户端报告数据格式如下:

AspectReport
  ClientId int, //client that reported the apsect
  AspectId int, //aspect that we got a value for
  Value string  //arbitrary string

相同的aspect可以用相同或不同的值多次报告。

在服务器端,我只想跟踪每个客户端和方面的 unqiue 值。因此,我需要能够存储已报告的值以及来自哪个客户端。

标准化结构可能如下所示:

Aspect
  Id
  Name

// used to store all reported values for 
// the aspect, no matter which client reported it
// (each client can report a subset of all values)
ApplicationAspectValues   
  Id
  AspectId 
  Value

// Which unique values a specific client reported
ClientAspectValues
  Id
  ClientId
  AspectId
  Value

可能有数千个客户(我们最大的客户迄今为止有 20000 个客户)可以针对少数几个方面报告每个方面的数千个值。

写比读要频繁得多。从长远来看,我预计每秒会报告数百个方面。每天最多使用几次读取(对于客户端)。

很少使用纵横比值。仅在更深入地分析系统(Web 应用程序)时显示报告的值。相反,这些值通常用于计算每个方面和客户端 (ClientValues.Count / ApplicationValues.Count) 报告的值的百分比,并确保只存储唯一值。

遵循 3NF 意味着每次收到一个新方面时都会查询和更新几行,这似乎有点低效。

是否有更好的设计允许:

  • 优化写入
  • 确保只存储唯一值
  • 允许偶尔检索客户端/方面的所有值(显示给用户)。

我的幼稚实现是在代码中进行重复检查,然后将带有所有值的 gzip 压缩逗号分隔字符串与计数器字段一起存储在 ApplicationAspectValuesClientAspectValues 的列中。

像这样:

ClientAspectValues
  Id
  ClientId
  AspectId
  NumberOfUniqueValues
  Values

这样,只有一行用于检查重复项和更新报告值。对于大多数读取场景,这些值永远不会被获取。

我确定有更好的解决方案?

这个问题贴在这里,因为结合代码和数据库的解决方案非常好

(我们的产品中还有其他几个以相同频率写入数据库的功能,优化不仅仅是为了适应这个功能,而是为了完整的画面)

【问题讨论】:

  • 如果您只想要唯一值,则将该值设为主键。数据库不允许重复。
  • 另一个选项,将唯一值存储在 c# 缓存中并检查该缓存是否存在,然后如果它不在缓存中,则只需插入到表中,并在插入新方面时清除缓存.应该减少数据库的负载。

标签: c# sql-server database-design database-normalization


【解决方案1】:

我会使用您的 3NF 设计,但使用表 ClientAspectValue 来存储所有新写入。

然后,我将创建一个批处理,定期读取 ClientAspectValue ,获取唯一值,并将它们存储到专用表 - ClientAspectUniqueValues 中。

【讨论】:

  • 这实际上是一个很好的解决方案。添加入站值时根本不需要查询。一个查询就足以找到新的唯一值(使用左连接)。为清楚起见,我将第一个表命名为 InboundPartitionValues,并保留其他表名。
【解决方案2】:

架构设计:

标准化结构应如下所示:

Client
  Client_ID        Primary Key
  Other_Columns....


Aspect
  Aspect_Id        Primary Key
  Name


ApplicationAspectValues   
  AAV_Id           Primary Key
  Aspect_Id        Foreign Key       
  Value                         Unique Constraint on Aspect_Id &  Value


ClientAspectValues
  CAV_Id            Primary Key
  Client_Id         Foreign Key
  AAV_Id            Foreign Key
  Reported          Time Stamp

现在在 ClientAspectValues 上创建一个视图以即时计算不同的值,不要将不同的值存储在任何地方,让它们保持更新会很痛苦,实际上有点不可能。

不要担心添加的行数,考虑存储您以后可能需要的所有信息(尤其是报告的时间戳)。

还与企业讨论并要求某种保留期,例如 6 个月或一年。

每晚将旧数据(比企业决定的保留期限更早)清除到某种数据仓库以用于报告目的。

【讨论】:

    猜你喜欢
    • 2010-11-25
    • 1970-01-01
    • 2011-05-21
    • 2017-05-29
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多