【问题标题】:Generate a primary key on index view using T SQL使用 T SQL 在索引视图上生成主键
【发布时间】:2011-11-01 16:03:46
【问题描述】:

我尝试创建一个索引视图,并在视图上创建唯一聚集索引。我的问题是如何在 select 子句中生成主键。例如

Create view ssrs.vMyView
with schemabinding
as
  select firstname, lastname, other columns  --example columns
  from mytable

如何动态为每一行生成一个主键?

更新

问题是它没有唯一的列或列组合,所以我需要动态生成一个唯一的 id。 名字和姓氏只是示例。基表有主键。

提前致谢!

【问题讨论】:

  • 乒乓球,名字和姓氏是主键吗?哎哟!只需扫描电话簿,这不是一个非常独特的主键。最重要的是,当有人结婚或离婚并想改名时,这会引起很多悲伤。

标签: sql-server


【解决方案1】:

一旦你创建了这个视图,如果你遵守all the rules and requirements for an indexed view,你应该可以像这样创建聚集索引:

CREATE CLUSTERED INDEX cix_vMyView ON dbo.vMyView(....)

您需要选择一个好的、有效的集群密钥——最好根据 NUSE 原则:

  • 独一无二的
  • 静态
  • 不断增加

INT IDENTITY 将是完美的 - 或者类似于 BIGINT 或 INT 和 DATETIME 的组合。

更新:看到您的基表甚至没有主键(这是一个更大的问题您需要尽快修复!如果它没有主键,就不是表),您可以在视图定义中使用 ROW_NUMBER() 之类的东西:

CREATE VIEW ssrs.vMyView
WITH SCHEMABINDING
AS
  SELECT firstname, lastname,
     ROW_NUMBER() OVER(ORDER BY Lastname, FirstName) AS 'ID'
  FROM dbo.mytable

为您提供一个“人造的”独特的、不断增加的主键。

(2014 年 4 月 25 日更新:不幸的是,与我在发布此内容时的看法相反,这行不通,因为您无法在以下视图上创建聚集索引包含一个排名函数,如ROW_NUMBER .....)。感谢@jspaey 指出这一点。所以这使得在基表上拥有一个主键并将其包含在您的视图定义中变得更加重要!)

但同样:如果您的基表没有主键 - 请先修复它!

更新 #2: 好的,所以您的基表确实毕竟有一个主键 - 那为什么不是您的视图定义的一部分?我会始终在我的视图中包含所有基表中的所有主键 - 只有那些 PK 才能让您清楚地识别基表中的行,并且它们允许您使视图可更新。

【讨论】:

  • @Pingpong:添加一些独特的东西!我确定你的基表有某种主键,不是吗??
  • @Pingpong - 您可以(可能)将group by firstname, lastname 添加到查询中,并将COUNT_BIG(*) 添加到select 列表中以摆脱欺骗,然后索引vMyView(firstname,lastname)。不过最好修复你的基表。
  • @Pingpong - 好吧,如果您的基表确实有一个主键(与您上面所说的相反)然后将其包含在您的视图定义中。
  • 您不能在使用 ROW_NUMBER() 或任何其他窗口排名或聚合函数的视图上创建索引。
  • @jspaey: 废话 - 你是对的 :-( 太糟糕了.....好吧,所以这使得在基表中包含一些独特的东西更加很重要如果您想将它们编入索引,请在您的视图中!
【解决方案2】:

Pingpong,Marc 说得对,您需要一些独特的东西来添加主键。请记住,这不必是单个列,因此如果您有两个唯一的列一起使用,那将非常有效。

如果没有独特的列组合,您可能希望重新考虑您的视图,甚至添加列,以便有一些独特的东西。

作为相关说明,请记住企业版将自动利用索引视图。但在企业版之外,您可能需要通过 noexpand 提示明确告诉优化器使用索引。我之前在On Indexes and Views写过这个

【讨论】:

  • 名字和姓氏只是示例。基表有主键。
  • 在哪个星球上,'Firstname + Lastname' 是主键?我想这将是一个两个人不能同名的星球,否则他们会被某种外星激光炸毁。 Firstname + Lastname 很少会成为主键! (PS。我知道蒂莫西的回答指出,选择独特的东西是“关键”,这不是他说的)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2014-10-16
  • 1970-01-01
  • 2018-12-01
相关资源
最近更新 更多