【问题标题】:Database Structure for hierarchical data with horizontal slices具有水平切片的分层数据的数据库结构
【发布时间】:2012-03-25 20:11:59
【问题描述】:

我们目前正在努力提高我们网站的查询性能,核心分层数据结构有 5 个级别,每个类型有大约 20 个字段。

level1: rarely added, updated infrequently, ~ 100 children
level2: rarely added, updated fairly infrequently, ~ 200 children
level3: added often, updated fairly often, ~ 1-50 children (average ~10)
level4: added often, updated quite often, ~1-50 children (average <10)
level5: added often, updated often (a single item might update once a second)

我们有一个单一的数据管道来执行所有这些更新和插入(即,我们可以完全控制进入的数据)。

对此我们需要做的查询是:

fetch single items from a level + parents
fetch a slice of items across a level (either by PK, or sometimes filtering criteria)
fetch multiple items from level3 and parts of their children (usually by complex criteria)
fetch level3 and all children

我们从这个数据源读取了很多数据,每秒数百次。我们需要执行的所有查询都是已知的和优化的,就像它们可以针对当前数据结构一样。

我们目前在 memcached 后面使用 MySQL 查询,并且只是做额外的查询来获取孩子/父母,我认为某种基于树或基于文档的数据库可能更合适。

我的问题是:对这些数据进行建模以提高读取性能的最佳方法是什么?

【问题讨论】:

    标签: database database-design language-agnostic nosql database-schema


    【解决方案1】:

    听起来您的数据属于 OLAP(在线分析处理)数据库。您描述级别、切片和性能问题的方式似乎适用于 OLAP。它可能建模得很好(虽然不确定),但您需要一个不同的工具来提高性能。

    我目前管理这样的系统。我们有一个标准的关系数据库用于输入,然后将相关数据复制到 OLAP 服务器以进行报告。我们的组合是 Microsoft SQL Server(输入、原始数据)、Microsoft Analysis Services(预先计算然后存储分析数据以提高速度)和 Microsoft Excel/Access 数据透视表和/或用于报告的 Tableau。

    OLAP 服务器: http://en.wikipedia.org/wiki/Comparison_of_OLAP_Servers

    结合关系和 OLAP: http://en.wikipedia.org/wiki/HOLAP

    画面: http://www.tableausoftware.com/

    *Tableau 是一款出色的产品,如果您的数据不是特别大(即使这样它也可以处理大量数据),它可能可以替代 OLAP 服务器。它将根据需要制作本地副本以提高性能。我强烈建议你看看。

    如果我误解了您遇到的问题,那么请务必忽略此答案:\

    更新:经过更多讨论,Object DB 也可能是一种解决方案。您的数据本质上听起来是多维的,一种或另一种方式,但我认为区别在于您是在进行分析聚合计算和检索(SUM、AVG),还是只是存储和获取分类或关系数据(购物车物品或家庭成员的朋友)。

    ODBMS 信息:http://en.wikipedia.org/wiki/Object_database

    InterSystem 的缓存是我所知道的一个对象数据库,根据您所说的,这听起来更合适。

    http://www.intersystems.com/cache/

    如果转换到不同的系统不可行(完全可以理解),那么您可能需要查看规范化和查询正在处理的数据类型,以便进一步提高速度。事实上,这可能是跳到不同类型系统之前的良好第一步(抱歉,我没有早点了解)。

    在我的例子中,我知道在 MS SQL 上,我们从使用 VARCHAR 字段到使用 INTEGER 字段的一些核心查询的切换在速度上产生了巨大的差异。文本数据是处理成本最高的数据类型之一。因此,例如,如果您有一个查询在文本字段上执行大量 INNER JOINs,您可能会考虑规范化到使用链接到文本数据的 INTEGER ID 的程度。

    高度规范化的一个例子是使用身份证号码作为一个人的名字或姓氏。大多数数据库设计直接存储这些名称并且不尝试减少重复,但您可以规范化到姓氏和/或名字有自己的表(或一个表同时保存名字和姓氏)和 ID每个唯一的名称。

    在您的案例中,重点是提高性能而不是重复数据删除,但是从VARCHAR 切换到INTEGER 之类的事情可能会带来巨大的收益。我会先在单个字段上进行尝试,测量前后案例,然后从那里仔细做出决定。

    当然,一般来说,您应该确保对您的数据有适当的索引。

    希望对您有所帮助。

    【讨论】:

    • 我以前没有看过 OLAP,但我怀疑由于我们的阅读量很高,而且有众所周知的查询,这不会是前进的方向(我想我会在这个问题,但显然我没有)
    • 不,我认为您解释得很好,我只是提供一种我认为可能适合您的用例的替代方案。重新阅读您的问题,我不确定某些细节。一个问题是,您是否有这些查询正在更新/获取的聚合数据(SUM、AVG 等),或者它们是否获取分类或关系数据(购物车中的项目或家庭成员的朋友等)之类的东西?您的用例听起来像是多维数据,但区别可能在于 OLAP DB 与 Object DB(例如:InterSystems Cache)。用更多链接更新我的答案。
    • 为我的回答添加了更多细节和其他解决方案。
    • 我认为我们的一般方法是将我们的读取表去规范化,使其更像数据的物化视图。您关于更改列类型的观点是一个很好的观点,我没有真正认真考虑过行长度。
    • 当我第一次尝试更改查询在 JOIN 等上使用的数据类型时,我自己感到非常惊讶,因为我认为数据库会通过索引来优化它,但在我们的例子中并非如此。不同的 DBMS 系统在这方面也可能有所不同,所以一定要设置一些仔细的测试(考虑在你的数据库副本上进行测试,而不是实时的)并测量差异,看看实施更改是否有益。跨度>
    【解决方案2】:

    基于文档/树的数据库旨在执行分层查询。您的设计中是否有任何分层查询——我没有看到任何?向上和向下查询一个级别不算:它是一个简单的连接。请记住,走“基于文档/树的数据库”路线会损害您的一般查询能力。总而言之,只需聘请一位称职的数据库专家来分析您的性能瓶颈——它们通常可以通过添加普通索引来解决。

    【讨论】:

      【解决方案3】:

      这里没有足够的信息来说明很多有用的信息 - 您需要衡量事物,查看“解释”等 - 但超出通常索引的一种选择是按 3 级实例进行分片。这将使您在处理不同分片的并行查询时获得更好的性能,最简单(单独的磁盘),或者如果您想在每个分片上投入更多资源,您可以使用单独的机器。

      我真正提到这一点的唯一原因是您的用例表明该级别的分片会工作得很好(如果您愿意,它看起来很简单,可以在您的应用程序层中执行 - 我不知道什么工具mysql有这个)。

      如果您的数据量不是那么高,那么通过分片您也许可以将其降低到 ssds...

      【讨论】:

        猜你喜欢
        • 2010-12-22
        • 2015-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多