RDBMSes नेस्टेड फॉर्मेट में टेबल्स में वापस क्यों नहीं आए?


14

उदाहरण के लिए, मान लें कि मैं एक उपयोगकर्ता और उसके सभी फोन नंबर और ईमेल पते लाना चाहता हूं। फोन नंबर और ईमेल अलग-अलग तालिकाओं में संग्रहीत हैं, एक उपयोगकर्ता से कई फोन / ईमेल। मैं यह आसानी से कर सकता हूं:

SELECT * FROM users user 
    LEFT JOIN emails email ON email.user_id=user.id
    LEFT JOIN phones phone ON phone.user_id=user.id

समस्या * इसके साथ यह है कि यह उपयोगकर्ता के नाम, DOB, पसंदीदा रंग, और उपयोगकर्ता तालिका में संग्रहीत सभी अन्य जानकारी को प्रत्येक रिकॉर्ड (उपयोगकर्ता ईमेल फोन रिकॉर्ड) के लिए फिर से जारी कर रहा है , संभवतः बैंडविड्थ खा रहा है और धीमा कर रहा है परिणाम नीचे।

यह अच्छे नहीं होगा अगर यह प्रत्येक उपयोगकर्ता के लिए एक ही पंक्ति लौट आए, और है कि रिकॉर्ड के भीतर एक था सूची और ईमेल की एक सूची फोन की? इससे डेटा को काम करना भी आसान हो जाएगा।

मुझे पता है कि आप LINQ या शायद अन्य रूपरेखाओं का उपयोग करके इस तरह के परिणाम प्राप्त कर सकते हैं, लेकिन यह संबंधपरक डेटाबेस के अंतर्निहित डिजाइन में कमजोरी लगती है।

हम NoSQL का उपयोग करके इसके चारों ओर प्राप्त कर सकते हैं, लेकिन क्या कोई बीच का मैदान नहीं होना चाहिए?

क्या मैं कुछ भूल रहा हूँ? यह मौजूद क्यों नहीं है?

* हां, इसे इस तरह से डिजाइन किया गया है। मैं समझ गया। मैं सोच रहा हूं कि ऐसा कोई विकल्प क्यों नहीं है जिसके साथ काम करना आसान हो। एसक्यूएल ऐसा कर सकता है जो वह कर रहा है, लेकिन फिर वे एक कीवर्ड या दो जोड़ सकते हैं ताकि थोड़ा बाद में प्रसंस्करण किया जा सके जो कार्टिजियन उत्पाद के बजाय डेटा को नेस्टेड प्रारूप में लौटाता है।

मुझे पता है कि यह आपकी पसंद की स्क्रिप्टिंग भाषा में किया जा सकता है, लेकिन इसके लिए यह आवश्यक है कि SQL सर्वर या तो अनावश्यक डेटा (उदाहरण के लिए नीचे) या आपको कई प्रश्न जारी करने के लिए भेजता है SELECT email FROM emails WHERE user_id IN (/* result of first query */)


इसके बजाय MySQL कुछ इस तरह से वापस आ:

[
    {
        "name": "John Smith",
        "dob": "1945-05-13",
        "fav_color": "red",
        "email": "johnsmith45@gmail.com",
    },
    {
        "name": "John Smith",
        "dob": "1945-05-13",
        "fav_color": "red",
        "email": "john@smithsunite.com",
    },
    {
        "name": "Jane Doe",
        "dob": "1953-02-19",
        "fav_color": "green",
        "email": "originaljane@deerclan.com",
    }
]

और फिर कुछ विशिष्ट पहचानकर्ता (जिसका अर्थ है कि मुझे भी प्राप्त करने की आवश्यकता है) पर समूह के लिए ग्राहक-पक्ष को परिणाम सेट करने के लिए सुधार करना है कि आप इसे कैसे चाहते हैं, बस इसे वापस करें:

[
    {
        "name": "John Smith",
        "dob": "1945-05-13",
        "fav_color": "red",
        "emails": ["johnsmith45@gmail.com", "john@smithsunite.com"]
    },
    {
        "name": "Jane Doe",
        "dob": "1953-02-19",
        "fav_color": "green",
        "emails": ["originaljane@deerclan.com"],
    }
]

वैकल्पिक रूप से, मैं 3 प्रश्नों को जारी कर सकता हूं: उपयोगकर्ताओं के लिए 1, ईमेल के लिए 1, और फोन नंबर के लिए 1, लेकिन फिर ईमेल और फोन नंबर के परिणाम सेट के लिए user_id को शामिल करने की आवश्यकता है ताकि मैं उन्हें उपयोगकर्ताओं के साथ मिलान कर सकूं मैंने पहले भ्रूण लिया था। फिर से, अनावश्यक डेटा और अनावश्यक प्रसंस्करण के बाद।


6
एसक्यूएल को स्प्रेडशीट के रूप में माइक्रोसॉफ्ट एक्सेल की तरह समझें, फिर यह पता लगाने की कोशिश करें कि सेल वैल्यू कैसे बनाई जाए जिसमें इनर सेल हो। यह अब एक स्प्रेडशीट के रूप में अच्छी तरह से काम नहीं करता है। आप जो खोज रहे हैं वह एक पेड़ की संरचना है, लेकिन तब आपको स्प्रैडशीट के लाभ नहीं मिलते हैं (यानी आप किसी पेड़ में एक कॉलम को पूरा नहीं कर सकते हैं)। पेड़ की संरचना बहुत मानवीय पठनीय रिपोर्टों के लिए नहीं बनती है।
रिएक्टगुलर सेप

54
एसक्यूएल डेटा वापस करने में बुरा नहीं है, आप जो चाहते हैं उसके लिए क्वेरी करना बुरा है। अंगूठे के एक नियम के रूप में, यदि आपको लगता है कि एक व्यापक रूप से इस्तेमाल किया जाने वाला उपकरण छोटी गाड़ी है या आम उपयोग के मामले में टूट गया है, तो समस्या यह है कि आप हैं।
शॉन मैकसोमेटिंग सेप

12
@SeanMcSomething इतना सच है कि यह दर्द होता है, मैं इसे बेहतर नहीं कह सकता था।
वर्नरसीडी

5
यह एक महान प्रश्न है। उत्तर जो कह रहे हैं "यह वह तरीका है जो बिंदु को याद कर रहा है"। पंक्तियों के एम्बेडेड संग्रह के साथ पंक्तियों को वापस करना क्यों संभव नहीं है?
क्रिस पिटमैन

8
@SeanMcSomething: जब तक कि व्यापक रूप से उपयोग किया जाने वाला उपकरण C ++ या PHP नहीं है, तब तक आप शायद सही हों। ;)
मेसन व्हीलर

जवाबों:


11

डीप डाउन, एक रिलेशनल डेटाबेस की हिम्मत, इसकी सभी पंक्तियों और स्तंभों में। यह वह संरचना है जिसके साथ काम करने के लिए एक संबंधपरक डेटाबेस को अनुकूलित किया जाता है। कर्सर एक समय में अलग-अलग पंक्तियों पर काम करते हैं। कुछ संचालन अस्थायी टेबल बनाते हैं (फिर से, इसे पंक्तियों और स्तंभों की आवश्यकता होती है)।

केवल पंक्तियों के साथ काम करने और केवल पंक्तियों को वापस करने से, सिस्टम मेमोरी और नेटवर्क ट्रैफ़िक से बेहतर तरीके से निपटने में सक्षम है।

जैसा कि उल्लेख किया गया है, यह कुछ अनुकूलन के लिए अनुमति देता है (अनुक्रमित, सम्मिलित, यूनियन, आदि ...)

अगर किसी को नेस्टेड ट्री स्ट्रक्चर चाहिए था, तो इसके लिए जरूरी है कि एक बार में सारा डेटा खींच लिया जाए। डेटाबेस पक्ष पर कर्सर के लिए अनुकूलन किया गया है। इसी तरह, नेटवर्क पर ट्रैफ़िक एक बड़ा विस्फोट बन जाता है जो पंक्ति द्वारा पंक्ति की धीमी गति की तुलना में अधिक समय ले सकता है (यह कुछ ऐसा है जो आज की वेब दुनिया में कभी-कभी खो जाता है)।

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

ऐसा नहीं है कि प्रोग्राम की भाषा के लिए किसी अन्य संरचना में लौटी पंक्तियों को परिवर्तित करना कठिन है। इसे एक पेड़ या हैश सेट में बनाएं या इसे उन पंक्तियों की सूची के रूप में छोड़ दें जिन्हें आप खत्म कर सकते हैं।

यहां काम पर भी इतिहास है। पुराने दिनों के दिनों में संरचित डेटा स्थानांतरित करना बदसूरत था। ईडीआई प्रारूप को देखें जिससे आपको यह पता चल सके कि आप क्या मांग रहे हैं। पेड़ों में भी पुनरावृत्ति होती है - जिसका कुछ भाषाओं ने समर्थन नहीं किया था (पुराने दिनों की दो सबसे महत्वपूर्ण भाषाओं ने पुनरावृत्ति का समर्थन नहीं किया था - पुनरावृत्ति ने फोर्टन में F90 तक प्रवेश नहीं किया था और COBOL के युग में भी नहीं था)।

और जबकि आज की भाषाओं में पुनरावृत्ति और अधिक उन्नत डेटा प्रकारों के लिए समर्थन है, वास्तव में चीजों को बदलने का एक अच्छा कारण नहीं है। वे काम करते हैं, और वे अच्छा काम करते हैं। जो कि कर रहे हैं चीजों को बदलने NoSQL डेटाबेस है। आप एक दस्तावेज़ पर आधारित दस्तावेज़ों में पेड़ों को स्टोर कर सकते हैं। LDAP (इसकी वास्तव में पुरानी) भी एक पेड़ आधारित प्रणाली है (हालांकि इसकी शायद आप इसके बाद नहीं हैं)। कौन जानता है, शायद nosql डेटाबेस में अगली चीज एक होगी जो क्वेरी को एक json ऑब्जेक्ट के रूप में वापस करती है।

हालांकि, 'पुराने' संबंधपरक डेटाबेस ... वे पंक्तियों के साथ काम कर रहे हैं क्योंकि यही वे अच्छे हैं और सब कुछ परेशानी या अनुवाद के बिना उनसे बात कर सकते हैं।

  1. प्रोटोकॉल डिजाइन में, पूर्णता तब तक पहुंच गई है जब जोड़ने के लिए कुछ भी नहीं बचा है, लेकिन जब लेने के लिए कुछ भी नहीं बचा है।

से बारह नेटवर्किंग सत्य - RFC 1925


"अगर किसी को नेस्टेड ट्री संरचना चाहिए थी, तो इसके लिए जरूरी है कि एक ही बार में सारा डेटा खींच लिया जाए। डेटाबेस के पक्ष में अभिशाप के लिए अनुकूलन किया गया है।" - यह सच नहीं है। यह सिर्फ एक जोड़े को बनाए रखना होगा: मुख्य तालिका के लिए एक, और फिर प्रत्येक में शामिल मेज के लिए एक। इंटरफ़ेस के आधार पर, यह एक पंक्ति में वापस आ सकता है और सभी एक चंक (आंशिक रूप से प्रवाहित) में तालिकाओं में शामिल हो गए, या यह सबट्रीस स्ट्रीम कर सकते हैं (और शायद उन्हें क्वेरी भी नहीं) जब तक आप उन्हें पुनरावृत्त करना शुरू नहीं करते। लेकिन हां, यह बहुत जटिल है।
एमपीएन

3
हर आधुनिक भाषा में किसी न किसी प्रकार का वृक्ष वर्ग होना चाहिए, नहीं? और उस से निपटने के लिए यह ड्राइवर के लिए नहीं होगा? मुझे लगता है कि SQL लोगों को अभी भी एक सामान्य प्रारूप तैयार करने की आवश्यकता है (उस बारे में ज्यादा जानकारी नहीं है)। हालांकि जो चीज मुझे मिलती है वह यह है कि मुझे या तो 1 क्वेरी को जॉइन करने के लिए भेजना है, और वापस आना है और निरर्थक डेटा को फ़िल्टर करना है जो प्रत्येक पंक्ति (उपयोगकर्ता जानकारी, जो केवल प्रत्येक एनटी पंक्ति को बदलता है), या 1 क्वेरी (उपयोगकर्ता) जारी करता है , और परिणामों पर लूप, फिर प्रत्येक रिकॉर्ड के लिए दो और क्वेरीज़ (ईमेल, फोन) भेजें जो मुझे चाहिए जानकारी प्राप्त करने के लिए। या तो विधि बेकार लगती है।
एमपीएन

51

यह वही वापस लौट रहा है जो आपने मांगा था: एक एकल रिकॉर्ड जिसमें कार्टेशियन उत्पाद शामिल है जो कि जोड़ों द्वारा परिभाषित किया गया है। वहाँ बहुत सारे वैध परिदृश्य हैं जहाँ आप यही चाहते हैं, इसलिए यह कहना कि एसक्यूएल एक बुरा परिणाम दे रहा है (और इस प्रकार यह कहना कि यदि आप इसे बदल देते हैं तो बेहतर होगा) वास्तव में बहुत सारे प्रश्नों को खत्म कर देगा।

आप जो अनुभव कर रहे हैं, उसे " ऑब्जेक्ट / रिलेशनल इम्पीडेंस मिसमैच " के रूप में जाना जाता है , जो तकनीकी कठिनाइयाँ इस तथ्य से उत्पन्न होती हैं कि ऑब्जेक्ट-ओरिएंटेड डेटा मॉडल और रिलेशनल डेटा मॉडल कई मायनों में मौलिक रूप से अलग हैं। LINQ और अन्य चौखटे (ORMs, ऑब्जेक्ट / रिलेशनल मैपर्स के रूप में जाना जाता है, संयोग से नहीं)) जादुई रूप से "इसके आसपास नहीं मिलता है;" वे सिर्फ अलग-अलग प्रश्न जारी करते हैं। इसे SQL में भी किया जा सकता है। यहाँ है कि मैं यह कैसे करूँगा:

SELECT * FROM users user where [criteria here]

उपयोगकर्ताओं की सूची में बदलाव करें और आईडी की सूची बनाएं।

SELECT * from EMAILS where user_id in (list of IDs here)
SELECT * from PHONES where user_id in (list of IDs here)

और फिर आप जॉइनिंग क्लाइंट-साइड करते हैं। यह कैसे LINQ और अन्य चौखटे यह करते हैं। इसमें कोई वास्तविक जादू शामिल नहीं है; अमूर्तता की एक परत।


14
+1 के लिए "वास्तव में आपने जो मांगा था"। बहुत बार हम इस निष्कर्ष पर पहुंचते हैं कि इस निष्कर्ष के बजाय तकनीक के साथ कुछ गड़बड़ है, हमें यह जानने की जरूरत है कि प्रौद्योगिकी का प्रभावी ढंग से उपयोग कैसे करें।
मैट

1
हाइबरनेट किसी एक क्वेरी जब में जड़ इकाई और कुछ संग्रहण पुनः प्राप्त करेगा उत्सुक लाने मोड उन संग्रहों के लिए प्रयोग किया जाता है; उस स्थिति में यह मेमोरी में रूट एंटिटी के गुणों को कम करता है। अन्य ओआरएम संभवत: ऐसा ही कर सकते हैं।
माइक पार्टरिज

3
वास्तव में यह संबंधपरक मॉडल पर दोष नहीं है। यह बहुत अच्छी तरह से नेस्टेड संबंधों के साथ मुकाबला करता है धन्यवाद। यह विशुद्ध रूप से SQL के शुरुआती संस्करणों में एक कार्यान्वयन बग है। मुझे लगता है कि हाल के संस्करणों ने इसे जोड़ा है।
जॉन निल्सन

8
क्या आप सुनिश्चित हैं कि यह वस्तु-संबंधपरक प्रतिबाधा का एक उदाहरण है? मुझे लगता है कि संबंधपरक मॉडल पूरी तरह से ओपी के वैचारिक डेटा मॉडल से मेल खाता है: प्रत्येक उपयोगकर्ता शून्य, एक, या अधिक ईमेल पतों की सूची के साथ जुड़ा हुआ है। वह मॉडल OO प्रतिमान (एकत्रीकरण: उपयोगकर्ता ऑब्जेक्ट में ईमेल का संग्रह) में भी पूरी तरह से प्रयोग करने योग्य है। सीमा डेटाबेस को क्वेरी करने के लिए उपयोग की जा रही तकनीक में है, जो एक कार्यान्वयन विवरण है। ऐसी क्वेरी तकनीकें हैं जिनके चारों ओर उत्तराधिकारी डेटा लौटाया जाता है, जैसे .Net में डेटास्क्रेटिक डेटासेट्स
मार्कज

@MarkJ आपको उत्तर के रूप में लिखना चाहिए।
मि। मिंडोर

12

आप अभिलेखों को एक साथ जोड़ने के लिए एक अंतर्निहित फ़ंक्शन का उपयोग कर सकते हैं। MySQL में आप GROUP_CONCAT()फ़ंक्शन का उपयोग कर सकते हैं और Oracle में आप LISTAGG()फ़ंक्शन का उपयोग कर सकते हैं ।

यहाँ एक नमूना है जो MySQL में एक क्वेरी जैसा दिख सकता है:

SELECT user.*, 
    (SELECT GROUP_CONCAT(DISTINCT emailAddy) FROM emails email WHERE email.user_id = user.id
    ) AS EmailAddresses,
    (SELECT GROUP_CONCAT(DISTINCT phoneNumber) FROM phones phone WHERE phone.user_id = user.id
    ) AS PhoneNumbers
FROM users user 

यह कुछ इस तरह लौटेगा

username    department       EmailAddresses                        PhoneNumbers
Tim_Burton  Human Resources  hr@m.com, tb@me.com, nunya@what.com   231-123-1234, 231-123-1235

यह ओपी क्या करने का प्रयास कर रहा है (एसक्यूएल में) निकटतम समाधान प्रतीत होता है। वह संभावित रूप से अभी भी क्लाइंट साइड प्रोसेसिंग करने के लिए ईमेलएड्रेस और फोनअनुल का परिणाम सूची में तोड़ देगा।
Mr.Mindor

2
क्या होगा अगर फोन नंबर में "सेल", "होम", या "वर्क" की तरह "टाइप" हो? इसके अलावा, ईमेल पते में अल्पविराम को तकनीकी रूप से अनुमति दी जाती है (यदि उन्हें उद्धृत किया जाता है) - मैं इसे फिर कैसे विभाजित करूंगा?
एमपीएन

10

इसके साथ समस्या यह है कि यह उपयोगकर्ता का नाम, DOB, पसंदीदा रंग, और अन्य सभी संग्रहीत जानकारी लौटा रहा है

समस्या यह है कि आप पर्याप्त रूप से चयनात्मक नहीं हो रहे हैं। आप के लिए कहा सब कुछ है जब आप ने कहा

Select * from...

... और आपको यह मिल गया (डीओबी और पसंदीदा रंगों सहित)।

आपको शायद थोड़ा और (अहम) होना चाहिए ... चयनात्मक, और कुछ इस तरह कहा:

select users.name, emails.email_address, phones.home_phone, phones.bus_phone
from...

यह भी संभव है कि आप रिकॉर्ड देख सकते हैं जो डुप्लिकेट की तरह दिखते हैं क्योंकि userकई emailरिकॉर्ड में शामिल हो सकते हैं , लेकिन इन दोनों को अलग करने वाला क्षेत्र आपके Selectबयान में नहीं है , इसलिए आप कुछ ऐसा कहना चाहते हैं

select distinct users.name, emails.email_address, phones.home_phone, phones.bus_phone
from...

... प्रत्येक रिकॉर्ड के लिए बार-बार ...

इसके अलावा, मुझे लगता है आप कर रहे हैं नोटिस LEFT JOIN। यह जॉइन (यानी users) के बाईं ओर सभी रिकॉर्ड्स को दाईं ओर सभी रिकॉर्ड्स में शामिल करेगा, या दूसरे शब्दों में:

एक बाएं बाहरी जुड़ाव एक आंतरिक जोड़ से सभी मानों को छोड़ देता है और बाईं तालिका में सभी मान शामिल होते हैं जो सही तालिका से मेल नहीं खाते हैं।

( http://en.wikipedia.org/wiki/Join_(SQL)#Left_outer_join )

तो एक और सवाल यह है कि क्या आपको वास्तव में एक लेफ्ट जॉइन की जरूरत है, या INNER JOINपर्याप्त है? वे बहुत अलग प्रकार के जोड़ हैं।

यदि यह प्रत्येक उपयोगकर्ता के लिए एकल पंक्ति लौटाया गया, तो यह अच्छा नहीं होगा और उस रिकॉर्ड के भीतर ईमेल की एक सूची थी

यदि आप वास्तव में परिणाम की सूची के भीतर एकल-स्तंभ चाहते हैं, जिसमें एक सूची है जो कि मक्खी से उत्पन्न होती है, तो यह किया जा सकता है लेकिन यह इस बात पर निर्भर करता है कि आप किस डेटाबेस का उपयोग कर रहे हैं। Oracle का listaggकार्य है


अंत में, मुझे लगता है कि यदि आप अपनी क्वेरी को इस तरह से कुछ के करीब लिख देते हैं, तो आपकी समस्या हल हो सकती है:

select distinct users.name, users.id, emails.email_address, phones.phone_number
from users
  inner join emails on users.user_id = emails.user_id
  inner join phones on users.user_id = phones.user_id

1
* का उपयोग कर हतोत्साहित किया गया है, लेकिन उसकी समस्या का नहीं। यहां तक ​​कि अगर वह 0 उपयोगकर्ता कॉलम का चयन करता है, तो वह अभी भी दोहराव प्रभाव का अनुभव कर सकता है क्योंकि फ़ोन और ईमेल दोनों उपयोगकर्ताओं के लिए 1-कई संबंध हैं। विशिष्ट फ़ोन नंबर को दो बार ala phone1/name@hotmail.com, phone1/name@google.com पर प्रदर्शित होने से नहीं रोक सकेगा।
माइक 30

6
-1: "आपकी समस्या हो सकता है हल किया जा" का कहना है कि आप क्या प्रभाव होगा से परिवर्तन नहीं जानते left joinकरने के लिए inner join। इस मामले में, यह "दोहराव" को कम नहीं करेगा, जिसके बारे में उपयोगकर्ता शिकायत कर रहा है; यह केवल उन उपयोगकर्ताओं को छोड़ देगा जिनके पास फोन या ईमेल की कमी है। शायद ही कोई सुधार हो। इसके अलावा, जब दाईं ओर "सभी रिकॉर्ड बाईं ओर सभी रिकॉर्ड्स" की व्याख्या करते हैं, तो ONमानदंड को छोड़ देता है, जो कार्टेशियन उत्पाद में निहित सभी 'गलत' संबंधों की प्रशंसा करता है, लेकिन सभी दोहराए गए क्षेत्रों को रखता है।
जेवियर

@ जेवियर: हां, यही कारण है कि मैंने भी कहा कि क्या आपको वास्तव में एक लेफ्ट जॉइन की जरूरत है, या एक INNER JOIN पर्याप्त है? * ओपी की समस्या का वर्णन यह * ध्वनि बनाता है जैसे कि वे एक आंतरिक जुड़ाव के परिणाम की उम्मीद कर रहे थे। बेशक, बिना किसी सैंपल डेटा या किसी विवरण के कि वे वास्तव में क्या चाहते थे, यह कहना मुश्किल है। मैंने सुझाव दिया क्योंकि मैंने वास्तव में लोगों को देखा है (जिनके साथ मैं काम करता हूं) ऐसा करते हैं: गलत जुड़ाव का चयन करें और फिर शिकायत करें कि जब वे परिणाम प्राप्त नहीं करते हैं। इसे देखने के बाद , मुझे लगा कि शायद यहीं हुआ है।
FrustratedWithFormsDesigner

3
आप प्रश्न के बिंदु को याद कर रहे हैं। इस काल्पनिक उदाहरण में, मैं चाहता हूँ सभी उपयोगकर्ता डेटा (नाम, जन्म तिथि, आदि) और मैं सभी उसकी / उसके फोन नंबर चाहते हैं। इनर जॉइन में यूजर्स को w / नो ईमेल या कोई फोन शामिल नहीं है - यह कैसे मदद करता है?
mpen

4

क्वेरी हमेशा डेटा का एक आयताकार (संयुक्त-दांतेदार) सारणी सेट उत्पन्न करती है। सेट के भीतर कोई नेस्टेड उप-सेट नहीं हैं। सेट की दुनिया में सब कुछ एक शुद्ध संयुक्त राष्ट्र नेस्टेड आयत है।

आप 2 सेट को साथ-साथ रखकर एक जुड़ाव के बारे में सोच सकते हैं। "चालू" स्थिति यह है कि प्रत्येक सेट में रिकॉर्ड का मिलान कैसे किया जाता है। यदि किसी उपयोगकर्ता के पास 3 फ़ोन नंबर हैं, तो आपको उपयोगकर्ता जानकारी में 3-बार दोहराव दिखाई देगा। एक आयताकार संयुक्त-दांतेदार सेट को क्वेरी द्वारा निर्मित किया जाना चाहिए। यह बस 1-से-कई संबंधों के साथ सेट में शामिल होने की प्रकृति है।

आप जो चाहते हैं उसे पाने के लिए, आपको एक अलग क्वेरी का उपयोग करना होगा जैसे कि मेसन व्हीलर वर्णित है।

select * from Phones where user_id=344;

इस क्वेरी का परिणाम अभी भी एक आयताकार संयुक्त-दांतेदार सेट है। जैसा कि सेट की दुनिया में सब कुछ है।


2

आपको तय करना होगा कि अड़चनें कहां हैं। आपके डेटाबेस और एप्लिकेशन के बीच बैंडविड्थ आमतौर पर बहुत तेज है। कोई कारण नहीं है कि अधिकांश डेटाबेस एक कॉल और 3 जॉइन के भीतर 3 अलग-अलग डेटासेट वापस नहीं कर सके। फिर आप चाहें तो इसे अपने ऐप में शामिल कर सकते हैं।

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


"कोई कारण नहीं है कि अधिकांश डेटाबेस एक कॉल में 3 अलग-अलग डेटासेट वापस नहीं ला सकते हैं और कोई जोड़ नहीं है" - एक कॉल के साथ 3 अलग डेटासेट वापस करने के लिए आपको यह कैसे मिलता है? मुझे लगा कि आपको 3 अलग-अलग प्रश्न भेजने थे, जो प्रत्येक के बीच विलंबता का परिचय देता है?
एमपीएन

एक संग्रहीत प्रक्रिया को 1 लेनदेन में बुलाया जा सकता है, और फिर आप जितने चाहें उतने डेटासेट वापस कर सकते हैं। शायद "SelectUserWithEmailsPhones" स्पोक की आवश्यकता है।
ग्राहम

1
@ मर्क: आप एक ही बैच के एक हिस्से में कम से कम (sql सर्वर में) एक से अधिक कमांड भेज सकते हैं। cmdText = "b से * सेलेक्ट *; a से सेलेक्ट * का चयन करें, c से * का चयन करें और फिर sqlcommand के लिए कमांड टेक्स्ट के रूप में उपयोग करें।
6

2

यदि आप उपयोगकर्ता क्वेरी और फ़ोन नंबर क्वेरी के लिए अलग-अलग परिणाम चाहते हैं, तो बहुत ही सरलता से, अपने डेटा से जुड़ें नहीं, अन्यथा जैसा कि अन्य लोगों ने "सेट" किया है या डेटा में प्रत्येक पंक्ति के लिए अतिरिक्त फ़ील्ड होंगे।

एक जुड़ने के साथ एक के बजाय 2 अलग-अलग प्रश्न जारी करें।

संग्रहीत कार्यविधि या इनलाइन पैरामीटराइज्ड एसक्यूएल क्राफ्ट 2 प्रश्नों में और दोनों के परिणाम वापस करते हैं। अधिकांश डेटाबेस और भाषाएं कई परिणाम सेट का समर्थन करती हैं।

उदाहरण के लिए, SQL सर्वर और C # का उपयोग करके कार्यक्षमता को पूरा करता है IDataReader.NextResult()


1

आप कुछ याद कर रहे हैं। यदि आप अपने डेटा को अलग करना चाहते हैं, तो आपको इसे स्वयं करना होगा।

;with toList as (
    select  *, Stuff(( select ',' + (phone.phoneType + ':' + phone.PhoneNumber) 
                    from phones phone
                    where phone.user_id = user.user_id
                    for xml path('')
                  ), 1,1,'') as phoneNumbers
from users user
)
select *
from toList

1

मूल रूप से संबंधपरक बंद की अवधारणा का मतलब है कि किसी भी प्रश्न का परिणाम एक ऐसा संबंध है जो अन्य प्रश्नों में इस्तेमाल किया जा सकता है जैसे कि यह एक आधार तालिका थी। यह एक शक्तिशाली अवधारणा है क्योंकि यह प्रश्नों को रचना योग्य बनाती है।

यदि SQL ने आपको क्वेरीज़ लिखने की अनुमति दी है जो डेटा संरचनाओं को नेस्टेड करता है, तो आप इस सिद्धांत को तोड़ देंगे। एक नेस्टेड डेटा संरचना एक संबंध नहीं है, इसलिए आपको इसे आगे क्वेरी करने के लिए या अन्य संबंधों में शामिल होने के लिए, SQL को एक नई क्वेरी भाषा या जटिल एक्सटेंशन की आवश्यकता होगी।

मूल रूप से आप एक संबंधपरक DBMS के शीर्ष पर एक पदानुक्रमित DBMS का निर्माण करेंगे। यह एक संदिग्ध लाभ के लिए बहुत अधिक जटिल होगा, और आप लगातार रिलेशनल सिस्टम के फायदे खो देते हैं।

मैं समझता हूं कि यह एसक्यूएल से पदानुक्रम से संरचित डेटा को सक्षम करने के लिए कभी-कभी सुविधाजनक क्यों होगा, लेकिन इसका समर्थन करने के लिए डीबीएमएस में जोड़ा जटिलता में लागत निश्चित रूप से इसके लायक नहीं है।


-4

Pls STUFF फ़ंक्शन के उपयोग को संदर्भित करता है जो एक स्तंभ (संपर्क) के कई पंक्तियों (फोन नंबर) को समूह करता है जिसे एक पंक्ति (उपयोगकर्ता) के सीमांकित मानों के एकल कक्ष के रूप में निकाला जा सकता है।

आज हम बड़े पैमाने पर इसका उपयोग कर रहे हैं लेकिन कुछ उच्च CPU और प्रदर्शन समस्याओं का सामना कर रहे हैं। XML डेटा प्रकार एक और विकल्प है, लेकिन एक डिज़ाइन परिवर्तन है जो क्वेरी स्तर एक नहीं है।


5
कृपया इस पर विस्तार करें कि यह प्रश्न कैसे हल करता है। "Pls के उपयोग के संदर्भ में" कहने के बजाय, यह पूछे जाने वाले प्रश्न को कैसे प्राप्त किया जाएगा, इसका एक उदाहरण प्रदान करें। यह 3 पार्टी स्रोतों को उद्धृत करने में भी सहायक हो सकता है जहां यह चीजों को स्पष्ट करता है।
बिट्सफ्लॉजिक जूल

1
लगता STUFFहै बंटवारे के समान है। निश्चित नहीं कि यह मेरे प्रश्न पर कैसे लागू होता है।
म्पेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.