表定义中的主键与唯一聚簇索引

时间:2015-07-28 19:36:38

标签: sql-server

将PK定义为表定义的一部分与将其添加为唯一的聚簇索引之间有什么区别。使用下面的示例,两个表在sys.indexes中显示为index_id 1,但只有table1具有is_primary_key = 1

我认为这是相同的,但SSMS只显示table1上的键符号

感谢。

CREATE DATABASE IndexVsHeap
GO
USE [IndexVsHeap]
GO

-- Clustered index table
CREATE TABLE [dbo].[Table1](
    [LogDate] [datetime2](7) NOT NULL,
    [Database_Name] [nvarchar](128) NOT NULL,
    [Cached_Size_MB] [decimal](10, 2) NULL,
    [Buffer_Pool_Percent] [decimal](5, 2) NULL
    CONSTRAINT [PK_LogDate_DatabaseName] PRIMARY KEY(LogDate, Database_Name) 
) 

-- Table as heap, PK-CI added later, or did i?
CREATE TABLE [dbo].[Table2](
    [LogDate] [datetime2](7) NOT NULL,
    [Database_Name] [nvarchar](128) NOT NULL,
    [Cached_Size_MB] [decimal](10, 2) NULL,
    [Buffer_Pool_Percent] [decimal](5, 2) NULL
) 

-- Adding PK-CI to table2
CREATE UNIQUE CLUSTERED INDEX [PK_LogDate_Database_Name] ON [dbo].[Table2]
(
    [LogDate] ASC,
    [Database_Name] ASC
) 
GO

SELECT object_name(object_id), * FROM sys.index_columns
    WHERE object_id IN ( object_id('table1'),  object_id('table2') )
SELECT * FROM sys.indexes
    WHERE name LIKE '%PK_LogDate%'

3 个答案:

答案 0 :(得分:0)

主键是以唯一方式标识每一行的键(它也是唯一索引)。它可以是群集的,但强烈建议群集。如果它是群集的,则根据该密钥存储数据。

唯一聚簇索引是唯一值(或值的组合),并且数据基于该索引存储。

聚集索引的优势是什么?如果你必须进行索引扫描(扫描整个索引),数据会一起存储,因此速度更快。

答案 1 :(得分:0)

对于所有意图和目的,这里没有区别。

唯一索引允许null,但无论如何列都是not null

此外,唯一索引(尽管不是约束)可以使用include d列声明或作为筛选索引声明,但这些索引都不适用于此处,因为索引是聚集的。

主键创建一个命名约束对象,该对象是模式作用域,因此名称必须是唯一的。索引只能在其所属的表中唯一地命名。

我仍然会选择PK来获得工具中的视觉指示器。它允许其他开发人员(可能还有代码)更容易地检测到唯一的行标识符。

答案 2 :(得分:0)

还要记住,虽然一个表只能有一个PK,但它可以有多个唯一索引(尽管只有一个可以聚类)。

我可以看到你可能想要以某种有意义的方式对信息进行聚类,但可能希望有一个单独的自动生成的非聚集PK来加快连接速度,例如加入汽车VIN号码。这就是两者都可用的原因。