SQL Server 使用没有主键的聚集索引创建表

Posted

技术标签:

【中文标题】SQL Server 使用没有主键的聚集索引创建表【英文标题】:SQL Server creating table with clustered index without a primary key 【发布时间】:2012-01-10 02:32:54 【问题描述】:

是否可以从 SQL Server 2008 中的非主键的 create table 语句创建聚集索引?

这样做的目的是为了 SQL Azure 中的一个表,所以我不能先创建表,然后在表上创建聚集索引。

编辑:显然是 FluentMigrator 导致了我的问题,它的版本表没有聚集索引,因此尝试创建版本控制表而不是我的表时出错。

【问题讨论】:

我很确定您可以稍后再回来创建聚集索引,即使在 Azure 中也是如此。 Azure 不会阻止您创建没有聚集索引的表,它只会阻止您插入其中。 @MikeMooney Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again. 不存在插入数据。 @MikeMooney 你是对的,如果你还没有看到我在上面的编辑。 见dba.stackexchange.com/questions/6937/…,不知何故相关 【参考方案1】:

是的,可以创建一个不是主键的聚集索引。只需使用CREATE CLUSTERED INDEX 语句即可。

CREATE TABLE dbo.myTable (
    myTableId int PRIMARY KEY NONCLUSTERED
    myColumn int NOT NULL
)

CREATE CLUSTERED INDEX myIndex ON dbo.myTable(myColumn)

在 Azure SQL 数据库 v12 版本之前,您必须先拥有聚集索引,然后才能将任何数据插入到表中。从Azure SQL Database v12 开始,现在支持堆(没有聚集索引的表)。

如果您的数据库是在 2016 年 6 月之前创建的,这里是 instructions for upgrading to version 12。

【讨论】:

链接不再相关。 请记住,集群约束/索引仅在 AZURE SQL 中是必需的。安装的 SQL 没有这个要求。我意识到读者确实提到这是针对 Azure 的,但这个答案听起来像是适用于所有 SQL 风格。【参考方案2】:
CREATE TABLE dbo.Table_1
    (
    Id int NOT NULL IDENTITY (1, 1) PRIMARY KEY NONCLUSTERED,
    SomeOtherUniqueColumn int NOT NULL CONSTRAINT Item4 UNIQUE CLUSTERED
)  ON [PRIMARY]

注意主键上非聚簇的规范

这仍然有效。

CREATE TABLE dbo.Table_1
    (
    SomeOtherUniqueColumn int NOT NULL CONSTRAINT Item4 UNIQUE CLUSTERED
)  ON [PRIMARY]

【讨论】:

有趣,但我不想要主键。 我只是把它放在那里,但不需要主键。我假设你已经有一个主键,所以强制它是非集群的。 聚集索引实际上是针对非唯一列的(因此它不仅仅是一个 PK)。我尝试从第二个示例中删除唯一关键字,但 sql server 似乎不喜欢这样。 问题是CONSTRAINT 在创建CLUSTERED 列时需要PRIMARY KEYUNIQUE...除了使用单独的语句之外,不确定其他解决方法。 msdn.microsoft.com/en-us/library/ms174979.aspx【参考方案3】:

以下代码与 Azure 兼容。它在单个 create table 语句中创建主键非聚集索引和聚集索引。此语法还允许在您的键中指定多个列。

CREATE TABLE MyTable (
    ID uniqueidentifier  NOT NULL,
    UserID uniqueidentifier  NOT NULL,
    EntryDate DATETIME NOT NULL,
    CONSTRAINT PK_MyPrimaryKey_Name PRIMARY KEY NONCLUSTERED (ID),
    CONSTRAINT UCI_MyClusteredIndexName UNIQUE CLUSTERED (UserID ASC,EntryDate ASC,ID ASC)
);

为了更改表的聚集索引,必须删除聚集索引,这会将表转换为堆,然后应用新的聚集索引。因为 Azure 不支持堆(没有聚集索引的表),所以不可能在不删除表并重新创建它的情况下更改聚集索引。在 Azure 中,除了 table create 语句之外,您不能在任何其他位置指定聚集索引。

【讨论】:

以上是关于SQL Server 使用没有主键的聚集索引创建表的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft SQL Server 2008 主键的含义

如何在 SQL Server 中创建聚集索引,同时仍保留主键?

MySQL中怎样创建聚集索引和非聚集索引,求创建这两种索引的SQL语句。谢谢

怎么取消自增列上的聚集索引

SQL Server查询优化和事务处理

主键上的非聚集索引?