2009-11-02 29 views
52

我在它(CG001T,GH066L等)有数百笨拙命名表的数据库,我对每一个与它的“友好”名称(视图“顾客”的意见是“SELECT * FROM GG120T”,为例)。我想在视图中添加“WITH SCHEMABINDING”,这样我就可以拥有一些与它相关的优点,比如能够为视图编制索引,因为少数几个视图计算出了即时计算昂贵的列。在SQL Server中有“WITH SCHEMABINDING”的缺点?

SCHEMABINDING这些视图有缺点吗?我发现了一些隐约暗示缺点的文章,但从来没有详细讨论过。我知道,一旦视图是模式绑定的,在不首先放弃视图的情况下,不能改变会影响视图的任何内容(例如,列数据类型或排序规则),所以这只是一个,但除此之外呢?似乎索引视图本身的能力远远超过了更小心地规划架构修改的缺点。

+3

您不必删除视图,但是您必须在删除了模式绑定的情况下更改视图。 – JeffO 2009-11-03 03:28:05

回答

24

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

+4

如果没有缺点,而且更安全(这是我最初的印象),那么人们为什么不使用它?看起来保护你的视图免受意外破坏是一个优先事项,或者它应该是相反的方式 - WITH是默认设置,如果你想要这种行为,你必须声明你的视图。 – SqlRyan 2009-11-02 14:07:15

+1

懒惰,太多纪律(例如合格的专栏等) – gbn 2009-11-02 14:11:25

+1

有没有办法让这是默认选项,还是总是需要有意识地完成的事情? – SqlRyan 2009-11-02 14:19:45

39

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

+3

这是我看来的一个大问题,特别是如果您想修改数据库结构而不使用原始DDL语句便利。在这些情况下,您必须尝试使用​​SCHEMABINDING为视图/函数生成完整的DDL语句,放下它们然后重新创建它们。做一个大任务只需要改变一个列的大小。 – jpierson 2010-08-19 15:48:38

+16

您不需要删除视图本身,只需对其进行修改,使其不受架构限制,并在修改后进行修改。 – Paul 2011-11-28 12:02:38

4

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

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

+1

我想这是事实,并且比在DDL期间放弃视图的侵入性要小得多。我最近不得不在一些列上更改排序规则,只是在执行ALTER/Change排序规则/ ALTER时比放下视图和中断应用程序要容易得多。 – SqlRyan 2009-11-03 16:30:55

+1

不幸的是,简单地通过ALTER语句删除SCHEMABINDING不适用于索引视图,因此在这些情况下,我相信唯一的解决方案仍然是删除并重新创建视图。 – jpierson 2010-08-19 15:51:35

+0

我刚刚在索引视图上测试了ALTER VIEW,看看会发生什么。我期待着看到某种类型的错误(一种好的方式是典型的SQL Server),但它只是删除了我的索引。所以要小心在视图上使用ALTER来改变它是否是模式绑定或不知道它是否有索引。 – jpierson 2010-08-19 16:01:14

4

一个缺点是,如果您对一个视图进行schemabind绑定,那么它只能引用其他的绑定了视图的视图。

我知道这是因为我试图schemabind视图,并会见了一个错误信息,告诉我它无法架构绑定,因为它引用其他视图一个是不是也架构绑定。

这样做的唯一的后果是,如果你突然要更新架构绑定视图引用一些新的或现有的视图,你可能需要schemabind新的或现有的视图中。在这种情况下,您将无法更新视图,并且您最好希望数据库开发人员知道如何使用架构绑定视图。

28

哦,还有DEFINITELY缺点使用SCHEMABINDING - 这些来自事实SCHEMABINDING,尤其是当与计算列再加“锁定”关系,使几乎不可能该死的一些“琐碎的变化”。

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

祝你好运的!

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

那么,frak。真..!?!我的一天刚成为PITA。 (现在,像ApexSQL DIFF工具时,用修改过的模式提供可以处理这个,但问题是在这里,我甚至不能修改,开始与该模式!)

我不反对SCHEMABINDING,头脑(在这种情况下它需要一个UDF),但是我反对那里没有办法(我可以找到)“暂时禁用”SCHEMABINDING

+1

你的意思是你可以创建一些循环的SCHEMABOUND引用?有没有什么办法摆脱这种情况,而不是在没有SCHEMABINDING OPTION的情况下删除/重新创建数据库? (在你的情况下删除索引可以解除阻止吗?) – Guillaume86 2014-10-23 13:27:43

+0

“1. UDF不能被删除或更改,因为它是SCHEMABOUND。”不,这与模式绑定所做的相反。 “3. COLUMN不能改变,因为它是COMPUTED。”咦?你什么意思? – MarredCheese 2018-02-09 20:30:55

2

另一个缺点是,你需要使用的模式限定名的一切:你会得到错误信息的负载是这样的:

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

另外,为了“关闭”模式绑定,你需要改变视图,这需要你重新定义视图的select语句。我认为唯一不需要重新定义的是任何补助。由于覆盖视图看起来像是一种固有的不安全操作,这使我感到很失望。

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

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

就我个人而言,我认为这并不代表一个解决方案,它更好地拥有一个体面的过程,因此任何数据库更改都会自动应用,因此更改数据库并不是一场噩梦。通过这种方式,您可以将所有视图+函数从头开始删除并重新创建(无论如何都会对创建进行检查),作为将更改应用到表的过程的一部分。

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. 

我还挺需要我的左连接。 This SO question是相关的。

1

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

0

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

0

如果您的工具(ssms等)不能很好地处理基础对象上的模式更改失败,那么您可能会导致一些真正的混乱。这就是我现在正在坐的,而且我确实意识到这是一个附带案例

相关问题