2009-01-07 48 views
1

我最近开始在一家拥有巨大“企业级”应用程序的公司工作。在我上一份工作中,我设计了数据库,但在这里我们有一个我不属于的整个数据库架构部门。视图中的日期范围 - 这是正常的吗?

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

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

更新我应该提到他们使用事务和每客户端锁,因此它可以防范大多数并发问题。此外,如果不是数百个视图,则几乎都有数十个取决于TMP_PARM_RANG的视图。

+0

这是什么意思的'意见'在这里?在我的网页开发中。背景是指代码本身保存在模型和控制器中的HTML文件。 – 2009-01-07 16:27:27

+0

我的意思是在SQL意义上的“意见”。这就是我使用SQL标签的原因。 – 2009-01-07 16:31:07

回答

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. 删除所有现有的行
  3. 插入一个新行到 TMP_PARM_RANG与用户的值
  4. 选择所有来自第e查看

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

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

实现相同的目标将是执行这个查询,用户的输入绑定到查询参数的简单和更正常的方式:

SELECT * FROM some_table WHERE some_table.date_column BETWEEN ? AND ?; 
1

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

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

我可以看到的唯一理由是,如果存在一个多步骤的过程,那么这个过程一次只能执行一次,而多个操作需要多个存储过程。

0

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

似乎共享状态的概念没有涵盖这些人,或共享状态的原因没有我们。

+0

我还没有发现它们是如何分配主键的,但是数据库中没有像我预期的那样的序列。 – 2009-01-07 16:28:13

0

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

对我来说听起来像某人只是不知道如何编写他们的WHERE子句。

2

此表必须有一些商业原因。我看到硬编码的日期实际上是分区视图,他们使用日期作为分区字段。我还看到,像处理夏令时一样的桌子,想象一个返回在DST期间发生的所有活动的视图。而且这些东西都不会删除并插入到表格中......这只是奇怪的

因此,无论是需要挖掘出来的更深层的原因,还是当时看起来像是好主意,但为什么这样做已经失去了作为部落的知识。

3

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

0

的意见可能被用作临时表。在SQL Server中,我们可以使用表变量或临时表(#/ ##)来达到此目的。尽管专家不建议创建视图,但我为SSRS项目创建了很多视图,因为我正在处理的表格不互相引用(认真对待NO FK的表格)。我必须解决数据库设计中的解决方法缺陷;这就是为什么我使用很多观点。

1

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

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

而且,你写到:

我应该指出,他们使用 交易和每客户端锁,因此 它防范的最大并发 问题。

虽然这可能会防止由于并发造成的数据一致性问题,但它在由于并发性而导致的性能问题时会受到伤害。

0

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