64

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

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

4

10 回答 10

49

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

于 2009-11-02T14:18:18.133 回答
34

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

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

祝一切顺利!

  1. 不能删除或更改 UDF,因为它是 SCHEMABOUND。
  2. 不能删除 COLUMN,因为它在 INDEX 中使用。
  3. COLUMN 无法更改,因为它已被计算。

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

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

于 2013-07-02T01:41:24.237 回答
33

一个都没有。它更安全。我们到处使用它。

于 2009-11-02T09:30:18.137 回答
6

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

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

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

于 2013-03-06T03:50:42.643 回答
4

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

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

于 2009-11-03T03:32:04.843 回答
2

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

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

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

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

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

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

于 2014-04-09T09:13:29.527 回答
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.

我有点需要我的左连接。 这个 SO question是相关的。

于 2015-03-04T15:24:38.433 回答
1

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

于 2016-02-17T12:01:22.293 回答
1

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

于 2016-02-19T16:43:27.830 回答
0

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

于 2016-11-10T08:08:39.993 回答