joh*_* Gu 52 sql t-sql sql-server sql-server-2008 sql-server-2008-r2
我有一个名为的表countries,我country_name通过在SQL Server 2008 R2上创建"唯一键"类型的"索引/键"来定义列是唯一的.
但我有以下问题:
IsUnique值保持为"是",那么会有任何差异吗?Aar*_*and 69
在幕后将唯一约束作为唯一索引实现,因此指定它并不重要.我倾向于简单地实现它:
ALTER TABLE dbo.foo ADD CONSTRAINT UQ_bar UNIQUE(bar);
Run Code Online (Sandbox Code Playgroud)
有些人创建了一个独特的索引,例如
CREATE UNIQUE INDEX IX_UQ_Bar ON dbo.foo(bar);
Run Code Online (Sandbox Code Playgroud)
不同之处在于意图 - 如果要创建约束以强制执行唯一性/业务规则,则创建约束,如果这样做是为了帮助查询性能,则创建唯一索引可能更合乎逻辑.同样,在幕后它是相同的实现,但你走到那里的道路可能有助于记录你的意图.
我认为有多种选择可以遵循以前的Sybase功能以及遵守ANSI标准(即使唯一约束不符合标准100%,因为它们只允许一个NULL值 - 一个唯一索引,另一方面,可以通过在SQL Server 2008及更高版本上添加WHERE子句(WHERE col IS NOT NULL)来解决此问题.
Ale*_*kov 14
还有一点需要注意的是,如果您创建索引,则可以指定包含的列,如果通过country_name进行搜索,这可以帮助您的SQL代码更快地运行.
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'
Run Code Online (Sandbox Code Playgroud)
SQL服务器将在索引本身中存储"foo_other_column".在唯一约束的情况下,它将首先找到'test'的索引,然后将在foo表中搜索行,并且仅在那里它将采用"foo_other_column".
除了上面的优秀答案之外,我还要在这里添加我的 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;
Run Code Online (Sandbox Code Playgroud)
我们将得到以下内容(约束和索引)
但是,如果我们不创建约束而仅创建唯一索引,如下所示
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
Run Code Online (Sandbox Code Playgroud)
您将看到没有创建任何约束对象(仅创建了一个索引)。
从“理论”的角度来看,在SQL Server中,约束是一个具有object_id值的对象,并且与模式绑定,而索引不是一个对象,没有object_id值,也与模式无关。