PostgreSQL में कर्सर के बारे में हमारे पिछले लेख में, हमने ओमोन सक्षम एक्सप्रेशंस (सीटीई) के बारे में बात की थी। आज, हम पोस्टग्रेएसक्यूएल की कम ज्ञात विशेषता का उपयोग करके कर्सर के लिए नए विकल्प खोजना जारी रखते हैं।
हम उस डेटा का उपयोग करेंगे जो हमने पिछले लेख (ऊपर लिंक) में आयात किया था। मैं आपके लिए वहां की प्रक्रिया का पालन करने के लिए एक क्षण प्रतीक्षा करूंगा।
मिला क्या? ठीक है।
डेटा प्राकृतिक दुनिया का एक वर्गीकरण चार्ट है। बेसिक हाई स्कूल बायोलॉजी से एक अनुस्मारक के रूप में, कार्ल लिनिअस द्वारा डेटा को किंगडम, फाइलम, क्लास, ऑर्डर, फैमिली, जीनस और स्पीशीज़ में व्यवस्थित किया जाता है। बेशक, पिछले 250 वर्षों में विज्ञान इतना थोड़ा आगे बढ़ा है, इसलिए टैक्सोनॉमिक चार्ट 21 स्तर गहरा है। हम पदानुक्रम ट्री को एक तालिका में पाते हैं जिसे (आश्चर्यजनक रूप से) itis.hierarchy कहा जाता है ।
इस लेख का विषय है कि PostgreSQL में ltrees का उपयोग कैसे करें। विशेष रूप से, एक जटिल रिकॉर्डसेट को बहुत कुशलता से पार करने के लिए उनका उपयोग कैसे करें। उस अर्थ में, हम उन्हें कर्सर के लिए एक और सरोगेट मान सकते हैं।
डेटा को एक ltree प्रारूप में (दुर्भाग्य से हमारे लिए) क्यूरेट नहीं किया गया है, इसलिए हम लेख के लिए इसे थोड़ा बदलने जा रहे हैं।
सबसे पहले, आपको उस डेटाबेस में ltree स्थापित करना होगा जिसका उपयोग आप इस आलेख का पालन करने के लिए कर रहे हैं। बेशक, एक्सटेंशन इंस्टॉल करने के लिए आपको एक सुपर उपयोगकर्ता होने की आवश्यकता है।
CREATE EXTENSION IF NOT EXISTS ltree;
अब हम कुछ बहुत ही कुशल लुकअप प्रदान करने के लिए इस एक्सटेंशन का उपयोग करेंगे। हमें डेटा को लुकअप टेबल में बदलने की जरूरत है। इस परिवर्तन को करने के लिए, हम सीटीई तकनीक का उपयोग करने जा रहे हैं जिसे हमने पिछले लेख में शामिल किया था। साथ ही, हम टैक्सोनॉमी ट्री में लैटिन नाम और अंग्रेजी नाम जोड़ने जा रहे हैं। इससे हमें संख्या, लैटिन नामों या अंग्रेजी नामों से आइटम देखने में मदद मिलेगी।
-- We need a little helper function to strip out illegal label names.
CREATE OR REPLACE FUNCTION strip_label(thelabel text)
RETURNS TEXT
AS $$
-- make sure all the characters in the label are legal
SELECT SELECT
regexp_replace(
regexp_replace(
regexp_replace(
regexp_replace(
-- strip anything not alnum (yes, this could be way more accurate)
thelabel, '[^[:alnum:]]', '_','g'),
-- consolidate underscores
'_+', '_', 'g'),
-- strip leading/trailing underscores
'^_*', '', 'g'),
'_*$', '', 'g');
$$
LANGUAGE sql;
CREATE MATERIALIZED VIEW itis.world_view AS
WITH RECURSIVE world AS (
-- Start with the basic kingdoms
SELECT h1.tsn, h1.parent_tsn, h1.tsn::text numeric_taxonomy,
-- There is no guarantee that there will be a textual name
COALESCE(l1.completename,h1.tsn::text,'')::text latin_taxonomy,
-- and again no guarantee of a common english name
COALESCE(v1.vernacular_name, lower(l1.completename),h1.tsn::text,'unk')::text english_taxonomy
FROM itis.hierarchy h1
LEFT JOIN itis.longnames l1
ON h1.tsn = l1.tsn
LEFT JOIN itis.vernaculars v1
ON (h1.tsn, 'English') = (v1.tsn, v1.language)
WHERE h1.parent_tsn = 0
UNION ALL
SELECT h1.tsn, h1.parent_tsn, w1.numeric_taxonomy || '.' || h1.tsn,
w1.latin_taxonomy || '.' || COALESCE(strip_label(l1.completename), h1.tsn::text,'unk'),
w1.english_taxonomy || '.' || strip_label(COALESCE(v1.vernacular_name, lower(l1.completename), h1.tsn::text, 'unk'))
FROM itis.hierarchy h1
JOIN world w1
ON h1.parent_tsn = w1.tsn
LEFT JOIN itis.longnames l1
ON h1.tsn = l1.tsn
LEFT JOIN -- just change this to "itis.vernaculars v1" to allow mulitples and all languages. (Millions of records.)
(SELECT tsn, min(vernacular_name) vernacular_name FROM itis.vernaculars WHERE language = 'English' GROUP BY tsn) v1
ON (h1.tsn) = (v1.tsn)
)
SELECT w2.tsn, w2.parent_tsn, w2.numeric_taxonomy::ltree, w2.latin_taxonomy::ltree latin_taxonomy, w2.english_taxonomy::ltree english_taxonomy
FROM world w2
ORDER BY w2.numeric_taxonomy
WITH NO DATA;
आइए एक पल के लिए रुकें और इस प्रश्न में फूलों को सूंघें। शुरुआत के लिए, हमने इसे बिना किसी डेटा को पॉप्युलेट किए बनाया है। यह हमें बहुत सारे बेकार डेटा उत्पन्न करने से पहले किसी भी वाक्यात्मक मुद्दों का ध्यान रखने का मौका देता है। हम यहां एक बहुत गहरी संरचना को एक साथ रखने के लिए सामान्य तालिका अभिव्यक्ति की पुनरावृत्ति प्रकृति का उपयोग कर रहे हैं, और हम स्थानीय भाषा तालिका में डेटा जोड़कर अधिक भाषाओं को कवर करने के लिए इसे आसानी से बढ़ा सकते हैं। भौतिक दृश्य में कुछ दिलचस्प प्रदर्शन विशेषताएं भी हैं। जब भी कोई REFRESH MATERIALIZED VIEW होगा, तो यह तालिका को छोटा कर देगा और उसका पुनर्निर्माण करेगा कहा जाता है।
हम आगे जो करने जा रहे हैं वह हमारे विश्व दृष्टिकोण को ताज़ा करेगा। ज्यादातर इसलिए क्योंकि समय-समय पर ऐसा करना सेहत के लिए फायदेमंद होता है। लेकिन इस मामले में, यह वास्तव में क्या करता है itis . के डेटा के साथ भौतिक दृश्य को पॉप्युलेट करता है स्कीमा।
REFRESH MATERIALIZED VIEW itis.world_view; डेटा से 600K+ पंक्तियां बनाने में कुछ मिनट लगेंगे।
पहली कुछ पंक्तियाँ इस तरह दिखाई देंगी:
┌────────────┬─────────┬───────────────────────────────────────────────────────────────────────────────┐
│ parent_tsn │ tsn │ english_taxonomy │
├────────────┼─────────┼───────────────────────────────────────────────────────────────────────────────┤
│ 768374 │ 1009037 │ animals.bilateria.protostomia.ecdysozoa.arthropods.hexapods.insects.winged_in…│
│ │ │…sects.modern_wing_folding_insects.holometabola.ants.ants.aculeata.apoid_wasps…│
│ │ │….cicadakillers.crabroninae.larrini.gastrosericina.gastrosericus.gastrosericus…│
│ │ │…_xanthophilus │
│ 768374 │ 1009038 │ animals.bilateria.protostomia.ecdysozoa.arthropods.hexapods.insects.winged_in…│
│ │ │…sects.modern_wing_folding_insects.holometabola.ants.ants.aculeata.apoid_wasps…│
│ │ │….cicadakillers.crabroninae.larrini.gastrosericina.gastrosericus.gastrosericus…│
│ │ │…_zoyphion │
│ 768374 │ 1009039 │ animals.bilateria.protostomia.ecdysozoa.arthropods.hexapods.insects.winged_in…│
│ │ │…sects.modern_wing_folding_insects.holometabola.ants.ants.aculeata.apoid_wasps…│
│ │ │….cicadakillers.crabroninae.larrini.gastrosericina.gastrosericus.gastrosericus…│
│ │ │…_zyx │
│ 768216 │ 768387 │ animals.bilateria.protostomia.ecdysozoa.arthropods.hexapods.insects.winged_in…│
│ │ │…sects.modern_wing_folding_insects.holometabola.ants.ants.aculeata.apoid_wasps…│
│ │ │….cicadakillers.crabroninae.larrini.gastrosericina.holotachysphex │
│ 768387 │ 1009040 │ animals.bilateria.protostomia.ecdysozoa.arthropods.hexapods.insects.winged_in…│
│ │ │…sects.modern_wing_folding_insects.holometabola.ants.ants.aculeata.apoid_wasps…│
│ │ │….cicadakillers.crabroninae.larrini.gastrosericina.holotachysphex.holotachysph…│
│ │ │…ex_holognathus │
└────────────┴─────────┴───────────────────────────────────────────────────────────────────────────────┘ एक वर्गीकरण में, ग्राफ़ कुछ इस तरह दिखाई देगा:
बेशक, यह वास्तव में 21 स्तर गहरा होगा, और कुल 600K+ रिकॉर्ड होगा।
अब हम मज़ेदार हिस्से पर आते हैं! ltrees पदानुक्रम पर कुछ बहुत ही जटिल प्रश्नों को करने का एक तरीका प्रदान करते हैं। इसके लिए मदद PostgreSQL के दस्तावेज़ीकरण में है, इसलिए हम यहाँ इसकी गहराई से चर्चा नहीं करेंगे। (बहुत तेज़) समझ के लिए, एक ltree के प्रत्येक खंड को एक लेबल कहा जाता है। तो, यह ltree kingdom.phylum.class.order.family.genus.species 7 लेबल हैं।
किसी ltree के विरुद्ध क्वेरीज़ एक विशेष संकेतन का उपयोग करती हैं जो एक सीमित रूप में रेगुलर एक्सप्रेशन की तरह होता है।
यहां एक सरल उदाहरण दिया गया है:Animalia.*.Homo_sapiens
तो दुनिया में मानवता को खोजने के लिए एक प्रश्न इस तरह दिखेगा:
SELECT tsn, parent_tsn, latin_taxonomy, english_taxonomy
FROM itis.world_view WHERE latin_taxonomy ~ 'Animalia.*.Homo_sapiens'; जिसके परिणाम अपेक्षित हैं:
┌────────┬────────────┬────────────────────────────────────────────────┬─────────────────────────────────────────────┐
│ tsn │ parent_tsn │ latin_taxonomy │ english_taxonomy │
├────────┼────────────┼────────────────────────────────────────────────┼─────────────────────────────────────────────┤
│ 180092 │ 180091 │ Animalia.Bilateria.Deuterostomia.Chordata.Vert…│ animals.bilateria.deuterostomia.chordates.v…│
│ │ │…ebrata.Gnathostomata.Tetrapoda.Mammalia.Theria…│…ertebrates.gnathostomata.tetrapoda.mammals.…│
│ │ │….Eutheria.Primates.Haplorrhini.Simiiformes.Hom…│…theria.eutheria.primates.haplorrhini.simiif…│
│ │ │…inoidea.Hominidae.Homininae.Homo.Homo_sapiens │…ormes.hominoidea.Great_Apes.African_apes.ho…│
│ │ │ │…minoids.Human │
└────────┴────────────┴────────────────────────────────────────────────┴─────────────────────────────────────────────┘ बेशक, PostgreSQL इसे कभी नहीं छोड़ेगा। ऑपरेटरों, इंडेक्स, ट्रांसफॉर्मेशन और उदाहरणों का एक व्यापक सेट है।
क्षमताओं की विशाल श्रृंखला पर एक नज़र डालें जिसे यह तकनीक अनलॉक करती है।
अब कल्पना करें कि यह तकनीक अन्य जटिल डेटा प्रकारों जैसे कि भाग संख्या, वाहन पहचान संख्या, सामग्री संरचनाओं के बिल या किसी अन्य वर्गीकरण प्रणाली पर लागू होती है। इस संरचना को सीधे उपयोग करने के लिए निषेधात्मक रूप से जटिल सीखने की अवस्था के कारण अंतिम उपयोगकर्ता के लिए इस संरचना को उजागर करना आवश्यक नहीं है। लेकिन इस तरह की संरचना के आधार पर "लुकअप" स्क्रीन बनाना पूरी तरह से संभव है जो बहुत शक्तिशाली है और कार्यान्वयन की जटिलता को छुपाता है।
श्रृंखला में हमारे अगले लेख के लिए, हम भाषाओं में प्लग के उपयोग की खोज करेंगे। PostgreSQL में कर्सर के विकल्प खोजने के संदर्भ में, हम डेटा को अपनी आवश्यकताओं के लिए सबसे उपयुक्त तरीके से मॉडल करने के लिए अपनी पसंद की भाषा का उपयोग करेंगे। अगली बार मिलते हैं!