एक विदेशी कुंजी के लिए संदर्भित संदर्भ बदलें


9

मेरे पास कुछ इस तरह है:

CREATE TABLE T1 (
    Id INT
    ...
    ,Constraint [PK_T1] PRIMARY KEY CLUSTERED [Id]
)

CREATE TABLE T2 (
    ....
    ,T1_Id INT NOT NULL
    ,CONSTRAINT [FK_T2_T1] FOREIGN KEY (T1_Id) REFERENCES T1(Id)
)

प्रदर्शन (और गतिरोध) कारणों से मैंने T1 पर एक नया सूचकांक बनाया

CREATE UNIQUE NONCLUSTERED INDEX IX_T1_Id ON T1 (Id)

लेकिन अगर मैं जांचता हूं कि कौन सा इंडेक्स एफके का संदर्भ लेता है, तो क्लस्टर इंडेक्स का संदर्भ रखता है

select
    ix.index_id,
    ix.name as index_name,
    ix.type_desc as index_type_desc,
    fk.name as fk_name
from sys.indexes ix
    left join sys.foreign_keys fk on
        fk.referenced_object_id = ix.object_id
        and fk.key_index_id = ix.index_id
        and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');

अगर मैं बाधा छोड़ता हूं और फिर से बनाता हूं तो यह गैर-अनुक्रमित सूचकांक को संदर्भित करता है, लेकिन इससे सभी t2 FK को फिर से जांचना होगा।

क्या इसे बदलने का कोई तरीका है, इसलिए FK_T2_T1 में PKX1 के बजाय IX_T1_Id का उपयोग किया जाता है, बिना FK को हटाए और FK चेकिंग पर तालिका को लॉक किए बिना?

धन्यवाद!


वहाँ एक प्रासंगिक चर्चा नहीं हुई यहाँ
i-एक

जवाबों:


6

खैर, खोज जारी रखने के बाद मुझे यह लेख मिला

एक सामान्य क्वेरी के विपरीत, यह आँकड़ों को अद्यतन किए जाने के कारण नया सूचकांक नहीं बनाएगा, एक नया सूचकांक बनाया जा रहा है, या यहां तक ​​कि सर्वर को रिबूट किया जा रहा है। जिस तरह से मैं एक अलग सूचकांक के लिए एक एफके बाँध है के बारे में पता कर रहा हूँ ड्रॉप करने के लिए और एफके फिर से बनाना है, यह स्वचालित रूप से इसे नियंत्रित करने के लिए कोई विकल्प नहीं के साथ सूचकांक का चयन करने देता है।

व्हाट्सअप, जब तक कि कोई अन्यथा नहीं कह सकता, मुझे इस कार्य को करने के लिए एक समय खिड़की की तलाश करनी होगी।

धन्यवाद


2

यहां MS DOCS पढ़ने के बाद ।

एक विदेशी कुंजी को संशोधित करने के लिए

Transact-SQL का उपयोग करके एक FOREIGN कुंजी बाधा को संशोधित करने के लिए, आपको पहले मौजूदा FOREIGN कुंजी बाधा को हटाना होगा और फिर इसे नई परिभाषा के साथ बनाना होगा। अधिक जानकारी के लिए, विदेशी कुंजी संबंध हटाएँ और विदेशी कुंजी संबंध बनाएँ देखें।

आपके मामले में मेरा मानना ​​है कि एक नया FK जोड़ें और पुराने को हटा दें। स्कैन को अक्षम करने के लिए आप NO CHECKविकल्प का उपयोग कर सकते हैं

--DROP TABLE T2
--DROP TABLE T1


CREATE TABLE T1 (
    [Id] INT,
    [NAME] varchar(100), CONSTRAINT [PK_T1] PRIMARY KEY CLUSTERED (id))

CREATE TABLE T2 (
    t2_id int,
    T1_Id INT NOT NULL
    ,CONSTRAINT [FK_T2_T1] FOREIGN KEY (T1_Id) REFERENCES T1(Id)
)


CREATE UNIQUE NONCLUSTERED INDEX IX_T1_Id ON T1 (Id)


select
    ix.index_id,
    ix.name as index_name,
    ix.type_desc as index_type_desc,
    fk.name as fk_name
from sys.indexes ix
    left join sys.foreign_keys fk on
        fk.referenced_object_id = ix.object_id
        and fk.key_index_id = ix.index_id
        and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');



╔══════════╦════════════╦═════════════════╦══════════╗
 index_id  index_name  index_type_desc  fk_name  
╠══════════╬════════════╬═════════════════╬══════════╣
        1  PK_T1       CLUSTERED        FK_T2_T1 
        2  IX_T1_Id    NONCLUSTERED     NULL     
╚══════════╩════════════╩═════════════════╩══════════╝




 ALTER TABLE T2
    WITH NOCHECK 
    ADD CONSTRAINT [FK_T2_T1_NEW] FOREIGN KEY(T1_Id)
    REFERENCES T1(Id)

select
    ix.index_id,
    ix.name as index_name,
    ix.type_desc as index_type_desc,
    fk.name as fk_name
from sys.indexes ix
    left join sys.foreign_keys fk on
        fk.referenced_object_id = ix.object_id
        and fk.key_index_id = ix.index_id
        and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');


╔══════════╦════════════╦═════════════════╦══════════════╗
 index_id  index_name  index_type_desc    fk_name    
╠══════════╬════════════╬═════════════════╬══════════════╣
        1  PK_T1       CLUSTERED        FK_T2_T1     
        2  IX_T1_Id    NONCLUSTERED     FK_T2_T1_NEW 
╚══════════╩════════════╩═════════════════╩══════════════╝   

ALTER TABLE T2  
DROP CONSTRAINT FK_T2_T1 

select
    ix.index_id,
    ix.name as index_name,
    ix.type_desc as index_type_desc,
    fk.name as fk_name
from sys.indexes ix
    left join sys.foreign_keys fk on
        fk.referenced_object_id = ix.object_id
        and fk.key_index_id = ix.index_id
        and fk.parent_object_id = object_id('T2')
where ix.object_id = object_id('T1');


╔══════════╦════════════╦═════════════════╦══════════════╗
 index_id  index_name  index_type_desc    fk_name    
╠══════════╬════════════╬═════════════════╬══════════════╣
        1  PK_T1       CLUSTERED        NULL         
        2  IX_T1_Id    NONCLUSTERED     FK_T2_T1_NEW 
╚══════════╩════════════╩═════════════════╩══════════════╝

यह देखें कि क्या यह काम करता है, मैं जो कोशिश कर रहा हूं वह एक और एफके को जोड़ना है ताकि नया बनाया गया नए सूचकांक से जुड़ा हो और पुराने केके को छोड़ दें। मुझे पता है कि सवाल मौजूदा को छोड़ने का नहीं है, लेकिन देखें कि क्या यह विकल्प आपकी मदद करेगा।

इसके अलावा, मैक्स वर्नोन की टिप्पणियों के अनुसार: "विद एनओएचईसीएचके विकल्प विदेशी कुंजी को ऑप्टिमाइज़र द्वारा भरोसेमंद होने से रोकेगा। कुछ बिंदु पर, आपको विदेशी कुंजी को बदलना होगा ताकि यह विश्वसनीय तालिका का उपयोग करके विश्वसनीय हो ... चेक के साथ "

NOCHECKकेवल निर्माण के समय ध्यान नहीं दिया जाएगा लेकिन अखंडता contraint लागू करने के लिए आप समय के कुछ बिंदु पर यह समाप्त हो गया है।


WITH NOCHECKविदेशी कुंजी पाएगा विकल्प अनुकूलक द्वारा भरोसा किया जा रहा। कुछ बिंदु पर, आपको विदेशी कुंजी को बदलना होगा ताकि इसका उपयोग करके भरोसा किया जाएALTER TABLE ... WITH CHECK
मैक्स वर्नोन

@MaxVernon का मतलब है कि हमारे पास विकल्प नहीं है
बीजू जो

सही बात। नए इंडेक्स का उपयोग करने के लिए विदेशी कुंजी प्राप्त करने का एकमात्र तरीका CHECK विकल्प के साथ विदेशी कुंजी को फिर से बनाना है।
मैक्स वेरनॉन

@ मोम वर्नोन, उत्तर को तब अपडेट करेगा
बीजू जोस

थैंक्स @Biju jose for aicial डॉक्यूमेंट।
मारियानो जी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.