2008-12-27 12 views
10

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

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

को देखते हुए मैं इन काल्पनिक रिकॉर्ड मेरी टेबल का प्रतिनिधित्व किया है:

-record(user, {name, salt, pass_hash, email}). 
-record(entry, {title, body, slug}). 
-record(user_entry, {user_name, entry_title}). 

मैं, उपयोगकर्ता नाम का उपयोग प्रविष्टि शीर्षक के साथ के रूप में कुछ प्रयोजनों के लिए काफी अच्छा हो सकता है समझ, संसाधन को पहचान करने के लिए है, लेकिन कैसे करना है मैं ईमानदारी बनाए रखने के बारे में जाना?

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

मैनेशिया में किसी प्रकार की प्राथमिक कुंजी प्रणाली को लागू करने का सबसे अच्छा तरीका क्या होगा?

इसके अलावा, यदि पहली फ़ील्ड आमतौर पर कुंजी है तो 'user_entry' जैसी मध्यस्थ तालिका कैसे होगी? अन्यथा, मेनेसिया में कई से अधिक रिश्ते का प्रतिनिधित्व करने का बेहतर तरीका क्या होगा?

उत्तर

9

मैं कृत्रिम विदेशी कुंजी के रूप में स्वत: वृद्धिशील इंक की बजाय GUID का उपयोग करना पसंद करता हूं। Erlang uuid module गिटहब पर उपलब्ध है, या आप {now(), node()} का उपयोग कर सकते हैं, now/0 दस्तावेज़ कहता है: "यह भी गारंटी है कि इस बीआईएफ के बाद की कॉल लगातार बढ़ती कीमतों को लौटती है।"

प्राथमिक कुंजी के रूप में परिवर्तित करने वाले कुछ का उपयोग करना मुझे लगता है कि डेटाबेस सिस्टम से स्वतंत्र एक बुरा विचार है।

यह मत भूलना कि आपको मेनेशिया में डेटा को सामान्य सामान्य रूप से सामान्य करने की आवश्यकता नहीं है;

-record(user, {id, name, salt, pass_hash, email, entries}). 
-record(entry, {id, title, body, slug, users}). 

जहां entries और users आईडी की सूची इस प्रकार हैं: अपने उदाहरण में, मैं निम्नलिखित संरचना पर विचार करेंगे। बेशक, यह आपके इच्छित प्रश्नों पर निर्भर करता है।

संपादित करें: कई से अधिक के बजाय कई से अधिक होने के लिए तय किया गया है।

+0

यह वास्तव में अच्छा तरीका है? ऐसा लगता है कि make_ref/0 खोल को पुनरारंभ करने के बाद इसकी गणना को रीसेट करता है और इसमें कई समान मान होंगे। इसका मतलब यह नहीं होगा कि सर्वर पुनरारंभ करने के बाद आपको खराब कुंजियां मिल सकती हैं? इसे अब/0 के साथ जोड़ना, शायद मदद कर सकता है। –

+1

वास्तव में अब/0 को नोड/0 के साथ जोड़ना बेहतर है। –

+0

या उस मामले के लिए, आप केवल यूयूआईडी मॉड्यूल का उपयोग कर सकते हैं: http://github.com/travis/erlang-uuid/tree/master –

8

मेनेसिया mnesia:dirty_update_counter(Table, Key, Increment) के रूप में समर्थन अनुक्रम (ऑटो-वृद्धिशील पूर्णांक) का समर्थन करता है। इसका उपयोग करने के लिए आपको दो विशेषताओं कुंजी और गणना वाले तालिका की आवश्यकता है। नाम के बावजूद, dirty_update_counter परमाणु है, भले ही यह लेनदेन के अंदर नहीं चलता है।

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

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

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

-record(user, {name, salt, pass_hash, email}). 
-record(entry, {posted, title, body, slug, user_name}). 

कहाँ posted erlang है: जब लेख अपलोड की गई है अब() समय। user_name को एक माध्यमिक अनुक्रमणिका की आवश्यकता हो सकती है यदि आपको अक्सर उपयोगकर्ता के लिए सभी लेखों की सूची को पुनः प्राप्त करने की आवश्यकता होती है। चूंकि यह डेटा दो तालिकाओं में विभाजित है, आपको अपने आवेदन कोड में किसी भी अखंडता बाधाओं को लागू करना होगा (उदाहरण के लिए, मान्य उपयोगकर्ता_नाम के बिना प्रविष्टियों को स्वीकार नहीं करना)।

मैनेशिया में प्रत्येक फ़ील्ड मान किसी भी एरलैंग शब्द हो सकता है, इसलिए यदि आप किसी एक विशेष क्षेत्र पर एक अद्वितीय कुंजी के लिए हानि में हैं, तो आप अक्सर कुछ फ़ील्ड जोड़ सकते हैं ताकि आपको वह मूल्य मिल सके जो हमेशा अद्वितीय रहेगा - शायद {उपयोगकर्ता नाम, डेटपोस्टेड, टाइमपोस्टेड}। मेनेसिया आपको mnesia:select(Table, MatchSpec) के माध्यम से आंशिक कुंजी खोजने की अनुमति देता है। MatchSpecs हाथ से लिखना काफी मुश्किल है, इसलिए याद रखें कि ets:fun2ms/1 आपके लिए एक psso erlang फ़ंक्शन को एक matchspec में परिवर्तित कर सकता है।

इस उदाहरण में, fun2ms हमें ब्लॉग प्रविष्टि तालिका -record(entry, {key, title, slug, body}). खोजने के लिए एक matchspec उत्पन्न करता है जहां कुंजी {Username, {Year, Month, Day}, {Hour, Minute, Second}} है - लेखक का उपयोगकर्ता नाम और लेख पोस्ट करने की तिथि और समय। उदाहरण नीचे दिसंबर 2008 के दौरान TargetUsername द्वारा सभी ब्लॉग पोस्ट के शीर्षकों को पुन: प्राप्त

ets:fun2ms(fun (#entry{key={U, {Y,M,_D}, _Time}, title=T}) 
      when U=:=TargetUsername, Y=:=2008, M=:=12 -> 
       T 
      end). 
+0

मुझे लगता है कि "कहां" होना चाहिए "कब।" महान स्पष्टीकरण के लिए भी धन्यवाद। –

संबंधित मुद्दे