代码之家  ›  专栏  ›  技术社区  ›  James McMahon

好的(=fast)存储策略,用于动态变化维度的事实?

  •  1
  • James McMahon  · 技术社区  · 16 年前

    我需要在数据库中存储大量的计量数据。 记录由标识数据源的ID、时间戳和值组成。这些记录随后通过ID及其时间戳进行检索。

    根据我以前的经验(我正在开发一个在过去五年中一直在生产性使用的应用程序的继承者),磁盘I/O是数据检索的相关性能瓶颈。(也见) this other question of mine )

    由于我从不查找单行,而是始终查找(可能是大型)匹配一系列ID和时间戳的行组,因此,一个相当明显的优化似乎是 存储更大的压缩数据块 通过一个小得多的索引(例如,通过一个日数)访问,并且 动态减压过滤 通过应用程序。

    我要找的是 决定将数据的哪个部分放入一个块的最佳策略 . 在一个完美的世界中,每个用户请求都将通过检索一块数据并使用其中的大部分或全部来完成。因此,我希望最小化每个请求必须加载的块的数量,并且最小化每个块的多余数据。

    我将在下面发布一个答案,包含我目前为止的想法,并使它成为社区财产,以便您可以扩展它。当然,如果你有不同的方法,请发表你自己的。

    埃塔: S. Lott 张贴 this answer 下面,这对讨论很有帮助,即使我不能直接使用它(见我的评论)。这里的要点是,我的“事实”的“维度”是(并且应该是)受最终用户的影响和随时间的变化。这是应用程序的一个核心功能,实际上也是我第一次提出这个问题的原因。

    5 回复  |  直到 16 年前
        1
  •  2
  •   S.Lott    16 年前

    “与一系列ID和时间戳匹配的行组”

    你有两个维度:源和时间。我相信数据源有很多属性。我知道时间有很多属性(年、月、日、时、周、周、季度、会计期间等)。

    虽然您的事实“只有”一个ID和一个时间戳,但它们可以具有数据源维度和时间维度的FK。

    作为星型模式,定位“与ID范围匹配的行组”的查询可能(更恰当地说)是一组具有公共数据源属性的行。它不是ID的随机集群,而是由维度的一些公共属性定义的ID集群。

    一旦定义了数据源维度的这些属性,您的“分块”策略就应该明显得多。

    此外,您可能会发现,某些数据库产品的位映射索引功能使您可以简单地将事实存储在一个简单的旧表中,而不必担心块设计。

    如果位映射索引仍然不够快,那么可能需要将数据源属性非规范化为维度和事实,然后在此维度属性上对事实表进行分区。

        2
  •  1
  •   community wiki Hanno Fietz    16 年前

    选项3:

    找到一个聪明的数据库功能来完成这项工作。

        3
  •  1
  •   Ken Gentle    16 年前

    对于选项1和3,您需要非常清楚最频繁的查询是什么。使用80/20规则,不要试图 全部的 查询在同一级别执行。

    选项2听起来很有趣,但是簿记可能会有点麻烦。

    选项3有一些承诺,它可以在不改变应用程序的情况下解决性能问题。我建议调查两件事:

    1. 表分区。Oracle和MS SQL Server(以及其他一些,我确信)支持按某个值(在本例中是日期/时间戳)对表中的数据进行物理分组。您可以将分区配置为驻留在不同的物理设备上,以便将负载分散到硬件上,希望能够减少延迟。
    2. 索引包含的列。这对我来说总是感觉不到直观,但是通过将要检索的列添加到索引中,可以执行整个查询,而无需点击实际的表。

    这两种选择的缺点都是突变操作(插入/删除),其中必须更新索引。

    您可能想尝试1和3的组合(它们在很多方面都很相似)和2的味道。跟踪关于最常查询哪个时间段的统计信息(选项2),并定期重新访问1或3中的策略,直到核心查询的性能可以接受为止。

        4
  •  0
  •   community wiki 2 revs Hanno Fietz    16 年前

    选项1:

    好好猜猜什么东西会经常被加载到一起,然后把它放在一个块中,不要太大。例:一天吃一大块

    赞成的意见:

    • 简单的数据查找可以通过简单的计算完成(请求时间范围中涉及哪些天?)而不是保留去哪里的索引。
    • 没有工具,存档结构很容易理解

    欺骗:

    • 不是最好的表演
    • 不适应应用程序用户不断变化的行为
        5
  •  0
  •   community wiki 2 revs Hanno Fietz    16 年前

    选项2:

    开发一个聪明的“再平衡策略”,跟踪数据被加载在一起,并尝试将经常被加载在一起的东西放在一起。这可能包括将行的副本保存在多个块中。

    赞成的意见:

    • 几乎可以任意聪明
    • 可以使性能变得非常有效
    • 允许发展战略

    欺骗:

    • 几乎任意难以开发、测试和调试
    • 在自我优化开始之前,可能会遇到性能不佳的问题。
    • 多个记录副本可能会膨胀存储
    • 不知怎么的,我觉得这应该由数据库来完成