संपादित करें :तो, मैंने नीचे प्रश्न लिखा और फिर सोचा... "रुको, Postgresql के लिए आवश्यक है कि विदेशी प्रमुख लक्ष्यों में अद्वितीय सूचकांक हों।" तो मुझे लगता है कि मैंने गलत समझा कि आपका क्या मतलब है? आप नीचे दी गई क्वेरी का उपयोग यह जांचने के लिए कर सकते हैं कि स्रोत आपकी विदेशी कुंजियों में "confrelid" के लिए "conrelid" और "confkey" के लिए "conkey" को प्रतिस्थापित करके सूचकांक हैं (हाँ, हाँ, क्वेरी में कोई उपनाम नहीं है...)
ठीक है, मुझे लगता है कि सिस्टम कैटलॉग के माध्यम से जाना संभव होना चाहिए ... हमेशा की तरह, सिस्टम कैटलॉग के लिए सबसे अच्छा गाइड psql का उपयोग करना और "\ सेट ECHO_HIDDEN 1" करना है और फिर देखें कि यह दिलचस्प के लिए कौन सा SQL उत्पन्न करता है "\ डी" कमांड। तालिका ("\d tablename") के लिए विदेशी कुंजियों को खोजने के लिए उपयोग किया जाने वाला SQL यहां दिया गया है:
-- $1 is the table OID, e.g. 'tablename'::regclass
SELECT conname, conrelid::pg_catalog.regclass,
pg_catalog.pg_get_constraintdef(c.oid, true) as condef
FROM pg_catalog.pg_constraint c
WHERE c.confrelid = $1 AND c.contype = 'f' ORDER BY 1;
ऐसा लगता है कि pg_constraint में कॉलम conkey
हैं और confkey
ऐसा लगता है कि वे कॉलम संख्याएं हो सकती हैं जिन्हें कुंजी को परिभाषित किया गया है। शायद confkey
विदेशी तालिका में स्तंभ संख्या है क्योंकि यह विदेशी कुंजी के लिए केवल गैर-शून्य है। साथ ही, मुझे यह महसूस करने में थोड़ा समय लगा कि यह विदेशी कुंजी दिखाने के लिए SQL है संदर्भित दी गई तालिका। वैसे भी हम यही चाहते हैं।
तो कुछ इस क्वेरी से पता चलता है कि डेटा आकार लेना शुरू कर रहा है:
select confrelid, conname, column_index, attname
from pg_attribute
join (select confrelid::regclass, conname, unnest(confkey) as column_index
from pg_constraint
where confrelid = 'ticket_status'::regclass) fkey
on fkey.confrelid = pg_attribute.attrelid
and fkey.column_index = pg_attribute.attnum
मैं अननेस्ट जैसी 8.4 सुविधाओं का उपयोग करने जा रहा हूं ... आप इसके बिना भी साथ रह सकते हैं।
मैं इसके साथ समाप्त हुआ:
select pg_index.indexrelid::regclass, 'create index ' || relname || '_' ||
array_to_string(column_name_list, '_') || '_idx on ' || confrelid ||
' (' || array_to_string(column_name_list, ',') || ')'
from (select distinct
confrelid,
array_agg(attname) column_name_list,
array_agg(attnum) as column_list
from pg_attribute
join (select confrelid::regclass,
conname,
unnest(confkey) as column_index
from (select distinct
confrelid, conname, confkey
from pg_constraint
join pg_class on pg_class.oid = pg_constraint.confrelid
join pg_namespace on pg_namespace.oid = pg_class.relnamespace
where nspname !~ '^pg_' and nspname <> 'information_schema'
) fkey
) fkey
on fkey.confrelid = pg_attribute.attrelid
and fkey.column_index = pg_attribute.attnum
group by confrelid, conname
) candidate_index
join pg_class on pg_class.oid = candidate_index.confrelid
left join pg_index on pg_index.indrelid = confrelid
and indkey::text = array_to_string(column_list, ' ')
ठीक है, यह राक्षसी उम्मीदवार इंडेक्स कमांड को प्रिंट करता है और उन्हें मौजूदा इंडेक्स के साथ मिलाने की कोशिश करता है। तो आप अंत में "जहाँ indexrelid शून्य है" जोड़ सकते हैं ताकि कमांड को ऐसे इंडेक्स बनाने के लिए प्राप्त किया जा सके जो मौजूद नहीं हैं।
यह क्वेरी बहु-स्तंभ विदेशी कुंजियों से बहुत अच्छी तरह निपटती नहीं है; लेकिन इम्हो यदि आप उनका उपयोग कर रहे हैं, तो आप परेशानी के पात्र हैं।
बाद में संपादित करें :यहां शीर्ष पर प्रस्तावित संपादन के साथ क्वेरी है। तो यह उन स्तंभों पर सूचकांक बनाने के लिए आदेश दिखाता है जो मौजूद नहीं हैं, जो एक विदेशी कुंजी का स्रोत हैं (इसका लक्ष्य नहीं)।
select pg_index.indexrelid::regclass, 'create index ' || relname || '_' ||
array_to_string(column_name_list, '_') || '_idx on ' || conrelid ||
' (' || array_to_string(column_name_list, ',') || ')'
from (select distinct
conrelid,
array_agg(attname) column_name_list,
array_agg(attnum) as column_list
from pg_attribute
join (select conrelid::regclass,
conname,
unnest(conkey) as column_index
from (select distinct
conrelid, conname, conkey
from pg_constraint
join pg_class on pg_class.oid = pg_constraint.conrelid
join pg_namespace on pg_namespace.oid = pg_class.relnamespace
where nspname !~ '^pg_' and nspname <> 'information_schema'
) fkey
) fkey
on fkey.conrelid = pg_attribute.attrelid
and fkey.column_index = pg_attribute.attnum
group by conrelid, conname
) candidate_index
join pg_class on pg_class.oid = candidate_index.conrelid
left join pg_index on pg_index.indrelid = conrelid
and indkey::text = array_to_string(column_list, ' ')
where indexrelid is null
मेरा अनुभव यह है कि यह वास्तव में इतना उपयोगी नहीं है। यह संदर्भ कोड जैसी चीजों के लिए सूचकांक बनाने का सुझाव देता है जिन्हें वास्तव में अनुक्रमित करने की आवश्यकता नहीं होती है।