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

时间:2016-07-10 02:05:26

标签: database-design relational-database

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

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

我意识到这可能需要一个主观的答案(对不起,如果确实如此),但我对数据库设计知之甚少,不知道它们是否是对这种情况的确定答案。

3 个答案:

答案 0 :(得分:2)

  

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

TL; DR"是"。

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

  

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

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

另一方面,SQL数据库的 lot 与性能有关。 SQL数据库具有物理实现,其性能受核心数量的影响;记忆量;磁盘空间,配置和主轴速度;并发用户数;指标;等等。

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

所以是的,您需要在清洁设计与性能之间取得平衡。每个人都这样。

最好的方法是先做一个干净的逻辑(即关系)设计,然后作为一个单独的后续步骤,将该逻辑设计映射到目标DMBS发生的任何物理结构中。 。支持" [2]

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

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

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

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

  

最佳做法是让API查看每个洞来计算球道击球的数量,或者只是直接在球员桌上存放球道?

有很多统计数字。您应该可能在一个或多个附加表中存储统计信息。 SQL DBMS不必查看每个洞&#34 ;;他们在集合中运作。

  

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

不,你不需要经历每一个洞,至少在每个洞中迭代的意义上都是如此,尽管这样做正是很多前端应用程序框架所做的事情。您只需要一个SQL查询,如select count(*) from player_holes where fairway_hit = True;

<小时/> [1] 数据库系统简介,第7版,C。J. Date,第14页

[2]同上,第327页。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

我不相信提供详细统计数据的摘要,并在数据变化时维护它们会有害。 Oracle物化视图可以为您管理,虽然它不是一个便宜的选择。