You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

若表中主键为聚集索引,其他列(如唯一列)是否均为非聚集索引?

关于聚集索引与唯一列索引的疑问解答

首先先看你提供的people表创建语句(注意这里有个小拼写错误:LastNanme应该是LastName):

CREATE TABLE people(
    personID int,
    FirstName VARCHAR(255),
    LastNanme VARCHAR(255),
    Address VARCHAR(255),
    City VARCHAR(255),
    PRIMARY KEY (PERSONID)
);

默认情况下,多数主流数据库(比如SQL Server、MySQL InnoDB)会把主键设置为聚集索引——这也是你问题的前提,那我们基于这个场景来拆解问题:

核心结论:其他唯一列并不「必然」全是非聚集索引,但一张表永远只能有一个聚集索引

  • 先明确一个关键规则:一张表只能存在一个聚集索引。因为聚集索引的本质是决定了表中数据在磁盘上的物理存储顺序,一张表的数据总不能同时按两种顺序排列吧?所以聚集索引是唯一的。
  • 回到你的场景:如果personID已经是聚集索引,那么:
    • 当你给其他唯一列(比如给FirstName加唯一约束,或者新增一个唯一的Email列)创建唯一索引/约束时,数据库默认会创建非聚集索引——这是最常见的使用场景。
    • 你没法直接给另一个唯一列加聚集索引,除非先把原主键的聚集属性拿掉(比如把主键改成非聚集索引),之后才能把目标唯一列设为聚集索引。但这么操作后,原来的主键索引就变成了非聚集索引,表中依然只有一个聚集索引。

举个具体操作例子(以SQL Server为例):

  1. 先移除原主键的聚集属性:
ALTER TABLE people DROP CONSTRAINT PK_people_personID;
ALTER TABLE people ADD CONSTRAINT PK_people_personID PRIMARY KEY NONCLUSTERED (personID);
  1. 新增唯一列并设置为聚集索引:
ALTER TABLE people ADD COLUMN Email VARCHAR(255) UNIQUE NOT NULL;
CREATE CLUSTERED INDEX CI_people_Email ON people(Email);

这时候Email是聚集索引,而personID的主键索引就变成了非聚集索引。

额外小补充

在MySQL的InnoDB引擎里,聚集索引是强制存在的:如果没显式设主键,数据库会自动选第一个非空的唯一列当聚集索引;如果连这样的列都没有,会偷偷创建一个内部自增列作为聚集索引。但不管哪种情况,一张表始终只有一个聚集索引。

内容的提问来源于stack exchange,提问作者Saket khatavkar

火山引擎 最新活动