代码之家  ›  专栏  ›  技术社区  ›  Igor Serebryany

数据库中的结构化数据与非结构化数据

  •  3
  • Igor Serebryany  · 技术社区  · 16 年前

    这个问题是一个设计问题。我正在收集大量的性能数据和大量的键值对。在/proc/cpuinfo,/proc/meminfo/,/proc/loadavg中几乎所有的东西,加上其他一些东西,来自几百个主机。现在,我只需要在ui中显示最新的数据块。我可能最终会对收集到的数据进行一些分析,以找出未来的性能问题,但这是一个新的应用程序,所以我还不确定我到底在寻找什么样的性能方面的问题。

    我可以在数据库中构造数据——为收集的每个键都有一个列。该表最终将是o(100)列宽,放入数据库会很痛苦,如果我开始收集新的统计数据,我将不得不添加新的列。但是仅仅使用sql就可以很容易地对数据进行排序/分析。

    或者我可以将非结构化数据块转储到表中。可能有三列——主机ID、时间戳和数组的序列化版本,可能在文本字段中使用JSON。

    我该怎么办?如果我采用非结构化的方法,我会后悔吗?在进行分析时,我应该转换感兴趣的字段并创建一个新的、更结构化的表吗?我在这里错过了哪些取舍?

    5 回复  |  直到 16 年前
        1
  •  3
  •   Bill Karwin    16 年前

    我说,如果需要运行sql查询来计算min/max/avg之类的值,或者根据这些值执行排序、限制或联接,那么应该创建100多列。那就是我要做的。

    您不需要说明您使用的是哪个品牌的数据库,但大多数数据库应该支持表中的100多列,而不会有效率低下的风险。

    拜托 不要 使用 Entity-Attribute-Value 反模式——一些人会建议的关键/价值设计。在这样的设计中插入任意的键/值对集合是很好的,也很容易,但是在传统的表中,每个属性只有一列,这样的查询在eav设计中变得非常困难和低效。使用sql数据库也会失去许多优势,比如数据类型和约束。

        2
  •  0
  •   Randy    16 年前

    我想

    性能数据

            host_id
            key
            value
            timestamp
    

    是正确的结构。您将能够在特定时间从特定主机查询特定子集以生成分析。

        3
  •  0
  •   APC    16 年前

    这里有一个替代的解决方案:使用多个表。

    一个明显的模式设计是为每个 cpuinfo , meminfo , loadavg 等等,你可能会 miscellaneous_stats 桌子,这取决于你在“一堆其他东西”中的内容。

    这种方法有几个吸引人的特点:

    • 简化列命名。
    • 很容易根据相关的一组统计数据进行报告,例如 内存信息 . 或许还有更好的表现。
    • 添加列的问题更少。如果你开始收集新的 小精灵 统计数据,它们都聚集在一起,而在一个大杂音,你会结束列1-15和列94。
    • 记录的粒度。例如,您可能不想记录 CPUFIN 经常 内存信息 .

    你应该有一张主桌 stats_runs 保存诸如主机、时间戳等内容,而不是在每个表上复制这些细节。

    我有两个基本的工作假设:

    1. 要对这些数据做一些分析(因为如果你在收集数据的时候不打算分析它?).
    2. sql仍然是数据处理的最佳机制,尽管平面文件工具一直在改进。
        5
  •  0
  •   Igor Serebryany    16 年前

    谢谢你的建议。

    在考虑了这个问题之后,我决定采用两个表的方法。一个表保存最新的原始数据转储,格式与我最初获得的json格式相同。我使用这个来显示最新的统计数据——最常见的用例——如果试图解析转储文件中的所有字段,而只是在有人想查看当前状态时重新组合它们,那就太傻了。

    我已经从这些原始数据中挑选出一些我想做长期分析的统计数据,并将它们存储在一个宽表(很多列)中。这将使我能够轻松地呈现趋势图并发现性能问题。

    根据我在eav方面的经验,我认为这不是一个好主意。它既不容易做长期分析(40路连接或枢轴问题),也不容易,因为我的数据不是平面的,它会使存储原始数据更容易。