我是SQL Server的新手,在学习聚集索引时,我感到很困惑!
是唯一键聚簇还是非聚簇索引?唯一键只保留列中的唯一值,包括null,因此根据这个概念,唯一键应该是聚簇索引,对吧?但是当我阅读这篇文章时,我感到困惑MSDN
创建UNIQUE约束时,将使用唯一的非聚簇索引 默认情况下创建以强制执行UNIQUE约束。你可以指定一个 如果表上的聚簇索引没有,则为唯一聚簇索引 已经存在。
请帮助我以更好的方式理解这个概念,谢谢。
答案 0 :(得分:4)
在SQL Server索引中有三种强制唯一性的方法。
它们是聚簇还是非聚簇与使用这些方法中的索引是否声明为唯一正交。
这三种方法都可以创建聚簇索引或非聚簇索引。
默认情况下,如果您没有指定任何不同的唯一约束和唯一索引将创建非聚集索引(如果不存在冲突的聚簇索引,则默认情况下PK将创建为 npm -v && au --version && npm list typescript aurelia-framework webpack
3.10.3
0.18.0
rpf@0.1.12 C:\Users\xeno\IdeaProjects\rpf-ui
+-- aurelia-framework@1.0.2
+-- typescript@2.0.2
+-- typings@1.3.3
| `-- typings-core@1.4.1
| `-- typescript@1.8.7
`-- webpack@2.1.0-beta.21
)但您可以为其中任何一个明确指定CLUSTERED
/ CLUSTERED
。
示例语法是
NONCLUSTERED
对于未指定为唯一的索引,SQL Server将以任何方式静默地使它们成为唯一的。对于聚簇索引,可以通过将唯一文件附加到重复键来完成。对于非聚簇索引,行标识符(逻辑或物理)将添加到密钥以保证唯一性。
答案 1 :(得分:1)
唯一索引既可以是群集也可以是非群集。 但是如果你有可空列,则NULL值应该是唯一的(只有1行,其中column为null)。 如果要存储多于1个NULL,可以使用过滤器“where columnName not null”创建索引。
答案 2 :(得分:1)
所有提供的答案都非常有用,但我仍然想添加一些详细的答案,以便我对其他人也有帮助
场景1:主键将默认为聚集索引
在这种情况下,我们将只创建主键,当我们检查在表上创建的索引类型时,我们会注意到它已经自动创建了聚簇索引。
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY,
Col1 INT NOT NULL)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
场景2:主键定义为非聚集索引
在这种情况下,我们将显式定义主键作为非聚集索引,并将其创建为非聚集索引。它证明了主键可以是非聚集索引。
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY NONCLUSTERED,
Col1 INT NOT NULL)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
场景3:主键默认为非聚集索引,另一列定义为聚簇索引
在这种情况下,我们将在另一列上创建聚簇索引,SQL Server将自动创建一个主键作为非聚集索引,因为在另一列上指定了聚簇索引。
-- Case 3 Primary Key Defaults to Non-clustered Index
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY,
Col1 INT NOT NULL UNIQUE CLUSTERED)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO
场景4:主键默认为聚簇索引,其他索引默认为非聚集索引
在这种情况下,我们将在两个表上创建两个索引,但是我们不会在列上指定索引的类型。当我们检查结果时,我们会注意到主键自动默认为聚簇索引,另一列默认为非聚集索引。
-- Case 4 Primary Key and Defaults
USE TempDB
GO
-- Create table
CREATE TABLE TestTable
(ID INT NOT NULL PRIMARY KEY,
Col1 INT NOT NULL UNIQUE)
GO
-- Check Indexes
SELECT OBJECT_NAME(OBJECT_ID) TableObject,
[name] IndexName,
[Type_Desc] FROM sys.indexes
WHERE OBJECT_NAME(OBJECT_ID) = 'TestTable'
GO
-- Clean up
DROP TABLE TestTable
GO