मैं एक साधारण बैंक डेटाबेस के लिए स्कीमा लिख रहा हूं। यहाँ बुनियादी विनिर्देश हैं:
- डेटाबेस एक उपयोगकर्ता और मुद्रा के खिलाफ लेनदेन को संग्रहीत करेगा।
- प्रत्येक उपयोगकर्ता के पास प्रति मुद्रा एक शेष राशि है, इसलिए प्रत्येक शेष राशि किसी दिए गए उपयोगकर्ता और मुद्रा के खिलाफ सभी लेनदेन का योग है।
- एक संतुलन नकारात्मक नहीं हो सकता।
बैंक एप्लिकेशन अपने डेटाबेस के साथ विशेष रूप से संग्रहीत प्रक्रियाओं के माध्यम से संचार करेगा।
मुझे उम्मीद है कि इस डेटाबेस में प्रति दिन सैकड़ों हजारों नए लेनदेन स्वीकार किए जाएंगे, साथ ही साथ परिमाण के उच्च क्रम पर प्रश्नों को संतुलित किया जाएगा। बहुत जल्दी संतुलन बनाने के लिए मुझे उन्हें पूर्व-एकत्र करने की आवश्यकता है। उसी समय, मुझे यह गारंटी देने की आवश्यकता है कि एक संतुलन कभी भी इसके लेनदेन के इतिहास का खंडन नहीं करता है।
मेरे विकल्प हैं:
एक अलग
balancesटेबल रखें और निम्न में से एक करें:दोनों
transactionsऔरbalancesतालिकाओं के लिए लेनदेन लागू करें ।TRANSACTIONमेरी संग्रहीत कार्यविधि परत में तर्क का उपयोग करें ताकि यह सुनिश्चित हो सके कि संतुलन और लेनदेन हमेशा सिंक में हैं। ( जैक द्वारा समर्थित )लेन-देन को
transactionsतालिका में लागू करें और एक ट्रिगर करें जोbalancesलेनदेन की राशि के साथ मेरे लिए तालिका को अपडेट करता है ।लेन-देन को
balancesतालिका में लागू करें और एक ट्रिगर करें जोtransactionsलेनदेन की राशि के साथ मेरे लिए तालिका में एक नई प्रविष्टि जोड़ता है ।
मुझे यह सुनिश्चित करने के लिए सुरक्षा-आधारित दृष्टिकोणों पर भरोसा करना होगा कि संग्रहीत प्रक्रियाओं के बाहर कोई बदलाव नहीं किया जा सकता है। अन्यथा, उदाहरण के लिए, कुछ प्रक्रिया सीधे लेनदेन को
transactionsतालिका में सम्मिलित कर सकती है और योजना1.3के तहत प्रासंगिक संतुलन सिंक से बाहर हो जाएगा।एक
balancesअनुक्रमित दृश्य है जो लेनदेन को उचित रूप से एकत्रित करता है। भंडारण इंजन द्वारा बैलेंस की गारंटी उनके लेनदेन के साथ रहने के लिए दी जाती है, इसलिए मुझे इसकी गारंटी देने के लिए सुरक्षा-आधारित दृष्टिकोणों पर भरोसा करने की आवश्यकता नहीं है। दूसरी ओर, मैं संतुलन लागू नहीं कर सकता क्योंकि अब भी गैर-नकारात्मक हो सकता है - यहां तक कि अनुक्रमित विचार - भीCHECKअड़चन नहीं हो सकते । ( डेनी द्वारा समर्थित )सिर्फ एक
transactionsतालिका है लेकिन एक अतिरिक्त कॉलम के साथ शेष राशि को सही तरीके से लेन-देन करने के लिए प्रभावी है। इस प्रकार, एक उपयोगकर्ता और मुद्रा के लिए नवीनतम लेनदेन रिकॉर्ड में उनका वर्तमान संतुलन भी शामिल है। ( एंड्रयू द्वारा नीचे सुझाया गया ; वैरिक द्वारा प्रस्तावित संस्करण )
जब मैंने पहली बार इस समस्या से निपटा, तो मैंने इन दो चर्चाओं को पढ़ा और विकल्प पर निर्णय लिया 2। संदर्भ के लिए, आप इसके बारे में एक नंगे हड्डियों कार्यान्वयन देख सकते हैं यहां ।
क्या आपने एक उच्च लोड प्रोफ़ाइल के साथ एक डेटाबेस को इस तरह डिज़ाइन या प्रबंधित किया है? आपकी इस समस्या का हल क्या था?
क्या आपको लगता है कि मैंने सही डिज़ाइन पसंद किया है? क्या मुझे कुछ भी ध्यान में रखना चाहिए?
उदाहरण के लिए, मुझे पता है कि
transactionsतालिका में स्कीमा परिवर्तन से मुझेbalancesदृश्य के पुनर्निर्माण की आवश्यकता होगी । यहां तक कि अगर मैं डेटाबेस को छोटा रखने के लिए लेन-देन कर रहा हूं (जैसे उन्हें कहीं और ले जाकर और उन्हें सारांश लेनदेन के साथ बदलकर), तो हर स्कीमा अपडेट के साथ दसियों लाखों लेनदेन के दृश्य को फिर से बनाना, संभवतः तैनाती के प्रति काफी डाउनटाइम का मतलब होगा।यदि अनुक्रमित दृश्य जाने का रास्ता है, तो मैं कैसे गारंटी दे सकता हूं कि कोई संतुलन नकारात्मक नहीं है?
अभिलेखागार लेनदेन:
मुझे ऊपर दिए गए अभिलेखों और "सारांश लेनदेन" को संग्रहीत करने पर थोड़ा विस्तार से बताएं। सबसे पहले, इस तरह के एक उच्च-लोड प्रणाली में नियमित संग्रह एक आवश्यकता होगी। मैं पुराने लेनदेन को कहीं और स्थानांतरित करने की अनुमति देते हुए संतुलन और उनके लेनदेन इतिहास के बीच स्थिरता बनाए रखना चाहता हूं। ऐसा करने के लिए, मैं प्रत्येक राशि को प्रति उपयोगकर्ता और मुद्रा के सारांश के साथ संग्रहीत लेन-देन की जगह दूंगा।
इसलिए, उदाहरण के लिए, लेन-देन की यह सूची:
user_id currency_id amount is_summary
------------------------------------------------
3 1 10.60 0
3 1 -55.00 0
3 1 -12.12 0
दूर संग्रहीत है और इसके साथ प्रतिस्थापित किया गया है:
user_id currency_id amount is_summary
------------------------------------------------
3 1 -56.52 1
इस तरह, संग्रहीत लेनदेन के साथ एक संतुलन पूर्ण और सुसंगत लेनदेन इतिहास रखता है।