我有一个表称为countries
和我定义了country_name
列是SQL Server 2008 R2上创建一个类型为“唯一密钥”的“索引/键”独特的。
但是,我有以下问题:
- 将创建一个类型的“索引/键”“唯一键”自动创建该列的一个非聚集索引?
- 如果我从“唯一密钥”到“指数”更改类型和我保持
IsUnique
值是“是”,然后,,会不会有什么不同吗? - 那么,为什么有两种选择“唯一键”和“索引”我认为这两者是一样的吗?
我有一个表称为countries
和我定义了country_name
列是SQL Server 2008 R2上创建一个类型为“唯一密钥”的“索引/键”独特的。
但是,我有以下问题:
IsUnique
值是“是”,然后,,会不会有什么不同吗? 唯一的约束就是场面唯一索引后面实现的,所以它并没有真正不管你如何指定。 我倾向于实现它简称为:
ALTER TABLE dbo.foo ADD CONSTRAINT UQ_bar UNIQUE(bar);
有些人创建唯一索引来代替,如
CREATE UNIQUE INDEX IX_UQ_Bar ON dbo.foo(bar);
所不同的是在意向 - 如果你创建的约束强制唯一性/业务规则,为您营造一个约束,如果你这样做是为了帮助查询性能,它可能是更符合逻辑创建唯一索引。 同样,在幕后是相同的实现,但是你才能让路上有可能帮助记录您的意图。
我认为可以有多种选择,坚持既不同于以前Sybase功能以及坚持ANSI标准(即使唯一约束不符合标准的100%,因为他们只允许一个NULL值 - 一个独特的指数,上另一方面,可以通过添加解决此WHERE
子句( WHERE col IS NOT NULL
SQL Server 2008和更高版本)上)。
提一个额外的事情是,如果你创建索引时,可以指定包含的列,这可以帮助你的SQL代码,以更快的工作,如果有一些搜索通过COUNTRY_NAME。
CREATE UNIQUE NONCLUSTERED INDEX IX_UQ_Bar
ON dbo.foo (
bar
)
INCLUDE (foo_other_column)
GO
SELECT foo_other_column FROM Foo WHERE bar = 'test'
SQL服务器将存储“foo_other_column”,在指数本身。 在唯一约束,会先找到“测试”的指数的话,那么将搜索行FOO表,只有那里将采取“foo_other_column”。
有唯一索引或唯一约束,也没有任何性能上的差异没有什么区别。 但也有创造一定的差异,其中一些索引创建选项不可用唯一约束。
如果您正在使用SqlMetal.exe输出DBML或LinqToSql实体:
原因是在SqlMetal执行。 它查询数据库信息模式,特别是键列使用。 唯一键表示有,但唯一索引都没有。
SELECT TABLE_NAME, CONSTRAINT_NAME, COLUMN_NAME, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE;
除上述优异的答案,我会在这里添加我的2美分。
唯一键是一个约束,它使用强制自己唯一索引。 正如主键通常是由一个聚集唯一索引强制执行。 按理来说,约束和索引是两回事。 但在RDBMS,一个约束可以通过物理的索引来实现。
如果一个表在SQL Server上的唯一约束创建的,你也可以看到一个约束对象和唯一索引
create table dbo.t (id int constraint my_unique_constraint unique (id));
select [Constraint]=name from sys.key_constraints
where parent_object_id = object_id('dbo.t');
select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t')
and index_id > 0;
我们将得到以下(约束和索引)
然而,如果我们不建立一个约束,而只是一个唯一索引,如下
create table dbo.t2 (id int );
create unique index my_unique_constraint on dbo.t2 (id);
select [Constraint]=name from sys.key_constraints
where parent_object_id = object_id('dbo.t2');
select name, index_id, type_desc from sys.indexes
where object_id = object_id('dbo.t2')
and index_id > 0
你会看到有创建(仅创建索引)没有限制对象。
从“理论”的角度来看,在SQL Server中,约束与OBJECT_ID值的对象,是架构绑定,而指数是不是一个对象,没有价值的object_id,没有相关的架构。
第3选项强制唯一使用过滤独特的指数 ,以允许可空唯一索引。
这将不具有唯一约束工作。
例如,假设你有一个列,你只希望允许唯一值,
但还是要支持多个NULL
当他们不存在价值。
只有经过滤光独特的指数将工作:
CREATE UNIQUE NONCLUSTERED INDEX [UF_Employee_UserID] ON [dbo].[Employee]
(
[UserID] ASC--Not all Employees have a UserID to log into the System.
)
WHERE ([UserID] IS NOT NULL)--Enforce Uniqueness when not null.
现在,你仍然无法在使用GUI编辑表创建一个过滤指数在SSMS。
但是,您可以关闭所有打开的表的设计师,然后打开了指数本身的属性在对象资源管理器,如果你想要去通过GUI而不是手工创建索引(如上)。
其中最重要的一点是假设你想保留列null值与保持独特性,你不能用唯一键约束但唯一键索引做ü可以继续列null值与保持唯一性。 所以如果你需要列中唯一有可能为空的类型唯一索引所需否则,如果你需要所需的列不为空的则唯一键约束。