Cách chuyển đổi các khóa chính thành các khóa chính được phân cụm cho một số lượng lớn các bảng giữ bản sắc tham chiếu


7

Sau khi khám phá ra, tôi tốt hơn nên thay đổi các khóa chính từ không phân cụm thành phân cụm. Cf câu hỏi này về các chỉ mục được nhóm trên các cột danh tính , bước tiếp theo là làm thế nào để làm điều này theo cách prcatical.

Tôi đã rất ngạc nhiên khi tôi không tìm thấy câu hỏi này trên SO.

Có các tham chiếu tham chiếu giữa các bảng của tôi, tôi không thể đơn giản làm

if object_id('MyChild') > 0 drop table MyChild
if object_id('Mytable') > 0 drop table Mytable
create table Mytable(
    id int Not NULL
)
go
create table MyChild(
    id int Not NULL,
    masterid int NULL
)
go
alter table Mytable add constraint PK_Mytable primary key  (id)
alter table MyChild add constraint FK_MyChild_MyTable foreign key (masterid) references Mytable(id)
go
-- Now I want to change the primary key into a clustered primary key
-- this throws an error
ALTER TABLE Mytable DROP CONSTRAINT PK_Mytable
GO
ALTER TABLE Mytable ADD CONSTRAINT PK_Mytable  PRIMARY KEY CLUSTERED (id)
GO

Ở đây tôi nhận được lỗi sau

Msg 3725, Level 16, State 0, Line 1
Auf die 'PK_Mytable'-Einschränkung wird von der 'MyChild'-Tabelle, FOREIGN KEY-Einschränkung 'FK_MyChild_MyTable' verwiesen.
Msg 3727, Level 16, State 0, Line 1
Die Einschränkung konnte nicht gelöscht werden. Siehe vorherige Fehler.

OK Tôi biết rằng nó hoạt động, khi tôi bỏ ràng buộc khóa ngoại trước khi thay đổi và thiết lập lại sau đó.

alter table MyChild drop constraint FK_MyChild_MyTable
go
ALTER TABLE Mytable DROP CONSTRAINT PK_Mytable
GO
ALTER TABLE Mytable ADD CONSTRAINT PK_Mytable  PRIMARY KEY CLUSTERED (id)
GO
alter table MyChild add constraint FK_MyChild_MyTable foreign key (masterid) references Mytable(id)
go

Nghe có vẻ như, tôi phải kịch bản tất cả các quan hệ khóa ngoài từ cơ sở dữ liệu, loại bỏ chúng, thực hiện các thay đổi khóa chính của tôi và thiết lập lại các khóa ngoại từ tập lệnh được tạo.

Có cách nào tốt hơn cho nhiệm vụ này.

BTW. Cuối cùng chúng tôi muốn làm điều này trên cơ sở dữ liệu sản xuất. (Thời gian chết là một lựa chọn được phép). Tất cả các cơ sở dữ liệu là SQL Server 2005 hoặc SQL Server 2008.

Biên tập:

Một đồng nghiệp đã đề xuất bỏ tất cả các chỉ mục trước hoạt động này và xây dựng lại chúng sau đó. Âm thanh hợp lý với tôi.

2. Chỉnh sửa:

Nhìn vào câu hỏi dba.stackexchange này , tôi bắt đầu tự hỏi liệu nó có đủ để chỉ thêm các chỉ mục được nhóm vào các cột khóa chính của bảng không.

Câu trả lời:


6

Cách tiếp cận của bạn là chính xác và khá nhiều cách duy nhất, nhưng tôi sẽ xem xét sử dụng một công cụ như Red Gate để giúp tôi.

Bước thứ 3 lưu lại việc viết một cái gì đó vào kịch bản định nghĩa FK của chúng tôi hoặc xử lý SSMS / SMO


Hhm. Tôi nghĩ rằng tôi sẽ nhanh chóng hơn khi viết PowerShell Script bằng SMO để loại bỏ tất cả các khóa ngoại, hơn là cài đặt các công cụ Red Gate. BTW Tôi nghĩ sẽ tốt hơn nếu viết kịch bản cho các FK trước khi bỏ chúng. Tôi đoán công cụ được đề cập cần kết nối với cơ sở dữ liệu và mặc dù công cụ so sánh tên, kịch bản FK có thể từ cơ sở dữ liệu đã cho không?
bernd_k

Đúng. Nó sẽ tạo ra một kịch bản với sự khác biệt (bạn có thể chọn bỏ qua một số). Có những công cụ khác như dbghost cũng miễn phí.
gbn

Tôi đã tìm kiếm các tập lệnh T-SQL để tạo FK. Tôi đã tìm thấy một số thứ không hoàn hảo và tôi sẽ không cải thiện chúng. Nhưng sự lựa chọn giữa kịch bản SMO và sử dụng các công cụ dường như là một câu hỏi về sở thích cá nhân. Cho đến nay tôi vẫn kết hợp với PowerShell và SMO.
bernd_k

2

Tôi không phải là người của SQL Server, nhưng tôi biết rằng trong MySQL bạn có thể tạm thời vô hiệu hóa kiểm tra khóa ngoại. Tôi đã tìm hiểu nhanh về việc liệu có thể làm điều này trong SQL Server hay không và đã đưa ra liên kết này:

/programming/159038/can-forign-key-constraint-be-temporantly-disables-USE-t-sql

Tóm tắt từ câu trả lời:

-- disable all constraints
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

-- enable all constraints
EXEC sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

1
Cố gắng tốt đẹp. Tự nghĩ về nó, nhưng nó không hoạt động. Thông báo lỗi tương tự như trước đây.
bernd_k

cũng tốt để nó ở đây thay vì xóa để người khác không có cùng ý tưởng: D
Derek Downey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.