अब जब PostgreSQL 12 बाहर हो गया है, तो हम विदेशी कुंजियों को विभाजित तालिकाओं के साथ पूरी तरह से संगत मानते हैं। आपके पास एक विदेशी कुंजी बाधा के दोनों ओर एक विभाजित तालिका हो सकती है, और सब कुछ सही ढंग से काम करेगा।
मैं इसे क्यों इंगित करता हूं? दो कारण:सबसे पहले, जब विभाजन तालिका को पहली बार PostgreSQL 10 में पेश किया गया था, तो वे विदेशी कुंजियों का बिल्कुल भी समर्थन नहीं करते थे; आप विभाजित तालिकाओं पर FK नहीं बना सकते हैं, न ही FK बना सकते हैं जो एक विभाजित तालिका का संदर्भ देते हैं। दूसरा, क्योंकि (शुरुआती दिन) टेबल इनहेरिटेंस फीचर वास्तव में विदेशी कुंजियों का भी समर्थन नहीं करता है। इसका मतलब यह है कि पहली बार PostgreSQL में संदर्भात्मक अखंडता को बनाए रखते हुए बड़ी मात्रा में डेटा बनाए रखना संभव है। अब जबकि यह सुविधा पूरी हो गई है, PostgreSQL के लिए कुछ नए उपयोग के मामले खुले हैं जो पहले नहीं थे।
यहाँ एक बहुत ही तुच्छ उदाहरण है।
CREATE TABLE items ( item_id integer PRIMARY KEY, description text NOT NULL ) PARTITION BY hash (item_id); CREATE TABLE items_0 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 0); CREATE TABLE items_1 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 1); CREATE TABLE items_2 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 2); CREATE TABLE warehouses (warehouse_id integer primary key, location text not null); CREATE TABLE stock ( item_id integer not null REFERENCES items, warehouse_id integer not null REFERENCES warehouses, amount int not null ) partition by hash (warehouse_id); CREATE TABLE stock_0 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 0); CREATE TABLE stock_1 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 1); CREATE TABLE stock_2 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 2); CREATE TABLE stock_3 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 3); CREATE TABLE stock_4 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 4);
आप देख सकते हैं कि यहाँ दो विदेशी कुंजियाँ हैं। एक नियमित (विभाजित नहीं) तालिका की ओर इशारा करता है वेयरहाउस , अन्य विभाजित तालिका आइटम . की ओर इशारा करते हैं . क्या आपने देखा कि प्रत्येक विदेशी कुंजी केवल एक बार घोषित की जाती है?
दो बुनियादी ऑपरेशन हैं जिन्हें आप विदेशी कुंजी प्रदान करना चाहते हैं। सबसे पहले, अगर आप स्टॉक . में एक पंक्ति डालते हैं (संदर्भ तालिका) जिसमें आइटम . में संगत पंक्ति नहीं है या गोदाम (संदर्भित तालिका), एक त्रुटि उठाई जानी चाहिए। दूसरा, यदि आप किसी भी संदर्भित तालिका में एक पंक्ति को हटाते हैं और स्टॉक . में मेल खाने वाली पंक्तियाँ हैं , उस ऑपरेशन को भी खारिज कर दिया जाना चाहिए।
दोनों आसानी से सत्यापित हैं:
INSERT INTO stock values (1, 1, 10); ERROR: insert or update on table "stock_0" violates foreign key constraint "stock_item_id_fkey" DETAIL: Key (item_id)=(1) is not present in table "items".
अच्छा। फिर आप संदर्भित तालिकाओं और संदर्भ पंक्ति दोनों में मेल खाने वाली पंक्तियों को सम्मिलित कर सकते हैं। उसके बाद, किसी भी संदर्भित तालिका में अपेक्षित रूप से हटाना विफल हो जाएगा।
INSERT INTO items VALUES (1, 'item 1'); INSERT INTO warehouses VALUES (1, 'The moon'); INSERT INTO stock VALUES (1, 1, 10); DELETE FROM warehouses; ERROR: update or delete on table "warehouses" violates foreign key constraint "stock_warehouse_id_fkey" on table "stock" DETAIL: Key (warehouse_id)=(1) is still referenced from table "stock". DELETE FROM items; ERROR: update or delete on table "items_2" violates foreign key constraint "stock_item_id_fkey3" on table "stock" DETAIL: Key (item_id)=(1) is still referenced from table "stock".
(बेशक, एक अद्यतन ऑपरेशन पिछले ऑपरेशन के लिए INSERT . के समान है , और बाद के ऑपरेशन के लिए DELETE . के समान — जिसका अर्थ है कि मूल टपल और संशोधित टपल दोनों की जाँच की जानी चाहिए, यदि अद्यतन विदेशी कुंजी में शामिल कॉलम को संशोधित करता है।)
यदि ये उदाहरण अनुभवी उपयोगकर्ताओं के लिए लंगड़े लगते हैं, तो ऐसा इसलिए है क्योंकि ये चीजें अनादि काल से नियमित (विभाजित नहीं) तालिकाओं के लिए समान रूप से काम करती हैं।
वास्तविक उपयोग में, आपको स्टॉक . में संदर्भित कॉलम में अनुक्रमणिका की आवश्यकता होगी तालिका, यदि आप कभी भी संदर्भित तालिकाओं को संशोधित करते हैं। ऐसा इसलिए है क्योंकि सर्वर को किसी त्रुटि या इस तरह को फेंकने के लिए जानने के लिए उन संदर्भित पंक्तियों का पता लगाने की आवश्यकता होती है। आप इसे विभाजित संदर्भ तालिका के साथ आसानी से कर सकते हैं:
CREATE INDEX ON stock (item_id); CREATE INDEX ON stock (warehouse_id);
इस पोस्ट में मैंने विदेशी चाबियों की मूल बातें दिखाई हैं, और उनका उपयोग विभाजित तालिकाओं पर कैसे किया जा सकता है जैसे वे नियमित तालिकाओं पर कर सकते हैं। बाद की पोस्ट में मैं उनमें से कुछ अतिरिक्त विशेषताओं को शामिल करूंगा। अगर आपको यह पोस्टग्रेएसक्यूएल 12 सुधार पसंद है तो मुझे एक टिप्पणी में बताएं!