主键与聚簇指数的关系

F11*_*F11 82 sql database sql-server database-design

TABLE可以具有没有聚簇索引的主键吗?

并且TABLE可以在没有主键的情况下具有聚簇索引吗?

有人可以简单地告诉我主键和聚簇索引的关系吗?

Nev*_*uyt 87

主键是逻辑概念 - 它是表中行的唯一标识符.因此,它有一堆属性 - 它可能不是null,而且必须是唯一的.当然,由于您可能会通过其唯一标识符搜索记录,因此在主键上建立索引会很好.

聚簇索引是一个物理概念 - 它是一个影响记录存储在磁盘上的顺序的索引.这使得它在访问数据时成为一个非常快的索引,但如果主键不是序列号,它可能会减慢写入速度.

是的,您可以拥有一个没有聚簇索引的主键 - 有时,您可能想要(例如,当您的主键是连接表上的外键组合时,并且您不希望产生磁盘混乱开销)写作时).

是的,您可以在不是主键的列上创建聚簇索引.

  • 你好。主题很旧,但也许有人可以回答我的问题。如果列被声明为 NOT NULL UNIQUE CLUSTERED INDEX,使其成为 PRIMARY KEY 会对性能或其他方面产生任何实际变化吗? (2认同)

And*_*mar 31

表可以具有未集群的主键,并且集群表不需要主键.所以这两个问题的答案都是肯定的.

聚簇索引存储叶级别的所有列.这意味着聚簇索引包含表中的所有数据.没有聚簇索引的表称为堆.

主键是默认情况下是群集的唯一索引.默认情况下,在创建主键时,如果表尚未集群,则主键将创建为集群唯一索引.除非您明确指定nonclustered选项.

例如,其中t1包含非t2聚簇主键,并且不是群集但具有主键:

create table t1 (id int not null, col1 int);
alter table t1 add constraint PK_T1 primary key nonclustered (id);
create clustered index IX_T1_COL1 on t1 (col1);

create table t2 (id int not null, col1 int);
alter table t2 add constraint PK_T2 primary key nonclustered (id);
Run Code Online (Sandbox Code Playgroud)

SQL Fiddle的例子.


Bra*_*vic 16

首先,看一下Index-Organized Tables和Clustered Indexes.实际上,我建议阅读整个使用指数卢克!站点从一开始,直到您到达群集主题,以真正了解正在发生的事情.

现在,对你的问题......


TABLE可以具有没有聚簇索引的主键吗?

是,在声明主键以创建基于堆的表时使用NONCLUSTERED关键字.例如:

CREATE TABLE YOUR_TABLE (
    YOUR_PK int PRIMARY KEY NONCLUSTERED
    -- Other fields...
);
Run Code Online (Sandbox Code Playgroud)

这很不幸,因为很多人似乎只接受默认值(即CLUSTERED),即使在许多情况下基于堆的表实际上会更好(如链接文章中所述).


并且TABLE可以在没有主键的情况下具有聚簇索引吗?

与其他一些DBMS不同,MS SQL Server将允许您拥有与主键不同的集群索引,甚至根本没有主键.

下面的示例创建一个与PK分离的聚簇索引,它在其上面有一个UNIQUE约束,这在大多数情况下是您可能想要的:

CREATE TABLE YOUR_TABLE (
    YOUR_PK int PRIMARY KEY,
    YOUR_CLUSTERED_KEY int NOT NULL UNIQUE CLUSTERED
    -- Other fields...
);
Run Code Online (Sandbox Code Playgroud)

如果选择非唯一的聚类索引(使用CREATE CLUSTERED INDEX ...),MS SQL Server将通过向其添加隐藏字段来自动使其唯一.

请注意,对于范围扫描,群集的好处最为明显.如果您使用的聚簇索引与客户端应用程序执行的范围扫描没有"对齐"(例如,当过度依赖上面提到的隐藏列,或者在代理键上聚类时),那么您就是打败聚类的目的.


有人可以简单地告诉我主键和聚簇索引的关系吗?

在MS SQL Server下,默认情况下主键也是群集.您可以更改该默认值,如上所述.