जब आप एक अद्वितीय सूचकांक नहीं जोड़ सकते हैं तो डुप्लिकेट से बचने के लिए संभव तरीके क्या हैं


10

मैं एक समसामयिक समस्या में फंस गया हूं।

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

यह समस्या तब आसान होती है जब आप किसी ऐसे इंडेक्स (यूनिक) को एक कॉलम में जोड़ सकते हैं जहाँ आप हैश स्टोर करते हैं।

लेकिन इस मामले में, मेरे पास एक बड़ी तालिका है (शायद लाखों रिकॉर्ड) और मैं सिर्फ तालिका को संशोधित नहीं कर सकता।

वास्तव में, हमारे पास एक कॉलम होता है, जहां हम डेटा का एक हैश लगाते हैं, जिसे डुप्लिकेट नहीं किया जाना चाहिए, लेकिन एक अद्वितीय सूचकांक सेट नहीं किया गया था।

मैं अपने जावा कोड पर जांच कर रहा हूं कि क्या फ्लश से पहले मौजूद है, अभी भी डुप्लिकेट मिल रहा है।

इसके लिए मेरे संभावित समाधान हैं:

  • एक ट्रिगर बनाएं जो यह जांचता है कि मैं जिस हैश को सम्मिलित करने का प्रयास कर रहा हूं वह पहले से ही टेबल पर मौजूद है।
  • इस तालिका के लिए अनन्य अनुक्रमित संग्रह करने के लिए एक और तालिका बनाएं और मुख्य तालिका में एक विदेशी कुंजी जोड़ें।
  • भ्रूण की स्थिति पर बैठो और रोओ

क्या हैश टकराव या चेक में बग के कारण हैश की आपकी जाँच विफल हो रही है?
कैंडिड_ऑरेंज

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

समस्या यह है कि इस परिवर्तन को करने के लिए मुझे चेतावनी दी गई है कि हमें अपनी सेवा के लिए बहुत सी जगह और लंबे डाउनटाइम की आवश्यकता है, कुछ आवश्यकताओं को पूरा करने के लिए हमारी सेवा मासिक 2 घंटे से अधिक नहीं हो सकती है। मुझे पता है कि इस तालिका पर एक मुख्य प्रदर्शन करने का सबसे अच्छा तरीका है, लेकिन कुछ ऐसा है जो मैं इस समय नहीं कर सकता, इसलिए हमें एक वर्कअराउंड की आवश्यकता है।
रफुरू

4
मुझे यह नहीं मिलता है - एक अनुक्रमणिका जोड़ने या "अनुकरण" करने के लिए एक और तालिका जोड़ने से मौजूदा तालिका में केवल एक सूचकांक जोड़ने की तुलना में कम डाउनटाइम क्यों मिलता है?
डॉक्टर ब्राउन

2
@ आफुरु: किसने कहा कि आपको एक अद्वितीय सूचकांक बनाने की आवश्यकता है? एक मानक, गैर-अद्वितीय सूचकांक शायद आप सभी को एक ही हैश मान के साथ सभी पंक्तियों को खोजने की आवश्यकता होगी।
डॉक्टर ब्राउन

जवाबों:


3

संभावित परिदृश्यों के एक जोड़े को हल करना आसान है, और एक बुरा नहीं है।

उस उपयोगकर्ता के लिए जो किसी मूल्य में प्रवेश करता है, तो कुछ समय बाद उसी मूल्य में प्रवेश करता है जब INSERT के सामने एक सरल चयन समस्या का पता लगाएगा। यह उस स्थिति के लिए काम करता है जहां एक उपयोगकर्ता एक मान जमा करता है और कुछ समय बाद दूसरा उपयोगकर्ता उसी मान को जमा करता है।

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

ट्रिकी परिदृश्य तब होता है जब एक उपयोगकर्ता का लेखन उसी समय किसी अन्य उपयोगकर्ता के लेखन के रूप में DBMS के अंदर होता है, और वे एक ही मूल्य लिख रहे होते हैं। फिर आप उनके बीच एक शर्त रखते हैं। चूँकि DBMS है (सबसे अधिक संभावना है - आप यह नहीं कहते कि आप किसका उपयोग कर रहे हैं) एक प्रीमेप्टिव मल्टीटास्किंग सिस्टम किसी भी कार्य को इसके निष्पादन में किसी भी बिंदु पर रोका जा सकता है। इसका मतलब है कि user1 का कार्य देख सकता है कि कोई मौजूदा पंक्ति नहीं है, फिर user2 का कार्य देख सकता है कि कोई मौजूदा पंक्ति नहीं है, फिर user1 का कार्य उस पंक्ति को सम्मिलित कर सकता है, फिर उपयोगकर्ता 2 का कार्य उस पंक्ति को सम्मिलित कर सकता है। प्रत्येक बिंदु पर कार्य व्यक्तिगत रूप से खुश हैं वे सही काम कर रहे हैं। हालाँकि, एक त्रुटि होती है।

आमतौर पर एक DBMS प्रश्न में मूल्य पर ताला लगाकर इसे संभालता है। इस समस्या में आप एक नई पंक्ति बना रहे हैं, इसलिए लॉक करने के लिए अभी तक कुछ भी नहीं है। जवाब एक रेंज लॉक है। जैसा कि यह सुझाव देता है कि यह मानों की एक सीमा को लॉक करता है, चाहे वे वर्तमान में मौजूद हों या नहीं। एक बार लॉक होने के बाद उस रेंज को किसी अन्य कार्य द्वारा एक्सेस नहीं किया जा सकता है। रेंज लॉक प्राप्त करने के लिए आपको SERIALIZABLE का निर्दिष्ट और अलगाव स्तर रखना होगा । आपके कार्य की जाँच करने के बाद एक पंक्ति में चुपके से किसी अन्य कार्य की घटना को प्रेत रिकॉर्ड्स के रूप में जाना जाता है ।

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

कोड-आधारित विकल्प पहले के बजाय लिखने के बाद जांचना है । तो INSERT करें, फिर उन पंक्तियों की संख्या गिनें जिनके पास हैश मान है। यदि डुप्लिकेट हैं तो कार्रवाई को रोलबैक करें। इसके कुछ विकृत परिणाम हो सकते हैं। कार्य 1 कहें तो कार्य 2 लिखता है। फिर कार्य 1 जाँचता है और एक डुप्लिकेट पाता है। यह पहली बार होने के बावजूद वापस लौटता है। इसी तरह दोनों कार्यों में डुप्लिकेट और रोलबैक दोनों का पता लगाया जा सकता है। लेकिन कम से कम आपके पास काम करने के लिए एक संदेश होगा, एक पुन: प्रयास तंत्र और कोई नया डुप्लिकेट नहीं। रोलबैक को प्रोग्राम प्रवाह को नियंत्रित करने के लिए अपवादों का उपयोग करने पर बहुत पसंद किया जाता है। ध्यान दें कि सभीलेन-देन में काम वापस ले लिया जाएगा, न कि केवल डुप्लिकेट-उत्प्रेरण लेखन। और आपको स्पष्ट लेन-देन करना होगा जो कि संगामिति को कम कर सकता है। जब तक आपके पास हैश पर एक इंडेक्स न हो, डुप्लिकेट चेक बहुत ही धीमा होगा। यदि आप करते हैं तो आप इसे एक अनोखा बना सकते हैं!

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


2

वास्तव में, हमारे पास एक कॉलम होता है, जहां हम डेटा का एक हैश लगाते हैं, जिसे डुप्लिकेट नहीं किया जाना चाहिए, लेकिन एक अद्वितीय सूचकांक सेट नहीं किया गया था।

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

दूसरा चरण वास्तव में डेटा समानता की जांच करना है, क्योंकि सबसे अच्छा हैश फ़ंक्शन कभी-कभी टकराव में परिणाम देगा, क्योंकि आप (आमतौर पर) अपने डेटा के एन्ट्रापी को कम कर रहे हैं।

इसलिए:

चरण 1: जांचें कि क्या आपको क्रिप्टोग्राफिक हैश पर टक्कर मिलती है

चरण 2: यदि हैश मैच होता है, तो वास्तविक डेटा की जांच करें


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

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

मुझे पूरा यकीन है, यहां तक ​​कि जब एक इंडेक्स बनाना संभव नहीं है (जो कि इस मामले में शायद है), ओपी मूल सुझाव " इस तालिका के लिए अद्वितीय इंडेक्स को स्टोर करने के लिए एक और तालिका बनाने और मुख्य तालिका में एक विदेशी कुंजी जोड़ने के लिए " बहुत बनाता है अधिक समझदारी।
डॉक ब्राउन

नियतात्मक हैश और क्रिप्टोग्राफिक हैश दो ऑर्थोगोनल अवधारणाएं हैं वे नहीं हैं? एक क्रिप्टोग्राफिक हैश नियतात्मक नहीं हो सकता है और इसके विपरीत एक नियतकालिक हैश बहुत अच्छी तरह से क्रिप्टोकरेंसी की शक्ति का नहीं हो सकता है।
न्यूटोपियन

वे एक ही बात नहीं कर रहे हैं, लेकिन वे या तो रूढ़िवादी नहीं हैं। क्रिप्टोग्राफिक हैश, नियतात्मक हैश का एक उपसमुच्चय है, लेकिन कोई भी वास्तव में गैर क्रिप्टोग्राफिक नियतात्मक हैश को परेशान नहीं करता है जब तक कि आप विशेष रूप से किसी कारण के लिए प्रतिवर्ती नहीं चाहते हैं।
तुर्कसारमा

2

एक अद्वितीय प्राथमिक कुंजी के साथ एक नई तालिका बनाएं

क्लाइंट की ओर से प्रत्येक रिकॉर्ड के लिए GUID बनाना शुरू करें ताकि आप सरल रीसेंड का पता लगा सकें।

नए रिकॉर्ड को नए तालिका में डालें ताकि कम से कम आप नए डेटा के आने के लिए अच्छे हों।

नई तालिका "CheckedAgainstOldData" में एक कॉलम रखें

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

इस बीच एक और बैकएंड कार्य है जो पुराने से नए टेबल पर डेटा ले जाता है, आपके हैश चेक के साथ डुप्लिकेट की जाँच करता है और GUID उत्पन्न करता है।

आप कई दिनों तक (यदि आवश्यक हो) चल रहे इस कार्य को छोड़ सकते हैं, बिना किसी डाउनटाइम के डेटा को स्थानांतरित कर सकते हैं।

एक बार स्थानांतरण पूरा होने पर आप धीमी "CheckedAgainstOldData" प्रक्रिया को बंद कर सकते हैं। और सभी डेटा को एक ही तालिका में स्थानांतरित करें।

सच कहूँ तो अगर समस्या के रूप में आप के रूप में बुरा है और सॉफ्टवेयर पुराना है, तो आप हजारों डुप्लिकेट होने जा रहे हैं।


1

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

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