1

我最近开始在一家拥有庞大“企业”应用程序的公司工作。在我的上一份工作中,我设计了数据库,但在这里我们有一个我不属于的整个数据库架构部门。

他们的数据库中的一个奇怪的事情是他们有一堆视图,而不是让用户提供他们想要查看的日期范围,而是加入一个(全局临时)表“TMP_PARM_RANG”以及一个开始和结束日期。每次主应用程序开始处理请求时,它做的第一件事就是“ DELETE FROM TMP_PARM_RANG;” 然后插入其中。

这似乎是一种奇怪的做事方式,而且不是很安全,但这里的其他人似乎都可以接受。这是正常的,还是我的不安有道理?

更新 我应该提到他们使用事务和每个客户端的锁,所以它可以防止大多数并发问题。此外,实际上有数十个甚至数百个视图都依赖于TMP_PARM_RANG.

4

9 回答 9

3

如果数据库是oracle,可能是全局临时表;每个会话都会看到自己的表版本,插入/删除不会影响其他用户。

于 2009-01-07T16:28:18.527 回答
3

我理解正确吗?

有这样的观点:

SELECT * FROM some_table, tmp_parm_rang
  WHERE some_table.date_column BETWEEN tmp_parm_rang.start_date AND tmp_parm_rang.end_date;

然后在某些前端,用户输入日期范围,应用程序执行以下操作:

  1. 从 TMP_PARM_RANG 中删除所有现有行
  2. 使用用户值将新行插入 TMP_PARM_RANG
  3. 从视图中选择所有行

我想知道对 TMP_PARM_RANG 的更改是提交还是回滚,如果是,什么时候?它是临时表还是普通表?基本上,根据这些问题的答案,多个用户并行执行该过程可能并不安全。人们希望如果是这种情况,他们早就发现并解决了这个问题,但谁知道呢?

即使它以线程安全的方式完成,对数据库进行更改以进行简单的查询操作也没有多大意义。这些 DELETE 和 INSERT 正在生成完全没有必要的重做/撤消(或非 Oracle 数据库中的任何等效项)。

实现相同目标的一种简单且更正常的方法是执行此查询,将用户的输入绑定到查询参数:

SELECT * FROM some_table WHERE some_table.date_column BETWEEN ? AND ?;
于 2009-01-07T16:32:26.597 回答
2

这张表一定有一些商业原因。我已经看到了日期硬编码的视图,它们实际上是一个分区视图,并且他们使用日期作为分区字段。我还看到加入表格,例如在处理夏令时时想象一个返回 DST 期间发生的所有活动的视图。而且这些东西都不会删除并插入表中……这很奇怪

因此,要么有更深层次的原因需要挖掘,要么只是当时似乎是一个好主意,但为什么这样做已经作为部落知识丢失了。

于 2009-01-07T16:27:30.040 回答
1

就个人而言,我猜这将是一个非常奇怪的事件。从你所说的两个方法同时调用该过程可能会非常有趣。

通常,日期范围作为视图上的过滤器完成,而不是由存储在其他表中的外部值驱动。

我能看到的唯一理由是,如果有一个多步骤过程,一次只执行一次,并且跨多个存储过程的多个操作需要日期。

于 2009-01-07T16:23:31.577 回答
1

我想这会让他们支持多个范围。例如,他们可以返回 2008 年 1 月 1 日和 2009 年 1 月 1 日以及 2006 年 1 月 1 日和 2007 年 1 月 1 日之间的所有日期,以将 2006 年的数据与 2008 年的数据进行比较。你不能用一对绑定参数来做到这一点。另外,我不知道 Oracle 是如何对视图进行查询计划缓存的,但也许与此有关?随着日期列作为视图的一部分被检查,服务器可以缓存一个始终假定日期将被检查的计划。

只是在这里抛出一些猜测:)

另外,你写道:

我应该提到他们使用事务和每个客户端的锁,所以它可以防止大多数并发问题。

虽然这可以防止由于并发导致的数据一致性问题,但当涉及到由于并发导致的性能问题时,它会受到伤害。

于 2009-01-07T16:58:11.960 回答
0

他们是否还在应用程序中添加一个来为主键生成下一个唯一值?

似乎共享状态的概念无法理解这些人,或者共享状态的原因也无法理解。

于 2009-01-07T16:26:49.277 回答
0

对我来说,这听起来像是一个非常奇怪的算法。我想知道它如何处理并发 - 它是否包含在事务中?

在我看来,有人只是不确定如何编写他们的 WHERE 子句。

于 2009-01-07T16:27:25.953 回答
0

这些视图可能用作临时表。在 SQL Server 中,我们可以为此目的使用表变量或临时表 (# / ##)。尽管专家不建议创建视图,但我已经为我的 SSRS 项目创建了很多视图,因为我正在处理的表不相互引用(没有 FK,说真的!)。我必须解决数据库设计中的缺陷;这就是为什么我经常使用视图。

于 2009-01-07T16:56:14.053 回答
0

在这里使用您评论的全局临时表 GTT 方法,该方法对于多用户系统肯定是安全的,所以那里没有问题。如果这是 Oracle,那么我想检查系统是否正在使用适当级别的动态采样以便适当地加入 GTT,或者调用 DBMS_STATS 以提供有关 GTT 的统计信息。

于 2009-01-07T18:12:43.730 回答