SQL Server中的“WITH SCHEMABINDING”的缺点是什么?

时间:2009-11-02 03:37:20

标签: sql sql-server query-optimization schemabinding

我有一个包含数百个笨拙命名的表格的数据库(CG001T,GH066L等),我对每个人都有“友好”名称的观点(“CUSTOMERS”视图是“SELECT * FROM GG120T”,例如)。我想在我的视图中添加“WITH SCHEMABINDING”,以便我可以获得与之相关的一些优势,例如能够索引视图,因为少数视图计算了动态计算成本高昂的列。 / p>

SCHEMABINDING这些观点是否存在缺点?我发现一些文章隐约暗示了缺点,但从未详细讨论过。我知道一旦视图是模式绑定的,你就不能在没有先删除视图的情况下改变任何会影响视图的东西(例如,列数据类型或整理),所以这是一个,但除此之外?似乎索引视图本身的能力远远超过了更仔细地规划模式修改的缺点。

10 个答案:

答案 0 :(得分:44)

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

答案 1 :(得分:31)

哦,使用SCHEMABINDING有明确的DOWNSIDES - 这些来自SCHEMABINDING,特别是当与COMPUTED列结合“LOCKS”THE RELATIONSHIPS 并使得一些“琐碎”改变“几乎不可能。”

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

    1. 无法删除或更改UDF,因为它是SCHEMABOUND。
    2. 无法删除COLUMN,因为它在INDEX中使用。
    3. COLUMN无法更改,因为它是COMPUTED。
    4. 好吧,好吧。真..!?!我的日子刚刚变成了PITA。 (现在,像ApexSQL Diff这样的工具可以在提供修改后的模式时处理这个,但问题是我甚至无法修改模式开始!)

      我不反对SCHEMABINDING,介意(在这种情况下它需要UDF),但我反对那里没有办法(我可以找到)“临时禁用”SCHEMABINDING < / em>的

答案 2 :(得分:27)

完全没有。它更安全。我们到处都用它。

答案 3 :(得分:4)

如果这些表来自第三方应用程序(它们因尝试隐藏其表而臭名昭着),如果它试图更改任何这些表,则会导致升级失败。

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

答案 4 :(得分:4)

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

我知道这是因为我试图对一个视图进行架构并遇到一条错误消息,告诉我它不能是模式绑定的,因为它引用的其他视图之一也不是模式绑定。

这样做的唯一结果是,如果您突然想要更新模式绑定视图以引用某个新视图或现有视图,则可能还需要对该新视图或现有视图进行架构绑定。在这种情况下,您将无法更新视图,并且您希望数据库开发人员知道如何使用模式绑定视图。

答案 5 :(得分:2)

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

  

无法对视图'view'进行架构绑定,因为名称'table'无效   架构绑定。名称必须是两部分格式,而对象不能   引用自己。

同样要“关闭”架构绑定,您需要更改视图,这需要您重新定义视图的select语句。我认为你唯一没有重新定义的是任何补助金。这让我失望了,因为覆盖视图似乎是一种固有的不安全操作。

有点像添加非空约束的方式会强制你覆盖列的数据类型 - 讨厌!

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

就我个人而言,我认为这并不能真正代表一种解决方案,而且拥有一个体面的流程会更好,因为任何数据库更改都会自动应用,因此更改数据库并不是一件噩梦。这样,当您将更改应用于表时,您可以从头开始删除所有视图+函数并从头开始重新创建它们(无论如何都会在创建时检查它们)。

答案 6 :(得分:1)

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

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是相关的。

答案 7 :(得分:1)

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

答案 8 :(得分:1)

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

答案 9 :(得分:0)

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