【问题标题】:Relational Database - How to decide whether to store data or calculate data?关系数据库 - 如何决定是存储数据还是计算数据?
【发布时间】:2016-07-10 02:05:25
【问题描述】:

假设您在数据库中有两张表,一张用于高尔夫球手,一张用于高尔夫球洞,还有一个 API,该 API 必须返回玩家一生中击球的总球道数。最好的做法是让 API 查看每个球洞以计算击球道的数量,还是直接将击球的球道存储在球员表中?似乎将这些数据存储在球员表中基本上是复制数据,因为它已经存在于每个洞中。但是为了计算它,你需要每次都通过球员打过的每个洞。

更一般地说,这只是一种需要平衡正确数据设计与性能的情况吗?

我意识到这可能需要一个主观的答案(抱歉,如果需要的话),但我对数据库设计的了解还不够,无法知道它们是否是对这种情况的明确答案。

【问题讨论】:

    标签: database-design relational-database


    【解决方案1】:

    更一般地说,这只是一种需要平衡正确数据设计与性能的情况吗?

    TL;DR“是”。

    关系模型与性能无关。 数据的关系模型是一种形式化的理论;它是众多数据模型之一。

    数据模型是一个抽象的、自包含的、逻辑的定义 对象、运算符等,它们共同构成 用户与之交互的抽象机器。[1]

    抽象机器没有性能问题,因为它在物理意义上不存在。这就是为什么,例如,关系模型对索引只字未提。

    另一方面,SQL 数据库很多与性能有关。 SQL 数据库有一个物理实现,其性能受内核数量的影响;内存量;磁盘空间、配置和主轴速度;并发用户数;索引;等等。

    区别在于逻辑与物理、抽象与具体、原则与实践的区别。

    所以是的,您需要平衡简洁的设计和性能。每个人都这样。

    做到这一点的最佳方法是“首先进行清晰的逻辑(即关系)设计,然后作为单独的后续步骤,将该逻辑设计映射到目标 DMBS 恰好支持的任何物理结构中。” [2]

    如果必须存储计算结果,最佳做法是让 SQL DBMS 保持一致性。例如,如果您必须存储(quantity * price) + sales_tax 的结果,请编写一个 CHECK() 约束以保证一致性。一些 DBMS 不支持 CHECK() 约束。

    如果您必须跨多行维护计数(计数),请使用物化视图。一些 DBMS 不支持物化视图。

    在最坏的情况下,您只能使用某人阅读的报告来确定是否存在不一致之处。该人会采取纠正措施。

    在所有情况下,测量具有代表性的 INSERT、UPDATE 和 DELETE 语句在进行更改之前和之后的性能。

    最佳实践是让 API 查看每个球洞以计算击球道数,还是直接将击球数存储在球员表中?

    有很多统计数据。您应该可能将统计信息存储在一个或多个附加表中。 SQL DBMS 不必“查看每个漏洞”;他们在布景上运作。

    但是为了计算它,你需要每次都遍历玩家打过的每个洞。

    不,您不需要“遍历每一个漏洞”,至少不需要迭代遍历每一个漏洞,尽管这正是许多前端应用程序框架所做的.您只需要一个 SQL 查询,例如 select count(*) from player_holes where fairway_hit = True;


    [1] 数据库系统简介,第 7 版,C. J. Date,第 14 页

    [2] 同上,第 327 页。

    【讨论】:

    • 你让我想起了我最近读到的一句话:“System R 项目的目的是驳斥那些声称 Codd 模型不可行的专家的说法,出于性能原因。SQL 是由人设计的他们的主要兴趣和技能在于 DBMS 工程 [而不是] 计算机语言设计。” source
    • “一些 DBMS 不支持 CHECK() 约束”——由于关系的复杂性和任意复杂性的数据库约束,那些确实倾向于将它们限制在属性级别和元组级别。 MS Access 据称支持表级检查约束,但实际上它们是逐行检查的,因此实际上毫无用处!
    【解决方案2】:

    存储派生数据会产生一定的风险或责任。您必须维护派生数据或冒着错误答案的风险。这会增加系统的复杂性和工作量。在某些情况下,值得在写入时增加复杂度以减少读取时的复杂度,尤其是在计算复杂且计算结果可以增量更新的情况下。

    在您的示例中,我会尝试在存储派生数据之前通过索引来实现良好的性能。这听起来像是一个可以单独从合适的索引来回答的查询,而不需要加载任何物理行。

    【讨论】:

      【解决方案3】:

      非规范化的主要问题是维护重复数据所需的代码的序列化和复杂性。

      我认为您在这里不存在这个问题,因为您正在维护一个不会改变的历史数据集——或者至少,只会很少改变。

      我认为提供详细统计信息的摘要并在数据发生变化时对其进行维护不会有任何害处。 Oracle 物化视图会为您解决这个问题,尽管它不是一个便宜的选择。

      【讨论】:

        猜你喜欢
        • 2012-09-23
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        • 1970-01-01
        • 2014-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多