【问题标题】:Downsides to "WITH SCHEMABINDING" in SQL Server?SQL Server 中“WITH SCHEMABINDING”的缺点?
【发布时间】:2010-12-12 04:09:00
【问题描述】:

我有一个数据库,其中包含数百个名称笨拙的表(CG001T、GH066L 等),并且我对每个都有其“友好”名称的视图(视图“CUSTOMERS”是“SELECT * FROM GG120T”,例如)。我想在我的视图中添加“WITH SCHEMABINDING”,这样我就可以拥有一些与之相关的优势,比如能够索引视图,因为少数视图的计算列在运行时计算成本很高。

SCHEMABINDING 这些观点有什么缺点吗?我发现一些文章含糊地提到了缺点,但从不详细介绍。我知道一旦视图是模式绑定的,如果不首先删除视图,您就无法更改任何会影响视图的内容(例如,列数据类型或排序规则),所以这是一个,但除此之外?似乎对视图本身进行索引的能力将远远超过更仔细地规划架构修改的缺点。

【问题讨论】:

  • 您不必删除视图,但您必须在移除架构绑定的情况下更改视图。

标签: sql sql-server query-optimization schemabinding


【解决方案1】:

除非您先删除视图,否则您将无法更改/删除表格。

【讨论】:

  • 在我看来这是一个大问题,特别是如果您想修改数据库结构而不方便使用原始 DDL 语句。在这些情况下,您必须尝试使用​​ SCHEMABINDING 为视图/函数生成完整的 DDL 语句,删除它们然后重新创建它们。仅更改列的大小就需要完成一项艰巨的任务。
  • 您不需要删除视图本身,只需 ALTER 使其不受模式绑定,然后再将其 ALTER。
【解决方案2】:

哦,使用 SCHEMABINDING 有肯定的缺点 - 这些实际上来自 SCHEMABINDING,尤其是当与计算列 “锁定”关系 并使得一些“微不足道”时改变”几乎是不可能的。

  1. 创建一个表。
  2. 创建一个 SCHEMABOUND UDF。
  3. 创建一个引用 UDF 的 COMPUTED PERSISTED 列。
  4. 在所述列上添加一个 INDEX。
  5. 尝试更新 UDF。

祝你好运!

  1. 无法删除或更改 UDF,因为它是 SCHEMABOUND。
  2. 无法删除 COLUMN,因为它在 INDEX 中使用。
  3. 无法更改 COLUMN,因为它是 COMPUTED 的。

好吧,老兄。真的..!?!我的一天刚刚变成了 PITA。 (现在,像 ApexSQL Diff 这样的工具可以在提供修改后的架构时处理此问题,但问题出在我什至无法从一开始就修改架构!)

我不反对 SCHEMABINDING,请注意(在这种情况下,UDF 需要它),但我反对没有办法(我能找到)“暂时禁用”SCHEMABINDING。

【讨论】:

  • 你的意思是你可以创建一些循环的 SCHEMABOUND 引用?除了在没有 SCHEMABINDING OPTION 的情况下删除/重新创建数据库之外,还有什么方法可以摆脱这种情况? (在你的情况下删除索引可以解除阻止吗?)
  • "1. 不能删除或更改 UDF,因为它是 SCHEMABOUND。"不,这与模式绑定的作用相反。 “3. COLUMN 无法更改,因为它是 COMPUTED 的。”嗯?什么意思?
  • "1. 不能删除或更改 UDF,因为它是 SCHEMABOUND。"这与 SCHEMABINDING 无关,而是您在计算列中使用 UDF。 “3. COLUMN 无法更改,因为它是 COMPUTED 的。”嗯,是吗?这与 SCHEMABINDING 无关,但与 (MS)SQL 的工作方式有关。
  • 这个答案说,如果我创建一长串模式对象,每个模式对象都依赖于前一个对象,我可能不得不暂时更改或删除(而不是仅仅禁用)其中一些反向添加它们的顺序,以便我可以在塔的底部进行架构更改。当然,这与 OP “更仔细地规划 [one's] 模式修改” 的意思是一样的。但是 UDF 的例子还是很有启发性的。
【解决方案3】:

根本没有。它更安全。我们到处都在使用它。

【讨论】:

  • 如果没有缺点,而且更安全(这是我最初的印象),那为什么人们不使用它呢?似乎保护您的视图免受意外破坏将是一个优先事项,或者应该反过来 - WITH 是默认设置,如果您想要这种行为,您必须声明您的视图 WITHOUT。
  • 懒惰,过多的纪律(例如合格的列等)
  • 有没有办法让它成为默认选项,或者它总是需要有意识地完成?
  • 我大约一个月前发生了这种情况 - 我更改了一个基础表,并且返回的视图完全被淘汰了结果。原来视图使用了 SELECT * FROM,我必须在它意识到底层架构发生变化之前刷新视图 :)
  • @Triynko:这有充分的理由。不允许对需要影响整个索引视图的基表进行任何更改。例如,SUM 很容易仅针对更改的行进行计算。另外,我不认为盲表重建是一个好主意:高级 SQL 和这种开发不能混合
【解决方案4】:

一个缺点是,如果您对一个视图进行架构绑定,它只能引用其他架构绑定视图。

我知道这一点是因为我尝试对视图进行架构绑定,但收到一条错误消息,告诉我它不能被架构绑定,因为它引用的其他视图之一也不是架构绑定的。

这样做的唯一后果是,如果您突然想要更新模式绑定视图以引用一些新的或现有的视图,您可能还必须对新的或现有的视图进行模式绑定。在这种情况下,您将无法更新视图,最好希望您的数据库开发人员知道如何使用模式绑定视图。

【讨论】:

    【解决方案5】:

    如果这些表来自第三方应用程序(它们因试图隐藏其表而臭名昭著),那么如果它试图更改这些表中的任何一个,就会导致升级失败。

    您只需在更新/升级之前更改没有架构绑定的视图,然后将它们放回原处。就像其他人提到的那样。只需要一些计划、纪律等。

    【讨论】:

    • 我想这是真的,而且比在 DDL 期间删除视图的侵入性要小得多。我最近不得不更改某些列的排序规则,而仅执行 ALTER/Change collat​​ion/ALTER 比在我工作时删除视图并破坏应用程序要容易得多。
    • 不幸的是,通过 ALTER 语句简单地删除 SCHEMABINDING 对索引视图不起作用,因此在这些情况下,我认为唯一的解决方案仍然是删除并重新创建视图。
    • 我刚刚测试了在我的索引视图上执行 ALTER VIEW 以查看会发生什么。我期待看到某种类型的错误(以一种很好的方式典型的 SQL Server),但它只是删除了我的索引。所以要小心在视图上使用 ALTER 只是为了改变它是否是模式绑定而不知道它是否首先有索引。
    • 如果你删除模式绑定(你必须使用alter来完全重建视图)你不能有一个索引,所以是的,如果你重新添加模式绑定,你将不得不重新创建索引。
    【解决方案6】:

    另一个缺点是您需要对所有内容使用架构限定名称:您将收到大量错误消息,如下所示:

    无法架构绑定视图“视图”,因为名称“表”对 模式绑定。名称必须采用两部分格式,并且对象不能 引用自身。

    同样要“关闭”模式绑定,您需要更改视图,这需要您重新定义视图的选择语句。我认为您唯一不必重新定义的是任何赠款。这让我很反感,因为覆盖视图似乎是一种天生不安全的操作。

    这有点像添加非空约束迫使您覆盖列的数据类型的方式 - 讨厌!

    您还必须重新定义依赖于您要更改的架构绑定对象的任何其他视图或过程...这意味着您可能必须重新定义(并可能破坏)大量级联函数和视图,以便向一列添加(例如)非空约束。

    我个人认为这并不代表真正的解决方案,最好有一个体面的流程,自动应用任何数据库更改,这样更改数据库就不是一场噩梦。这样一来,当您将更改应用到表时,您可以将所有视图 + 函数从头开始删除和重新创建(无论如何都会在创建时对其进行检查)。

    【讨论】:

      【解决方案7】:

      这对我来说似乎是个缺点(# 是我的):

      Cannot create index on view "###.dbo.###" because it uses a LEFT, RIGHT, or FULL OUTER join, and no OUTER joins are allowed in indexed views. Consider using an INNER join instead.
      

      我有点需要我的 LEFT 连接。 This SO question 是相关的。

      【讨论】:

        【解决方案8】:

        使用 tSQLt 单元测试框架时,您会遇到问题,并且在使用 FakeTable 方法时需要解决方法,这将不允许您伪造链接到具有模式绑定的视图的表。

        【讨论】:

          【解决方案9】:

          自 SQL Svr 2005 以来,所提到的负面影响几乎没有超过这种最佳实践。它避免了可怕的表假脱机。对我来说,一个主要的负面因素是模式绑定的 sprocs、funcs、views 不能包含诸如 master db 之类的“外部”数据库,因此您可以将所有出色的实时系统内容扔进垃圾箱,除非,例如,您的生产核心数据库位于 master 内部。对我来说,没有 sys 的东西我无法应对生活。当然,并非所有处理都需要无假脱机性能,并且可以在更高的数据类层中同时组合快速和慢速结果。

          【讨论】:

            【解决方案10】:

            如果您的工具(ssms 等)不能很好/优雅地处理基础对象上的架构更改失败,您可能会给自己造成一些真正的混乱。这就是我现在所坐的,我确实意识到这是一个边缘案例

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-06-10
              • 1970-01-01
              • 2010-09-06
              • 2014-03-01
              • 1970-01-01
              • 2020-04-28
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多