Catatan: pada Azure SQL Database v12, pembatasan ini tidak lagi berlaku.
Tidak ada yang namanya 'indeks primer'. Ada yang namanya 'kunci utama' dan ada juga yang namanya 'indeks berkerumun'. Konsep yang berbeda, sering membingungkan. Dengan perbedaan ini dalam pikiran, mari kita kembali ke pertanyaan:
T1) Dapatkah indeks berkerumun di tabel SQL Azure diubah?
A: Ya. Gunakan WITH (DROP_EXISTING=ON)
:
create table Friend (
UserId int not null,
Id int not null);
go
create clustered index cdxFriend on Friend (UserId, Id);
go
create clustered index cdxFriend on Friend (Id, UserId) with (drop_existing=on);
go
T2) Dapatkah indeks berkerumun dari tabel yang memiliki batasan kunci primer diubah?
A: Ya, sama seperti di atas, selama batasan kunci utama tidak ditegakkan melalui indeks berkerumun:
create table Friend (
UserId int not null,
Id int not null identity(1,1),
constraint pk_Friend primary key nonclustered (Id));
create clustered index cdxFriend on Friend (UserId, Id);
go
create clustered index cdxFriend on Friend (Id, UserId) with (drop_existing=on);
go
T3) Dapatkah batasan kunci utama dari tabel diubah?
A: Ya, selama kendala utama tidak ditegakkan melalui indeks berkerumun:
create table Friend (
UserId int not null,
Id int not null identity(1,1),
constraint pk_Friend primary key nonclustered (Id));
go
create clustered index cdxFriend on Friend (UserId, Id);
go
alter table Friend drop constraint pk_Friend;
alter table Friend add constraint pk_Friend primary key nonclustered (UserId)
go
T4) Bisakah kunci primer tabel diubah ketika diberlakukan melalui indeks berkerumun?
A: Ya, jika tabel tidak pernah memiliki baris:
create table Friend (
UserId int not null,
Id int not null identity(1,1),
constraint pk_Friend primary key clustered (UserId, Id));
go
alter table Friend drop constraint pk_Friend;
alter table Friend add constraint pk_Friend primary key clustered (Id, UserId)
go
T5) Dapatkah kunci utama tabel diubah ketika diberlakukan melalui indeks berkerumun jika tabel diisi?
A: Tidak. Operasi apa pun yang mengubah indeks cluster yang dihuni menjadi heap akan diblokir dalam SQL Azure, bahkan jika tabel kosong :
create table Friend (
UserId int not null,
Id int not null identity(1,1),
constraint pk_Friend primary key clustered (UserId, Id));
go
insert into Friend (UserId) values (1);
delete from Friend;
go
alter table Friend drop constraint pk_Friend;
Sebagai catatan: kendala dapat dimodifikasi jika tabel terpotong .
Solusi untuk mengubah batasan PK dari tabel berpopulasi adalah dengan melakukan sp_rename
trik lama yang baik :
create table Friend (
UserId int not null,
Id int not null identity(1,1),
constraint pk_Friend primary key clustered (UserId, Id));
go
insert into Friend (UserId) values (1);
go
create table FriendNew (
UserId int not null,
Id int not null identity(1,1),
constraint pk_Friend_New primary key clustered (Id, UserId));
go
set identity_insert FriendNew on;
insert into FriendNew (UserId, Id)
select UserId, Id
from Friend;
set identity_insert FriendNew off;
go
begin transaction
exec sp_rename 'Friend', 'FriendOld';
exec sp_rename 'FriendNew', 'Friend';
commit;
go
sp_help 'Friend';
The sp_rename
pendekatan memiliki beberapa masalah, yang paling penting adalah bahwa hak akses atas meja tidak terbawa selama rename, serta batasan kunci asing.