MYSQL 5.7 में मूल JSON का समर्थन: MYSQL में JSON डेटा प्रकार के पेशेवरों और विपक्ष क्या हैं?


113

MySQL 5.7 में MySQL तालिकाओं में JSON डेटा संग्रहीत करने के लिए एक नया डेटा प्रकार जोड़ा गया है। यह स्पष्ट रूप से MySQL में एक महान बदलाव होगा। उन्होंने कुछ लाभ सूचीबद्ध किए

दस्तावेज़ सत्यापन - केवल वैध JSON दस्तावेज़ों को JSON कॉलम में संग्रहीत किया जा सकता है, इसलिए आपको अपने डेटा का स्वत: सत्यापन प्राप्त होता है।

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

प्रदर्शन - JSON कॉलम के भीतर मूल्यों पर अनुक्रमित बनाकर अपने क्वेरी प्रदर्शन में सुधार करें। यह आभासी स्तंभों पर "कार्यात्मक अनुक्रमित" के साथ प्राप्त किया जा सकता है।

सुविधा - JSON कॉलम के लिए अतिरिक्त इनलाइन सिंटैक्स आपके SQL के भीतर दस्तावेज़ प्रश्नों को एकीकृत करने के लिए बहुत स्वाभाविक बनाता है। उदाहरण के लिए (features.feature एक JSON कॉलम है):SELECT feature->"$.properties.STREET" AS property_street FROM features WHERE id = 121254;

वाह ! उनमें कुछ बेहतरीन विशेषताएं शामिल हैं। अब डेटा में हेरफेर करना आसान हो गया है। अब कॉलम में अधिक जटिल डेटा संग्रहीत करना संभव है। इसलिए MySQL अब NoSQL के साथ सुगंधित है।

अब मैं JSON डेटा के लिए एक क्वेरी की तरह कुछ कल्पना कर सकता हूं

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN 
( 
SELECT JSON_EXTRACT(data,"$.inverted") 
FROM t1 | {"series": 3, "inverted": 8} 
WHERE JSON_EXTRACT(data,"$.inverted")<4 );

तो क्या मैं कुछ छोटे कोलम में विशाल छोटे संबंधों को संग्रहीत कर सकता हूं? अच्छी है? क्या यह सामान्यीकरण को तोड़ता है। यदि यह संभव है तो मुझे लगता है कि यह MySQL कॉलम में NoSQL की तरह काम करेगा । मैं वास्तव में इस सुविधा के बारे में अधिक जानना चाहता हूं। MySQL JSON डेटा प्रकार के पेशेवरों और विपक्ष।


ओह कृपया मत कहो कि मुझे क्या लगता है कि आप कह रहे हैं। यहाँ, यह पढ़ें । तुम्हारा एक बुरा विचार पर एक और संस्करण है।
ड्रू

@ ड्रू तुमने बड़ा जवाब दिया। लेकिन यह मेरा सवाल नहीं है। मैं सिर्फ यह जानना चाहता हूं कि अगर हम json data के लिए क्वेरी लिखते हैं तो हम sql नियमों को छोड़ सकते हैं। beacuse हमें कई तालिकाओं की आवश्यकता नहीं है
इमरान

1
आपने कहा Now it is possible to store more complex data in column। सावधान रहें
आकर्षित किया

2
Json डेटा प्रकार समर्थन सूचकांक और इसका स्मार्ट आकार है: 64K और 4G। तो क्या समस्या है अगर मुझे 2000 डेटा स्टोर करना है और संबंध के साथ 5 टेबल के बजाय 5 नेस्टेड लेबल जोड़ना है?
इमरान

5
"मैं वास्तव में इस सुविधा के बारे में अधिक जानना चाहता हूं।" और "MySQL JSON डेटा प्रकार के पेशेवरों और विपक्ष।" प्रश्न नहीं हैं, और यदि प्रश्न बहुत व्यापक हैं। "इसलिए मैं MySQL में एक जटिल स्कीमा संरचना और विदेशी कुंजी के बारे में कभी नहीं सोचता। मैं केवल कुछ तालिकाओं का उपयोग करके जटिल संबंधों को संग्रहीत करता हूं।" JSON संबंध और FK नहीं है क्योंकि स्व-विरोधाभासी है। "यह अच्छा है" का एक स्पष्टीकरण केवल संबंधपरक मॉडल का एक परिचय है, इसलिए फिर से यह बहुत व्यापक है। कुछ उदाहरणों के माध्यम से काम करें, संदर्भों के साथ पेशेवरों और विपक्षों की अपनी सूची बनाएं, और पूछें कि आप कहां गलत थे।
दीक्षा

जवाबों:


57
SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

किसी अभिव्यक्ति या फ़ंक्शन के अंदर एक स्तंभ का उपयोग करना इस तरह क्वेरी के अनुकूलन में मदद करने के लिए एक इंडेक्स का उपयोग करके क्वेरी के किसी भी अवसर को खराब करता है। ऊपर दिखाया गया क्वेरी टेबल-स्कैन करने के लिए मजबूर है।

"कुशल पहुंच" के बारे में दावा भ्रामक है। इसका मतलब है कि क्वेरी JSON दस्तावेज़ के साथ एक पंक्ति की जांच करने के बाद, यह JSON वाक्यविन्यास के पाठ को पार्स किए बिना एक फ़ील्ड निकाल सकता है। लेकिन यह अभी भी पंक्तियों की खोज करने के लिए एक टेबल-स्कैन करता है। दूसरे शब्दों में, क्वेरी को प्रत्येक पंक्ति की जांच करनी चाहिए।

सादृश्य से, अगर मैं पहले नाम "बिल" वाले लोगों के लिए एक टेलीफोन बुक खोज रहा हूं, तो मुझे अभी भी फोन बुक में हर पृष्ठ को पढ़ना होगा, भले ही पहले नामों को उन्हें स्पॉट करने के लिए थोड़ा तेज बनाने के लिए हाइलाइट किया गया हो।

MySQL 5.7 आपको तालिका में एक वर्चुअल कॉलम को परिभाषित करने की अनुमति देता है, और फिर वर्चुअल कॉलम पर एक इंडेक्स बनाता है।

ALTER TABLE t1
  ADD COLUMN series AS (JSON_EXTRACT(data, '$.series')),
  ADD INDEX (series);

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

SELECT * FROM t1
WHERE series IN ...

यह अच्छा है, लेकिन यह JSON का उपयोग करने की बात को याद करता है। JSON का उपयोग करने का आकर्षक हिस्सा यह है कि यह आपको ALTER TABLE करने के बिना नई विशेषताओं को जोड़ने की अनुमति देता है। लेकिन यह पता चलता है कि आपको एक अतिरिक्त (आभासी) कॉलम को किसी भी तरह से परिभाषित करना होगा, यदि आप इंडेक्स की मदद से JSON फ़ील्ड खोजना चाहते हैं।

लेकिन आपको JSON दस्तावेज़ में हर क्षेत्र के लिए वर्चुअल कॉलम और इंडेक्स को परिभाषित करने की ज़रूरत नहीं है - केवल उन पर जिन्हें आप खोजना चाहते हैं या सॉर्ट करना चाहते हैं। JSON में अन्य विशेषताएँ हो सकती हैं जिन्हें आपको केवल निम्न की तरह चयन-सूची में निकालने की आवश्यकता है:

SELECT JSON_EXTRACT(data, '$.series') AS series FROM t1
WHERE <other conditions>

मैं आमतौर पर कहूंगा कि यह MySQL में JSON का उपयोग करने का सबसे अच्छा तरीका है। केवल चयन सूची में।

जब आप अन्य खंड (JOIN, WHERE, GROUP BY, HAVING, ORDER BY) में स्तंभों का संदर्भ देते हैं, तो यह पारंपरिक स्तंभों का उपयोग करने के लिए अधिक कुशल होता है, JSON दस्तावेज़ों के भीतर फ़ील्ड नहीं।

मैंने अप्रैल 2018 में पेरकोना लाइव कॉन्फ्रेंस में MySQL गलत में JSON का उपयोग कैसे करें नामक एक बात प्रस्तुत की। मैं ओरेकल कोड वन में इस बात को अद्यतन और दोहराता हूं।

JSON के साथ अन्य समस्याएं हैं। उदाहरण के लिए, मेरे परीक्षणों में समान डेटा को संग्रहीत करने वाले पारंपरिक स्तंभों की तुलना में JSON दस्तावेज़ों के लिए 2-3 बार अधिक संग्रहण स्थान की आवश्यकता होती है।

MySQL अपनी नई JSON क्षमताओं को आक्रामक रूप से बढ़ावा दे रहा है, बड़े पैमाने पर लोगों को MongoDB के लिए पलायन करने के खिलाफ अस्वीकार करने के लिए। लेकिन MongoDB जैसे दस्तावेज़-उन्मुख डेटा संग्रहण मूल रूप से डेटा को व्यवस्थित करने का एक गैर-संबंधपरक तरीका है। यह संबंधपरक से अलग है। मैं यह नहीं कह रहा हूं कि एक दूसरे से बेहतर है, यह सिर्फ एक अलग तकनीक है, जो विभिन्न प्रकार के प्रश्नों के अनुकूल है।

जब JSON आपके प्रश्नों को अधिक कुशल बनाता है तो आपको JSON का उपयोग करना चाहिए।

एक तकनीक का चयन न करें क्योंकि यह नया है, या फैशन के लिए।


संपादित करें: MySQL में वर्चुअल कॉलम कार्यान्वयन सूचकांक का उपयोग करने के लिए माना जाता है यदि आपका WHERE क्लॉज वर्चुअल कॉलम की परिभाषा के समान ही अभिव्यक्ति का उपयोग करता है। अर्थात, वर्चुअल कॉलम परिभाषित होने के बाद, निम्नलिखित को वर्चुअल कॉलम पर सूचकांक का उपयोग करना चाहिएAS (JSON_EXTRACT(data,"$.series"))

SELECT * FROM t1
WHERE JSON_EXTRACT(data,"$.series") IN ...

सिवाय मैंने इस सुविधा का परीक्षण करके पाया है कि यह किसी कारण से काम नहीं करता है अगर अभिव्यक्ति एक JSON-निष्कर्षण फ़ंक्शन है। यह अन्य प्रकार के भावों के लिए काम करता है, सिर्फ JSON फ़ंक्शन नहीं।


7
खैर स्लाइड के लिंक का अनुसरण करने के लायक है
पॉल कैम्पबेल

अच्छी बात यह है कि 2 प्रौद्योगिकियां अपने स्वयं के साधनों में अच्छी हैं, हम तय करते हैं कि हमारी आवश्यकताओं के अनुसार क्या होगा और सुरक्षा और प्रदर्शन के मामले में हमें अधिक लाभ देता है।
क्रिस्टोफर पेलायो

1
समस्या की जड़ यह है कि JSON में हर नई कुंजी के लिए जेनरेट किए गए कॉलम पर एक इंडेक्स का उपयोग करने के लिए ALTER TABLE की आवश्यकता अभी भी है। खुशी है कि इसे इंगित किया जा रहा है।
user1454926 20

यदि आपको वर्चुअल कॉलम और / या इंडेक्स जोड़ने की आवश्यकता है तो ही। यदि आप JSON डेटा को "ब्लैक बॉक्स" के रूप में मानते हैं और JSON के भीतर उप-फ़ील्ड पर खोज या सॉर्ट करने वाले किसी भी प्रश्न को करने की कोशिश नहीं करते हैं, तो आपको ऐसा करने की आवश्यकता नहीं है। इसलिए मैं JSON को JOIN, WHEREया अन्य खंडों को संदर्भित करने से बचने की सलाह देता हूं । बस चयन सूची में JSON कॉलम लाएं।
बिल कारविन

स्लाइड्स का लिंक टूटा है, @BillKarwin
झीलसेरे

43

MySQL 5.7 से निम्नलिखित JSON के साथ सेक्सी वापस लाता है जो मुझे अच्छा लगता है:

MySQL में JSON डेटा प्रकार का उपयोग करना एक पाठ क्षेत्र में JSON स्ट्रिंग्स को संग्रहीत करने के दो लाभों के साथ आता है:

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

...

NoSQL स्टोर्स (डॉक्यूमेंट डीबी, की-वैल्यू स्टोर और ग्राफ डीबी) के विशिष्ट जायके शायद उनके विशिष्ट उपयोग के मामलों के लिए बेहतर विकल्प हैं, लेकिन इस डेटाटाइप के अतिरिक्त आपको अपनी तकनीक स्टैक की जटिलता को कम करने की अनुमति दे सकते हैं। मूल्य MySQL (या संगत) डेटाबेस के लिए युग्मन है। लेकिन यह कई उपयोगकर्ताओं के लिए एक गैर-मुद्दा है।

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

  1. JSON डेटाटाइप्स के साथ मैसकल
  2. बिना मायके

नेट में अब तक के mysql / json / प्रदर्शन के विषय पर उथले स्लाइडशेयर हैं, जो मैं देख रहा हूं।

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


7
एक कोन; JSON डेटा प्रकार डेटा प्रकार, TEXT और BLOB की तरह, मैस्केल मेमोरी टेबल द्वारा समर्थित नहीं है। इसका मतलब है कि अगर एक अस्थायी तालिका की आवश्यकता है, तो यह एक डिस्क आधारित तालिका बनाएगा स्मृति नहीं। कुछ मामलों में जब एक अस्थायी तालिका का उपयोग यहां किया जाता है: dev.mysql.com/doc/refman/5.7/en/internal-temporary-tables.html
raiz media

1
@raizmedia क्या आप इस बारे में विस्तार से बता सकते हैं कि डिस्क आधारित तालिका एक समस्या बनाम मेमोरी (आधारित तालिका जिसका मुझे अनुमान है) है?
लैपिन

@ लैपिन संभवत: गति सीमाओं के कारण।
लिटिल हेल्पर

यदि आप PCI 4x 40 Gb / s M.2 स्लॉट का उपयोग करते हैं और 40 Gb / समर्थित ड्राइव सम्मिलित करते हैं तो आप इसे टाल सकते हैं। यह तेजी से यादगार के रूप में काम करता है। आप उस ड्राइव पर एक विशेष प्रारूप लागू कर सकते हैं जिसका उपयोग मेमरी को प्रारूपित करने के लिए किया जाता है।
सेर्गेई रोमानोव

@SergeyRomanov, [citation required]क्या आपने उस ड्राइव को रैम बनाम बेंचमार्क किया है?
बिल कार्विन

11

मैं हाल ही में इस समस्या में आया, और मुझे निम्नलिखित अनुभव मिले:

1, सभी प्रश्नों को हल करने का एक तरीका नहीं है। 2, आपको JSON का उपयोग ठीक से करना चाहिए।

एक मामला:

मेरे पास एक टेबल है जिसका नाम है: CustomFieldऔर इसमें दो कॉलम होंगे: name, fieldsnameएक स्थानीय स्ट्रिंग है, यह सामग्री पसंद करनी चाहिए:

{
  "en":"this is English name",
  "zh":"this is Chinese name"
   ...(other languages)
}

और fieldsइस तरह होना चाहिए:

[
  {
    "filed1":"value",
    "filed2":"value"
    ...
  },
  {
    "filed1":"value",
    "filed2":"value"
    ...
  }
  ...
]

जैसा कि आप देख सकते हैं, दोनों nameऔर fieldsJSON के रूप में सहेजे जा सकते हैं, और यह काम करता है!

हालांकि, अगर मैं nameइस तालिका को बहुत बार खोज करने के लिए उपयोग करता हूं, तो मुझे क्या करना चाहिए? का उपयोग करें JSON_CONTAINS, JSON_EXTRACT...? जाहिर है, इसे JSON के रूप में सहेजने के लिए एक अच्छा विचार नहीं है, हमें इसे एक स्वतंत्र तालिका में सहेजना चाहिए CustomFieldName:।

उपरोक्त मामले से, मुझे लगता है कि आपको इन विचारों को ध्यान में रखना चाहिए:

  1. क्यों MYSQL JSON का समर्थन करते हैं?
  2. आप JSON का उपयोग क्यों करना चाहते हैं? क्या आपके व्यावसायिक तर्क को बस इसकी आवश्यकता थी? या कुछ और भी है?
  3. कभी आलसी मत बनो

धन्यवाद


2
आपको VIRTUAL कॉलम का उपयोग करने में रुचि हो सकती है। percona.com/blog/2016/03/07/...
बेल

10

मेरे अनुभव से, JSON कार्यान्वयन कम से कम MySql 5.7 में खराब प्रदर्शन के कारण बहुत उपयोगी नहीं है। वैसे, डेटा पढ़ने और सत्यापन के लिए यह इतना बुरा नहीं है। हालाँकि, JSON संशोधन MySql के साथ 10-20 गुना धीमा है जो कि पायथन या PHP के साथ है। आइए बहुत सरल JSON की कल्पना करें:

{ "name": "value" }

मान लीजिए कि हमें इसे कुछ इस तरह बदलना है:

{ "name": "value", "newName": "value" }

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

मेरे पास 40 मिलियन पंक्तियों की तालिका है, और पायथन स्क्रिप्ट इसे 3-4 घंटों में अपडेट करती है।

अब हमारे पास MySql JSON है, इसलिए हमें अब Python या PHP की आवश्यकता नहीं है, हम ऐसा कुछ कर सकते हैं:

UPDATE `JsonTable` SET `JsonColumn` = JSON_SET(`JsonColumn`, "newName", JSON_EXTRACT(`JsonColumn`, "name"))

यह सरल और उत्कृष्ट दिखता है। हालांकि, इसकी गति पायथन संस्करण की तुलना में 10-20 गुना धीमी है, और यह एकल लेनदेन है, इसलिए अन्य एप्लिकेशन समानांतर में तालिका डेटा को संशोधित नहीं कर सकते हैं।

इसलिए, यदि हम 40 मिलियन पंक्तियों की तालिका में JSON कुंजी को केवल डुप्लिकेट करना चाहते हैं, तो हमें 30-40 घंटों के दौरान तालिका का उपयोग करने की आवश्यकता नहीं है। इसकी कोई संतान नहीं है।

के माध्यम से, डाटा पढ़ने JSON क्षेत्र के लिए मेरे अनुभव सीधी पहुंच से के बारे में JSON_EXTRACTमें WHEREभी extremelly धीमी गति से (बहुत धीमी है कि है TEXTके साथ LIKEनहीं अनुक्रमित स्तंभ पर)। वर्चुअल जनरेट किए गए कॉलम बहुत तेज़ी से प्रदर्शन करते हैं, हालाँकि, यदि हम अपनी डेटा संरचना को पहले से जानते हैं, तो हमें JSON की आवश्यकता नहीं है, हम इसके बजाय पारंपरिक कॉलम का उपयोग कर सकते हैं। जब हम JSON का उपयोग करते हैं, जहां यह वास्तव में उपयोगी होता है, अर्थात जब डेटा संरचना अज्ञात होती है या अक्सर बदलती रहती है (उदाहरण के लिए, कस्टम प्लगइन सेटिंग्स), किसी भी संभव नए कॉलम के लिए नियमित आधार पर आभासी स्तंभ निर्माण अच्छा विचार नहीं दिखता है।

पायथन और पीएचपी JSON सत्यापन को एक आकर्षण की तरह बनाते हैं, इसलिए यह संदेहास्पद है कि क्या हमें MySql की ओर JSON सत्यापन की आवश्यकता है। XML, Microsoft Office दस्तावेज़ या वर्तनी की जाँच को भी मान्य क्यों नहीं करते? ;)

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