【问题标题】:Date ranges in views - is this normal?视图中的日期范围 - 这正常吗?
【发布时间】:2010-09-30 01:47:23
【问题描述】:

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

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

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

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

【问题讨论】:

  • 这里的“浏览量”是什么意思?在我的网络开发中。背景它们表示 HTML 文件,而代码本身保存在模型和控制器中。
  • 我的意思是 SQL 意义上的“视图”。这就是我使用 SQL 标记的原因。

标签: sql views enterprise


【解决方案1】:

我理解正确吗?

有这样一个视图:

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 ?;

【讨论】:

  • 对您的第一个问题是肯定的,尽管实际上有数十个甚至数百个这些视图都依赖于 tmp_parm_rang。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

        另外,你写道:

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

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

        【讨论】:

          【解决方案6】:

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

          似乎这些人不知道共享状态的概念,或者我们不知道共享状态的原因。

          【讨论】:

          • 我还没有发现他们是如何分配主键的,但是数据库中没有我预期的序列。
          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-07-18
                • 1970-01-01
                • 2014-01-07
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-01
                • 1970-01-01
                相关资源
                最近更新 更多