2011-08-15 21 views
77

के रूप में करते हुए यदि मैं डेटा सोर्सिंग डेटा स्टोर करने के लिए आरडीबीएमएस (उदा। एसक्यूएल सर्वर) का उपयोग कर रहा था, तो स्कीमा कैसा दिख सकता है?आरडीबीएमएस का उपयोग स्टोरेज सोर्सिंग स्टोरेज

मैंने कुछ भिन्नताओं को एक अमूर्त अर्थ में बात की है, लेकिन कुछ भी ठोस नहीं है।

उदाहरण के लिए, कहें कि किसी के पास "उत्पाद" इकाई है, और उस उत्पाद में परिवर्तन: मूल्य, लागत और विवरण के रूप में आ सकता है। चाहे के बारे में मैं चाहते मैं उलझन में हूँ:

  1. एक "ProductEvent" मेज, एक उत्पाद है, जहां प्रत्येक परिवर्तन यह है कि तालिका में एक नया रिकार्ड का मतलब के लिए सभी क्षेत्रों है कि है, के साथ साथ "कौन, क्या, जहां , क्यों, कब और कैसे "उपयुक्त के रूप में। जब लागत, मूल्य या विवरण बदल जाते हैं, तो उत्पाद का प्रतिनिधित्व करने के लिए जोड़े गए एक पूरी नई पंक्ति।
  2. अलग-अलग तालिकाओं में स्टोर उत्पाद लागत, मूल्य और विवरण एक विदेशी कुंजी रिश्ते के साथ उत्पाद तालिका में शामिल हो गए। जब उन गुणों में परिवर्तन होते हैं, तो उचित रूप से WWWWWH के साथ नई पंक्तियां लिखें।
  3. स्टोर WWWWWH, प्लस एक धारावाहिक वस्तु घटना का प्रतिनिधित्व करने वाले एक "ProductEvent" तालिका में, घटना अपने आप में लोड किया जाना चाहिए, de-धारावाहिक और आदेश के लिए आवेदन राज्य को फिर से बनाने के लिए अपने आवेदन कोड में फिर से खेला अर्थ एक दिया गया उत्पाद।

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

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

+2

अपने सबसे सरल रूप में: [घटना] {समेकित आईडी, समेकित संस्करण, EventPayload}। कुल प्रकार की आवश्यकता नहीं है, लेकिन आप इसे वैकल्पिक रूप से स्टोर कर सकते हैं। घटना प्रकार की कोई ज़रूरत नहीं है, लेकिन आप इसे वैकल्पिक रूप से स्टोर कर सकते हैं। यह उन चीजों की एक लंबी सूची है जो हुआ है, और कुछ भी अनुकूलन है। –

+7

निश्चित रूप से # 1 और # 2 से दूर रहें। सबकुछ नीचे एक ब्लॉब में सीरियलाइज करें और इसे इस तरह से स्टोर करें। –

उत्तर

83

ईवेंट स्टोर को विशिष्ट फ़ील्ड या ईवेंट के गुणों के बारे में जानने की आवश्यकता नहीं है। अन्यथा आपके मॉडल के प्रत्येक संशोधन के परिणामस्वरूप आपके डेटाबेस को माइग्रेट करना होगा (जैसे कि पुराने पुराने राज्य-आधारित दृढ़ता में)। इसलिए मैं विकल्प 1 और 2 की बिल्कुल अनुशंसा नहीं करता।

नीचे Ncqrs में उपयोग की जाने वाली स्कीमा है। जैसा कि आप देख सकते हैं, तालिका "ईवेंट" संबंधित डेटा को सीएलओबी (यानी JSON या XML) के रूप में संग्रहीत करती है। यह आपके विकल्प 3 से मेल खाता है (केवल इतना है कि "productEvents" तालिका नहीं है क्योंकि आपको केवल एक सामान्य "ईवेंट" तालिका की आवश्यकता होती है। एनसीकर्स में आपके कुल रूट्स पर मैपिंग "ईवेंट स्रोत" तालिका के माध्यम से होती है, जहां प्रत्येक EventSource वास्तविक से मेल खाता है सकल रूट।)

Table Events: 
    Id [uniqueidentifier] NOT NULL, 
    TimeStamp [datetime] NOT NULL, 

    Name [varchar](max) NOT NULL, 
    Version [varchar](max) NOT NULL, 

    EventSourceId [uniqueidentifier] NOT NULL, 
    Sequence [bigint], 

    Data [nvarchar](max) NOT NULL 

Table EventSources: 
    Id [uniqueidentifier] NOT NULL, 
    Type [nvarchar](255) NOT NULL, 
    Version [int] NOT NULL 

Jonathan Oliver's Event Store implementation की एसक्यूएल हठ तंत्र एक तालिका ब्लॉब क्षेत्र "पेलोड" के साथ "करता है" कहा जाता है की मूल रूप से होते हैं। यह एनसीकर्स में काफी समान है, केवल यह है कि यह घटना के गुणों को द्विआधारी प्रारूप में क्रमबद्ध करता है (उदाहरण के लिए, एन्क्रिप्शन समर्थन जोड़ता है)।

ग्रेग यंग extensively documented on Greg's website के समान दृष्टिकोण की सिफारिश करता है।

अपने प्रोटोटाइप "ईवेंट" तालिका के स्कीमा पढ़ता है:

Table Events 
    AggregateId [Guid], 
    Data [Blob], 
    SequenceNumber [Long], 
    Version [Int] 
+4

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

+5

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

+1

@ डेनिस ट्रब आपके उत्तर के लिए धन्यवाद। इवेंट स्टोर के खिलाफ क्यों सवाल नहीं उठाते? मुझे डर है कि अगर हम एक नए बीआई मामले के साथ आते हैं तो हमें पूर्ण इतिहास फिर से खेलना होगा? –

3

वैसे आप Datomic पर एक नज़र देना चाहते हो सकता है।

Datomic लचीला, समय आधारित तथ्यों, समर्थन प्रश्नों के एक डेटाबेस है और, मिलती है लोचदार क्षमता, और एसिड लेनदेन के साथ।

मैं एक विस्तृत जवाब here

आप स्टुअर्ट Halloway से एक टॉक Datomic here

के डिजाइन के बाद से समय में Datomic भंडार तथ्यों समझा देख सकते हैं लिखा है, आप उपयोग के मामलों सोर्सिंग घटना के लिए उपयोग कर सकते हैं, और इतना अधिक। (Type = 2)

1

संभावित संकेत द्वारा "धीरे धीरे आयाम बदलने" पीछा डिजाइन है की मदद करनी चाहिए आप को कवर करने के:

  • होने वाली घटनाओं (किराए की कुंजी के माध्यम से)
  • प्रत्येक राज्य के स्थायित्व के आदेश (मान्य से - वैध)

बाएं फोल्ड फ़ंक्शन को लागू करने के लिए भी ठीक होना चाहिए, लेकिन आपको भावी क्वेरी जटिलता के बारे में सोचना होगा।

2

गिटहब प्रोजेक्ट CQRS.NET में कुछ ठोस उदाहरण हैं कि आप कुछ अलग तकनीकों में EventStores कैसे कर सकते हैं। लिखने के समय SQL using Linq2SQL और SQL schema में इसके साथ जाने के लिए एक कार्यान्वयन है, MongoDB के लिए एक है, DocumentDB (कॉस्मोस डीबी यदि आप एज़ूर में हैं) और EventStore (जैसा ऊपर बताया गया है) का उपयोग कर रहा है। एज़ूर में टेबल स्टोरेज और ब्लॉब स्टोरेज की तरह अधिक है जो फ्लैट फ़ाइल स्टोरेज के समान है।

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

प्रोजेक्ट पर डेवलपर के रूप में मैं कुछ विकल्पों पर कुछ अंतर्दृष्टि साझा कर सकता हूं।

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

हम रखरखाव के कारणों के लिए एक कंटेनर/टेबल/संग्रह के साथ अटक गए, लेकिन हमने प्रति इकाई/ऑब्जेक्ट की एक अलग तालिका के साथ खेलना शुरू किया। हमने प्रैक्टिस में पाया कि इसका मतलब या तो "क्रिएट" अनुमतियों की आवश्यकता है (जो आम तौर पर बोलना एक अच्छा विचार नहीं है ... आम तौर पर, हमेशा अपवाद/बहिष्कार होते हैं) या हर बार जब कोई नई इकाई/वस्तु अस्तित्व में आती है या तैनात की जाती है, तो नया भंडारण कंटेनर/टेबल/संग्रह किए जाने की आवश्यकता है। हमने पाया कि स्थानीय विकास और उत्पादन तैनाती के लिए समस्याग्रस्त होने के लिए यह दर्दनाक रूप से धीमा था। आप नहीं कर सकते, लेकिन यह हमारा असली दुनिया का अनुभव था।

याद रखने के लिए एक और चीज यह है कि कार्रवाई करने के लिए एक्स पूछने से कई अलग-अलग घटनाएं हो सकती हैं, इस प्रकार कमांड/घटना/जो भी उपयोगी हो, द्वारा उत्पन्न सभी घटनाओं को जानना। वे अलग-अलग ऑब्जेक्ट प्रकारों में भी हो सकते हैं उदा। एक शॉपिंग कार्ट में "खरीद" को धक्का देकर खाते और गोदामों की घटनाओं को आग लग सकती है। एक उपभोग करने वाला एप्लिकेशन यह सब जानना चाहेगा, इसलिए हमने एक सहसंबंध जोड़ा। इसका मतलब था कि उपभोक्ता उनके अनुरोध के परिणामस्वरूप उठाए गए सभी कार्यक्रमों के लिए पूछ सकता है। आप देखेंगे कि schema में।

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

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

+0

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

+1

चीयर्स। मैंने मुख्य रूप से उन लोगों के लिए उत्तर जोड़ा जो हाल ही के समय में आते हैं और नतीजे के बजाय सीखने वाले कुछ सबक साझा करते हैं। – cdmdotnet

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