GraphQL के बजाय SQL का उपयोग क्यों नहीं करते?


20

हाल ही में मैंने ग्राफ़कॉल के बारे में सीखा जो कि रेस्टफुल से बेहतर होने का दावा करता है। हालाँकि, मैं सोचने लगा कि हम SQL बयानों को HTTP GET अनुरोध में क्यों नहीं डालते।

उदाहरण के लिए, GraphQL में मैं लिखूंगा

{
  Movie(id: "cixos5gtq0ogi0126tvekxo27") {
    id
    title
    actors {
      name
    }
  }
}

जो अपने SQL समकक्ष की तुलना में ज्यादा सरल नहीं है

SELECT id, title FROM movies WHERE id = cixos5gtq0ogi0126tvekxo27;
SELECT actors.name FROM actors, actors_movies WHERE actors.id == movies.actor_id AND movie.id == cixos5gtq0ogi0126tvekxo27;

हो सकता है कि हम क्वेरी को एनकोड कर सकते हैं और सर्वर को भेज सकते हैं

GET endpoint?q=SELECT%20id%2C%20title%20FROM%20movies%20WHERE%20id%20%3D%20cixos5gtq0ogi0126tvekxo27%3B%0ASELECT%20actors.name%20FROM%20actors%2C%20actors_movies%20WHERE%20actors.id%20%3D%3D%20movies.actor_id%20AND%20movie.id%20%3D%3D%20cixos5gtq0ogi0126tvekxo27%3B HTTP/1.1

हां, क्वेरी URL बहुत लंबा हो सकता है, लेकिन यदि आप REST अनुपालन की परवाह नहीं करते हैं, तो आप इसे POST अनुरोध के मुख्य भाग में रख सकते हैं। (वैसे, मुझे लगता है कि समझ बनाने के लिए HTTP RFC को REST के लिए संशोधित किया जाना चाहिए: क्वेरी स्ट्रिंग्स की लंबाई को मिलाते हुए शुरुआत में विनिर्देश के साथ कार्यान्वयन को मिलाया जाता है)

क्लाइंट से सीधे SQL जारी करने का भी फायदा है

  1. विकास के समय को कम करते हुए, ग्राफक्यूएल को पार्स करने के लिए किसी सर्वर-साइड कोड / लाइब्रेरी की आवश्यकता नहीं है।
  2. कोई भी सर्वर-साइड ओवरहेड को ग्राफक्यूएल को पार्स करने की जरूरत नहीं है, रनटाइम को कम करना।
  3. एसक्यूएल स्टेटमेंट ग्राफकॉइन की तुलना में बहुत अधिक लचीले होते हैं क्योंकि (ज्यादातर मामलों में) बाद में एसक्यूएल में कम हो जाएगा।
  4. हर कोई SQL जानता है।

तो, ग्राफ़िकल का एसक्यूएल पर क्या लाभ है?


41
छोटे बॉबी टेबल्स।
फिलिप केंडल

1
1. मैं अभी भी आपको मनमाने ढंग से जटिल एसक्यूएल प्रश्नों के साथ कर सकता हूँ। 2. कोई मौका नहीं है कि एक दुर्भावनापूर्ण अभिनेता कभी भी एक वैध कुंजी प्राप्त करेगा ...
फिलिप केंडल

3
@PhilipKendall आप सही हैं, लेकिन ग्राफकॉल (या आरईएसटी या जो भी) इन समस्याओं का समाधान नहीं करता है, है ना?
नालज़ोक

7
@nalzok: SQL ट्यूरिंग-पूर्ण है, जिसका अर्थ है कि यह सांख्यिकीय रूप से मान्य करना असंभव है।
जोर्ग डब्ल्यू मित्तग

3
यह समझना बहुत सरल है कि यह एक भयानक विचार क्यों है। इसे स्वयं लागू करें। कुछ बिंदु पर, आपको एहसास होगा कि आपका समय ज्यादातर 1 चीज में निवेश कर रहा है: सुरक्षा। नहीं बहुत बाद में आप कुछ परेशान महसूस करेंगे क्योंकि आप एक कैप्ड TOAD को लागू कर रहे हैं। तब आपको महसूस होगा कि पूरे सिस्टम में पंक्तियों की मैपिंग कितनी कठिन है और आप ORM व्हील को दोनों तरफ से मजबूत करने का प्रयास करेंगे: क्लाइंट और सर्वर। जब आप हार मानेंगे, तब तक आपका पीएम आपसे रिपोर्ट मांगेगा: उपयोगकर्ताओं की सेवा कैसे चल रही है ? यह हो गया? ”…
लाईव

जवाबों:


30

मूल रूप से, अमूर्तता।

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

एसक्यूएल को सीधे उजागर नहीं करने के लिए धन्यवाद, आप एपीआई के उपभोक्ता को अपने डेटाबेस के आंतरिक प्रतिनिधित्व तक सीमित नहीं कर रहे हैं। आप आसानी से केवल वही उजागर करते हैं जो आप उजागर करना चाहते हैं।

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

सार्वजनिक सेवाओं के लिए, डेटाबेस को सीधे उजागर करना बहुत सही दृष्टिकोण कभी नहीं है। यदि आपके पास कुछ आंतरिक प्रणालियां हैं, तो निश्चित रूप से, आपका दृष्टिकोण समझ में आता है, लेकिन तब भी आवेदन ए से डेटाबेस ए को सीधे लिंक करना आसान हो सकता है, आवेदन बी को डेटाबेस क्रेडेंशियल देकर, बजाय ऊपर आने के लिए प्रयास करने के डेटाबेस SQL ​​भाषा के लिए एक कस्टम HTTP इंटरफ़ेस के साथ।


RDBMS पर वास्तविक क्वेरी करने से पहले मैं Redis में कुंजियों के विरुद्ध सिर्फ URL (या SQL क्वेरी) की तुलना क्यों नहीं कर सकता?

क्योंकि यह आसान नहीं है। भले ही कोई बहुत ही सरल क्वेरी का उपयोग करता हो, जैसे:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.name = 'hello
world' AND st.type = 'STANDARD'

आप कैसे सुनिश्चित करते हैं कि परिणाम ठीक से कैश किया गया है? इस क्वेरी में newlines शामिल हैं, लेकिन कोई व्यक्ति निम्नलिखित तरीके से क्वेरी लिख सकता है:

SELECT st.id, jt.name FROM some_table st INNER JOIN join_table jt ON jt.some_table_id = st.id WHERE st.name = 'hello
world' AND st.type = 'STANDARD'

और यह अभी भी उसी तरह से कैश किया जाना चाहिए जैसा कि ऊपर दिया गया है। मैंने विशेष रूप से एक ऐसी जगह को शामिल किया है जिसमें एक स्ट्रिंग खोज में एक नई लाइन होती है, इसलिए बस लाइन के अंत को ढूंढना और उन्हें एक जगह के साथ बदलना यहां काम नहीं करने वाला है, अनुरोध को सही ढंग से पार्स करना अधिक जटिल होगा।

और अगर आप इसे ठीक करते हैं, तो भी दूसरी क्वेरी शर्तों के क्रम को बदल सकती है और क्वेरी इस तरह दिखाई देगी:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.type = 'STANDARD' AND st.name = 'hello
world'

और एक अन्य अनुरोध में एक निरर्थक WHEREतर्क हो सकता है , जैसे:

SELECT st.id, jt.name
FROM some_table st
INNER JOIN join_table jt ON jt.some_table_id = st.id
WHERE st.type = 'STANDARD' AND st.name = 'hello
world' AND st.stype = 'STANDARD'

उन सभी प्रश्नों को अभी भी उसी परिणाम पर वापस जाना है, उन्हें उसी तरह से कैश किया जाना चाहिए। लेकिन सभी संभावित विकल्पों को संभालना बहुत असंभव है। इसलिए आप केवल Redis में कुंजी के विरुद्ध URL की तुलना नहीं कर सकते।


यह एक अच्छा जवाब है, लेकिन कृपया अपडेट देखें।
नलज़ोक

19

सिद्धांत रूप में कोई कारण नहीं है कि आप इस तरह से एक SQL इंटरफ़ेस को उजागर नहीं कर सकते।

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

यहां तक ​​कि अगर आप केवल पढ़ने की अनुमति देते हैं, तो एक बुरी क्वेरी अभी भी संसाधनों को रोक सकती है।

अन्य भाषाओं जैसे कि ग्राफकॉल को उजागर करने के लिए डिज़ाइन किया गया है। वे केवल उपयोगकर्ताओं को एक फ़िल्टर विकल्प दे रहे हैं जो वे पहले से ही देख सकते हैं।

इन भाषाओं का उपयोग करने का लाभ यह है कि वे उन सभी चीजों से गुजरे हैं जिन्हें आप SQL में कर रहे उपयोगकर्ताओं को रोकना चाहते हैं और उन्हें टेबल से हटा दिया है।


2
उत्तर के लिए धन्यवाद, लेकिन क्या आप बता सकते हैं कि ग्राफकॉल संसाधन की समस्या को कैसे हल करता है? एक दुष्ट ग्राफक्लाइन क्वेरी अभी भी कह सकती है "मुझे प्रत्येक फिल्म और उनके अभिनेताओं के बारे में सब कुछ बताएं", जिसके परिणामस्वरूप एक बड़ा ग्राफ होता है, और मेरा DBMS और नेटवर्क समाप्त हो जाता है।
नलज़ोक

लेकिन मैं एक पुनरावर्ती SQL क्वेरी लिख सकता हूं जो आपकी तालिका को लॉक कर देगी और अन्य उपयोगकर्ताओं को किसी भी प्रश्न को चलाने से रोक देगी
Ewan

4
समस्या तालिकाओं तक पहुंच या हटाने के लिए बहुत सीमित नहीं है, लेकिन SQL की कतरनी जटिलता। क्या आप अस्थायी टेबल बनाने की अनुमति देंगे? CLI निष्पादित करने के बारे में क्या? छोरों? लेन-देन? उप चयन? कर्सर? जब आप इन चीजों का उपयोग स्वीकार्य है और जब इसकी 'खराब'
इवान

2

जैसा कि दूसरों ने उल्लेख किया है, एपी में सीधे एसक्यूएल को उजागर करना एक बहुत बुरा विकल्प है। ग्राफकॉल, यह नाम के बावजूद, एसक्यूएल के लिए एक अमूर्त नहीं है, लेकिन किसी भी डेटा स्टोर या अन्य सेवाओं के लिए।

यदि आप एक एब्स्ट्रैक्शन की तलाश में हैं जो SQL के करीब है, तो आप ओटाटा पर एक नज़र रखना चाह सकते हैं (यदि आप .NET बैकएंड में काम करने के लिए होते हैं, हालांकि शायद अन्य कार्यान्वयन मौजूद हैं)।


0

यदि आप एसक्यूएल को ग्राफकॉइल की तरह उजागर करना चाहते हैं, तो आपको ग्राफकॉल जैसी किसी चीज की आवश्यकता हो सकती है, क्योंकि आपको महत्वपूर्ण जानकारी को छिपाने और एपीआई में यह दिखाना होगा कि आपको सुरक्षा के लिए क्या चुनना है।

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

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

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