sql - 添加主键是否会导致底层数据重构

标签 sql sql-server sql-server-2008 primary-key clustered-index

我正在将大量数据导入 SQL Server 数据库。源数据源自 PgSql(包括表定义),我通过一些相当简单的正则表达式将其转换为 TSql。这将创建没有主键的表。

据我了解,缺少主键/聚集索引意味着数据存储在堆中。

导入完成后,我将添加 PK,如下所示:

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id);

(请注意缺少 CLUSTERED 关键字)。现在发生什么事了?还是一堆?主键查找有什么影响?这与添加标准索引真的有什么不同吗?

现在,假设我按如下方式添加 PK:

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY CLUSTERED (id);

我认为这现在将表完全重组为基于行的结构,通过 PK 进行更有效的查找,但插入特性不太理想。

我的假设正确吗?

如果我的导入按 PK 顺序插入数据,那么首先省略 PK 有什么好处吗?

最佳答案

当你执行

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id);

如果someTable上没有聚集索引,那么PK将是聚集PK。否则,如果在执行 ALTER .. ADD ... PRIMARY KEY (id) 之前存在聚集索引,则 PK 将是非聚集 PK。

-- 测试#1

BEGIN TRAN;
CREATE TABLE dbo.MyTable
(
    id INT NOT NULL,
    Col1 INT NOT NULL,
    Col2 VARCHAR(50) NOT NULL
);
SELECT  i.name, i.index_id, i.type_desc
FROM    sys.indexes i
WHERE   i.object_id = OBJECT_ID(N'dbo.MyTable');
/*
name index_id    type_desc
---- ----------- ---------
NULL 0           HEAP
*/
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable PRIMARY KEY (id);

SELECT  i.name, i.index_id, i.type_desc
FROM    sys.indexes i
WHERE   i.object_id = OBJECT_ID(N'dbo.MyTable');
/*
name        index_id    type_desc
----------- ----------- ---------
PK_MyTable  1           CLUSTERED
*/
ROLLBACK;

-- 测试#2

BEGIN TRAN;
CREATE TABLE dbo.MyTable
(
    id INT NOT NULL,
    Col1 INT NOT NULL,
    Col2 VARCHAR(50) NOT NULL
);
SELECT  i.name, i.index_id, i.type_desc FROM    sys.indexes i WHERE i.object_id = OBJECT_ID(N'dbo.MyTable');
/*
name index_id    type_desc
---- ----------- ---------
NULL 0           HEAP
*/
CREATE CLUSTERED INDEX ix1
ON dbo.MyTable(Col1);

SELECT  i.name, i.index_id, i.type_desc FROM    sys.indexes i WHERE i.object_id = OBJECT_ID(N'dbo.MyTable');
/*
name index_id    type_desc
---- ----------- ---------
ix1  1           CLUSTERED
*/

ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable PRIMARY KEY (id);

SELECT  i.name, i.index_id, i.type_desc FROM    sys.indexes i WHERE i.object_id = OBJECT_ID(N'dbo.MyTable');
/*
name       index_id    type_desc
---------- ----------- ------------
ix1        1           CLUSTERED
PK_MyTable 2           NONCLUSTERED
*/
ROLLBACK;

关于sql - 添加主键是否会导致底层数据重构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18539121/

相关文章:

调用存储过程时.NET READPAST 锁定错误

sql - 比较SQL Server中的两个字符串

MYSQL - 加入三个表

SQL根据激活/停用记录回答: which customers were active in a given month,

sql - 自连接与内部和外部连接查询

SQL:将 DATEADD 与 bigint 结合使用

sql - 你能告诉我数据是什么时候插入到表中的吗

SQL Numeric 的 C# 正确替代

mysql - 如何在mysql中查找与年份无关的特定月份的所有行

sql-server - 将 SQL Server 数据库导入 HDFS 或 HIVE