2

当我正在考虑为我的数据库设计新的表时。我在将最终计算存储在表格列中,或者在我计划创建的视图中计算它们之间左右为难。例如,如果您要将值 10 存储在一列中,而将 5 存储在另一列中,并且您想在另一列中获得 (10/5),那么您认为将 5 存储在自己的列中更好,还是计算它在计划的视图中?

该表每天将包含大约 400k 条记录,可能持续一年左右。即使我可以使用简单的数据类型来降低存储成本,我仍然必须为每条记录维护另外 4 个字节的数据 * 在同一行中我可能有多少计算记录。

我将在几天的数据中查询计算值。我仍然想要速度,但也想要更小的数据库、更容易维护的表以及视图的灵活性。

你有什么看法和想法?

4

3 回答 3

1

我将查询计算值...

我有什么办法?

  • 如果 SELECT 列表中刚刚提到了计算值,则不要存储它。1
  • 如果它在 WHERE 中,您会想要对其进行索引,在这种情况下,大多数 DBMS 会迫使您以一种或另一种方式持久化它。2

1对于 CPU 的小幅增加,您将减少存储需求,从而提高缓存效率,从而减少 I/O,这往往是大多数 OLTP 工作负载中最重要的性能瓶颈。当计算成本很高时,缓存结果是合理的,但简单的除法距离该阈值很远。

2在表中作为普通字段,或作为持久计算列或在物化/索引视图中。

于 2013-02-05T03:32:57.613 回答
1

数据完整性是最重要的。

在视图中计算结果可以保证为您提供最新的答案。权衡是 SELECT 语句的运行时性能,尤其是在 WHERE 子句中使用结果时。根据我的经验,计算结果很少用于 WHERE 子句。计算,我的意思不仅是算术,还包括字符串和子字符串的提取和连接、校验和计算等。

将计算结果存储在基表中可为您提供最佳 SELECT 性能。权衡是数据完整性。如果您可以编写保证结果始终正确的 CHECK() 约束,那么您应该这样做。但是,如果不使用用户定义的函数,有时无法表达复杂计算的 CHECK() 约束,而且并非所有平台都支持 CHECK() 约束中的用户定义函数。

如果您不能编写 CHECK() 约束,您仍然需要某种程序来定期检查您的数据是否有错误。在最坏的情况下,您可以在需求量低时每天或每周运行报告。

物化视图可能会为您提供两全其美的优势 - 可以作为 sargable WHERE 子句目标的计算,并且始终保证是正确的。(SQL Server 等价物称为索引视图。)权衡是存储空间和 CPU 周期,以使物化视图及其索引在基表更新后保持最新。

通常,我会先尝试一个视图。但在您的特定情况下——每天 40 万行,持续 365 天——我想我会先尝试物化视图。无论出于何种原因,它都无法正常工作,您可以将其替换为基表中的列,删除物化视图,然后创建一个具有相同名称的新视图。(逻辑数据独立性摇滚。)

于 2013-02-05T15:23:42.663 回答
0

如果您有一个开发环境,我建议您测试这两种方法并选择一种能够提供最佳性能/维护成本的方法。即使表存储了大约 400k 记录,这取决于您访问该数据的方式,一种方法可能更有意义。

于 2013-02-05T03:06:44.700 回答