3

假设我有一个大表来存储整数范围。我可以用两个字段做到这一点:

start|end
  10 |210     (represents 10 to 210)
  5  |55      (represents 5 to 55)

(快速按end列选择),或:

start|length
  10 | 200     (represents 10 to 210)
  5  | 50      (represents 5 to 55)

(快速按length列选择)。

如果有时我需要选择 by end,有时需要选择 by length,并且两个查询都需要快速,该怎么办?我可以同时存储:

start|length|end
  10 | 200  |210
  5  | 50   |55

但是这并没有标准化,每个人都必须记住更新这两个字段,这只是糟糕的设计。

我知道我可以选择 by start + lengthorend - start但是对于一个非常大的表,这不是非常慢吗?

如何在不存储冗余数据的情况下通过计算值快速查询 - 或者我应该只存储额外的列?

4

3 回答 3

2

根据您使用的数据库类型,您可能希望使用触发器来计算派生字段。这样,他们永远不会失去同步。

这意味着每次开始或结束更改时都可以重新计算字段(长度)。

于 2012-10-08T02:11:01.433 回答
1

不幸的是,您的目标数据库都不支持计算列。我会做以下事情:

  1. 首先,确定你是否真的有性能问题。确实,它的WHERE end - start = ?执行速度会比 慢WHERE length = ?,但是您没有定义应用程序中的“真正大的表”是什么,也没有定义所需的性能是什么。无需优化可能不存在的问题。
  2. 确定您是否可以支持搜索中的任何延迟。如果是这样,您可以将计算的列添加到表中,但专门指定一个单独的任务,每五分钟、每小时或其他运行一次,以填充值。
  3. 在 PostgreSQL 中,您可以考虑物化视图,我相信它在引擎级别得到支持。(见下文 Catcall 的评论)。
  4. 最后,如果所有其他方法都失败,请考虑使用触发器来维护计算列。
于 2012-10-08T11:32:52.567 回答
1

我会存储长度,但我会确保计算是在我的插入和更新存储过程中完成的,这样只要每个人都使用你的存储过程,他们就不会产生更多的开销。

于 2012-10-08T02:11:26.960 回答