关于Web应用程序数据库的实现哪一个最好:一个只有裸信息的精简且非常小的数据库,支持一个应用程序,根据需要“重新计算”所有辅助信息基本的,或者,一个数据库,里面填满了之前已经计算过但可能已经过时的所有次要信息?
显然,那里有交易,我认为有人会说这个问题的最佳答案是:“取决于”或“是两者之间的混合”。但我真的不舒服或经验不足以单独推理这个问题。有人可以分享一些想法吗?
另外,另一个不同的问题: 数据库应该是特定时刻的“快照”,还是数据库应该累积上一次的所有信息,允许回溯发生的事情?例如,假设我正在为银行账户建模。我应该只在当天保留一个人的余额,还是应该保留所有人的交易,并从这些交易中推断出余额?
关于这种东西的任何指针,不知何故,在数据库设计中更深层次?
由于
答案 0 :(得分:3)
我的快速回答是将所有内容存储在数据库中。 在谈论非常大规模的应用程序时,存储成本远低于处理成本。在小规模应用程序中,数据会少得多,因此存储仍然是一个合适的解决方案。
大多数RDMS都非常擅长处理大量数据,因此当有数百万/数万亿条记录时,仍然可以相对快速地提取数据,而不是每次都手动处理数据。
如果您选择计算数据而不是存储数据,则处理时间不会以与数据大小相同的速率增加 - 数据越多〜用户越多。这通常意味着处理时间会乘以数据的大小和用户数。
processing_time = data_size * num_users
要回答您的其他问题,我认为最佳做法是仅在数据达到如此高的值以便处理时间显着时,引入特定时刻的“快照”。< / p>
在计算大笔金额时,例如银行存款,最好将任何繁重的计算结果及其日期标记存储到数据库中。这只是意味着他们不需要再次计算,直到它变得过时。
答案 1 :(得分:2)
没有理由预先计算出过时的预先计算值。这就是触发器(除其他外)。但是对于大多数应用程序,我不会在需要之前开始预先计算。可能是计算速度始终存在。现在,在银行应用程序中,您需要几乎立即从数千甚至数百万条记录中预先计算,是的,设计一个基于触发器的预定位过程,每次更改时都会调整值。
关于是否仅按时间或历史值存储图片,这在很大程度上取决于您存储的内容。如果它与财务数据有关,请存储历史记录。审核后您将需要它。顺便提一下,设计存储一些截至操作日期的数据(这不是非规范化)。例如,您有订单,不依赖客户地址表或产品表来获取有关产品运送到何处或订单时的成本的数据。此数据随时间变化,然后您的订单不再准确。您不希望您的财务报告更改已售出的金额,因为价格在6个月后发生变化。
还有其他一些历史可能不需要存储的东西。在大多数应用程序中,我们不需要知道你是2年前的Judy Jones而且现在是Judy Smith(人力资源部申请通常是例外)。
答案 2 :(得分:1)
我说开始只是跟踪您需要的数据并动态执行计算,但是在整个设计过程中以及软件的测试/生产过程中请记住,您可能必须切换到存储在某些时候预先计算的值。设计能够在需要时移动到该模型。
添加预先计算的值是听起来不错的事情之一(因为在很多情况下它 好)但可能不需要。保持设计尽可能简单。如果性能成为动态计算的问题,那么您可以向数据库添加字段以存储计算并在一夜之间运行批处理以赶上并填写旧数据。
至于银行业的比喻,绝对存储所有交易的完整记录。存储任何相关的数据。数据库应该是过去和现在的数据存储。审计跟踪等。“当前状态”既可以在运行中计算,也可以在平面表中维护,并在写入其他表期间重新计算(如果性能需要,则触发器适用于此类事情)。
答案 3 :(得分:1)
它取决于:在数据库中保留派生数据非常有用,因为它可以实现对它的约束和其他逻辑。它也可以编入索引,或者您可以将计算放在视图中。无论如何,尽量坚持使用Boyce-Codd / 5th Normal Form作为数据库设计的指南。与您有时听到的相反,规范化不意味着您无法存储派生数据 - 它只是意味着数据不应该从同一个表中的非键属性派生。
基本上任何数据库都是特定时间点已知事实的记录。大多数数据库都包含一些时间组件,有些数据被保留,而有些数据则没有 - 要求应该规定这一点。
答案 4 :(得分:0)
你已经回答了自己的问题。
您做出的任何选择都取决于应用程序的要求。
有时速度胜利,有时空间胜利。有时数据准确性获胜,有时快照获胜。
虽然你可能没有能力说出什么是重要的,但你解决问题的人应该能够为你回答这个问题。
答案 5 :(得分:0)
我喜欢动态编程(不计算任何东西)。如果您没有空间限制并且对于有点过时的数据很好,那么将其预先计算并存储在数据库中。这将为您提供额外的好处,使您能够运行完整性检查并确保数据始终保持一致。
但正如其他人已经回复,这取决于:)