Database design 关系数据库-如何决定是存储数据还是计算数据?

Database design 关系数据库-如何决定是存储数据还是计算数据?,database-design,relational-database,Database Design,Relational Database,假设数据库中有两个表,一个用于高尔夫球员,另一个用于高尔夫洞,还有一个API,它必须返回球员在他/她的生活中所击中的总球道。让API查看每个洞以计算球道命中数是最佳做法,还是直接将球道命中数存储在球员表中?似乎将这些数据存储在players表中基本上是复制数据,因为它已经存在于每个孔中。但为了计算它,你需要每次都通过球员打过的每个洞 更一般地说,这仅仅是一种需要在正确的数据设计和性能之间取得平衡的情况吗 我意识到这可能需要一个主观的答案(如果需要的话,很抱歉),但我对数据库设计的了解还不够,不知

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

更一般地说,这仅仅是一种需要在正确的数据设计和性能之间取得平衡的情况吗


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

存储派生数据会产生某些风险或责任。您必须维护导出的数据,否则将面临回答错误的风险。这会增加系统的复杂性和工作量。在某些情况下,值得在写入时增加复杂性以降低读取时的复杂性,特别是在计算复杂且计算结果可以增量更新的情况下


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

存储派生数据会产生某些风险或责任。您必须维护导出的数据,否则将面临回答错误的风险。这会增加系统的复杂性和工作量。在某些情况下,值得在写入时增加复杂性以降低读取时的复杂性,特别是在计算复杂且计算结果可以增量更新的情况下


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

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

我认为这里没有这个问题,因为您维护的是一个不会改变的历史数据集——或者至少很少改变


我认为,提供详细统计数据的摘要,并随着数据的变化对其进行维护不会有什么害处。Oracle物化视图可以为您管理这一点,尽管这不是一个便宜的选择。

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

我认为这里没有这个问题,因为您维护的是一个不会改变的历史数据集——或者至少很少改变

我认为,提供详细统计数据的摘要,并随着数据的变化对其进行维护不会有什么害处。Oracle物化视图可以为您管理这一点,尽管这不是一个便宜的选择

更一般地说,这仅仅是一种需要在正确的数据设计和性能之间取得平衡的情况吗

TL;“是”博士

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

数据模型是对 共同构成 用户与之交互的抽象机器。[1]

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

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

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

所以,是的,你需要平衡干净的设计和性能。每个人都有

最好的方法是“首先进行干净的逻辑(即关系)设计,然后作为一个单独的后续步骤,将该逻辑设计映射到目标DMB恰好支持的任何物理结构中。”

如果必须存储计算结果,最佳做法是使SQL DBMS保持一致性。例如,如果必须存储
(数量*价格)+销售税的结果,请编写CHECK()约束以确保一致性。有些DBMS不支持CHECK()约束

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

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

在所有情况下,在进行更改之前和之后,测量代表性的插入、更新和删除语句的性能

让API查看每个洞以计算球道命中数是最佳做法,还是直接将球道命中数存储在球员表中

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

但为了计算它,你需要每次都通过球员打过的每个洞

不,您不需要“穿越每一个漏洞”,至少不需要遍历每一个漏洞,尽管这正是许多前端应用程序框架所做的。您只需要一个SQL查询