Primary Key vs Unique Constraint
Recently, I encountered a table that needed to have the definition of a clustered index altered. It just so happens that the clustered index and the primary key were one and the same, a pretty common occurrence. However, when we went to modify the index, it failed.
The following entry in Books Online for CREATE INDEX explains why:
If the index enforces a PRIMARY KEY or UNIQUE constraint and the index definition is not altered in any way, the index is dropped and re-created preserving the existing constraint. However, if the index definition is altered the statement fails. To change the definition of a PRIMARY KEY or UNIQUE constraint, drop the constraint and add a constraint with the new definition.
Let’s test this, shall we?
/* Create a table with a clustered primary key */
CREATE TABLE dbo.myTable
(
myID INT IDENTITY(1,1) Not Null
, myDate SMALLDATETIME Not Null
, myNumber INT Not Null
CONSTRAINT CIX_myTable
PRIMARY KEY CLUSTERED (myDate, myID)
);
/* Insert some data */
INSERT INTO myTable
SELECT '2009-01-01', 100 UNION All
SELECT '2009-02-01', 200 UNION All
SELECT '2009-01-05', 300;
/* Try to alter the index - FAIL */
CREATE CLUSTERED INDEX CIX_myTable
ON myTable(myID, myDate, myNumber)
WITH (Drop_Existing = ON);
/* Drop the clustered primary key */
ALTER TABLE dbo.myTable
DROP CONSTRAINT CIX_myTable;
/* Add a unique clustered index */
CREATE UNIQUE CLUSTERED INDEX CIX_myTable
ON myTable(myDate, myID);
/* Add a unique constraint */
ALTER TABLE myTable
ADD CONSTRAINT Unique_myTable
UNIQUE (myDate);
/* Try to alter the index - SUCCESS */
CREATE CLUSTERED INDEX CIX_myTable
ON myTable(myID, myDate, myNumber)
WITH (Drop_Existing = ON);
/* Add a primary key constraint */
ALTER TABLE myTable
ADD CONSTRAINT PK_myTable
PRIMARY KEY (myID, myDate);
/* Try to alter the index - SUCCESS */
CREATE CLUSTERED INDEX CIX_myTable
ON myTable(myID, myDate)
WITH (Drop_Existing = ON);
/* Clean-Up */
DROP TABLE myTable;
The only instance that actually fails is the PRIMARY KEY constraint. The unique clustered index is able to be modified successfully, even when a unique constraint is applied to the table. So either I’m misunderstanding BOL, or BOL is mistaken. Either way, I’m then left with the following question: is there any reason to actually use a primary key when a unique index serves the same purpose and offers greater flexibility?
Questions, comments, and explanations are welcome.