DDD के बिना और बिना (या के साथ?) ES - क्या मॉडल लिख रहा है और क्या पढ़ा मॉडल है?


11

जहां तक ​​मैं समझता हूं, CQRS के पीछे का बड़ा विचार कमांड और क्वेरी को संभालने के लिए 2 अलग-अलग डेटा मॉडल हैं। इन्हें "राइट मॉडल" और "रीड मॉडल" कहा जाता है।

आइए ट्विटर एप्लिकेशन क्लोन के एक उदाहरण पर विचार करें। यहाँ आदेश हैं:

  • उपयोगकर्ता खुद को पंजीकृत कर सकते हैं। CreateUserCommand(string username)का उत्सर्जन करता हैUserCreatedEvent
  • उपयोगकर्ता अन्य उपयोगकर्ताओं का अनुसरण कर सकते हैं। FollowUserCommand(int userAId, int userBId)का उत्सर्जन करता हैUserFollowedEvent
  • उपयोगकर्ता पोस्ट बना सकते हैं। CreatePostCommand(int userId, string text)का उत्सर्जन करता हैPostCreatedEvent

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

और यहाँ प्रश्न हैं:

  • एक उपयोगकर्ता को अपने पदों की सूची देखने की जरूरत है। GetPostsQuery(int userId)
  • एक उपयोगकर्ता को अपने अनुयायियों की सूची देखने की आवश्यकता है। GetFollowersQuery(int userId)
  • एक उपयोगकर्ता को उन उपयोगकर्ताओं की सूची देखने की जरूरत है, जो इस प्रकार हैं। GetFollowedUsersQuery(int userId)
  • एक उपयोगकर्ता को "मित्र फ़ीड" देखने की जरूरत है - उनके सभी दोस्तों की गतिविधियों का एक लॉग ("आपका दोस्त जॉन ने एक नया पोस्ट बनाया है")। GetFriedFeedRecordsQuery(int userId)

संभालने के लिए CreateUserCommandमुझे यह जानना होगा कि क्या ऐसा उपयोगकर्ता पहले से मौजूद है। इसलिए, इस बिंदु पर मुझे पता है कि मेरे लेखन मॉडल में सभी उपयोगकर्ताओं की एक सूची होनी चाहिए।

संभालने के लिए FollowUserCommandमुझे यह जानना होगा कि userA पहले से ही userB का अनुसरण करता है या नहीं। इस बिंदु पर मैं चाहता हूं कि मेरा लेखन मॉडल सभी उपयोगकर्ता-प्रकार-उपयोगकर्ता कनेक्शनों की एक सूची हो।

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

प्रश्न # 1 : क्या वास्तव में "राइट मॉडल" शब्द का उपयोग करना सही है, जिस तरह से वे इसका उपयोग करते हैं? या ES के मामले में "इवेंट मॉडल" हमेशा "इवेंट स्टोर" के लिए खड़ा है? यदि हां, तो क्या मुझे कमांड को संभालने के लिए आवश्यक डेटा और प्रश्नों को संभालने के लिए आवश्यक डेटा के बीच किसी प्रकार का अलगाव है?

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

दोनों को संभालने के लिए GetFollowersQueryऔर GetFollowedUsersQuery, मुझे उपयोगकर्ताओं के बीच सभी कनेक्शनों की एक सूची की आवश्यकता होगी। इस मॉडल को बनाए रखने के लिए मैं सुनने जा रहा हूं UserFollowedEvent। यहाँ एक प्रश्न # 2 है : क्या यह व्यावहारिक रूप से ठीक है अगर मैं राइट मॉडल की सूची का उपयोग यहां करता हूं? या क्या मुझे एक अलग रीड मॉडल बनाना चाहिए, क्योंकि भविष्य में मुझे लिखने के मॉडल की तुलना में अधिक विवरण की आवश्यकता हो सकती है?

अंत में, GetFriendFeedRecordsQueryमुझे संभालने की आवश्यकता होगी:

  • सुनना UserFollowedEvent
  • सुनना PostCreatedEvent
  • जानिए कौन से यूजर्स कौन से दूसरे यूजर्स को फॉलो करते हैं

यदि उपयोगकर्ता A उपयोगकर्ता B का अनुसरण करता है और उपयोगकर्ता B उपयोगकर्ता C का अनुसरण करना शुरू करता है, तो निम्नलिखित रिकॉर्ड दिखाई देने चाहिए:

  • उपयोगकर्ता A के लिए: "आप मित्र उपयोगकर्ता B ने अभी उपयोगकर्ता C का अनुसरण करना शुरू किया है"
  • उपयोगकर्ता B के लिए: "आपने अभी उपयोगकर्ता C का अनुसरण करना शुरू किया है"
  • उपयोगकर्ता C के लिए: "उपयोगकर्ता B अब आपका अनुसरण कर रहा है"

यहां प्रश्न # 3 है : कनेक्शन की सूची प्राप्त करने के लिए मुझे किस मॉडल का उपयोग करना चाहिए? क्या मुझे लेखन मॉडल का उपयोग करना चाहिए? क्या मुझे रीड मॉडल - GetFollowersQuery/ का उपयोग करना चाहिए GetFollowedUsersQuery? या क्या मुझे GetFriendFeedRecordsQueryअपने आप को मॉडल बनाना चाहिए UserFollowedEventऔर सभी कनेक्शनों की अपनी सूची को बनाए रखना चाहिए ?


ध्यान रखें कि CQRS सिस्टम में, क्वेरी डेटा मॉडल और कमांड डेटा मॉडल अलग-अलग डेटा बेस से डेटा की खपत कर सकते हैं। और दोनों मॉडल स्वतंत्र रूप से एक-दूसरे (अलग-अलग ऐप) में रह सकते हैं। कहा जा रहा है, जवाब "निर्भर करता है" (हमेशा की तरह) है। इसमें रुचि
Laiv

जवाबों:


7

ग्रेग यंग (2010)

CQRS बस दो वस्तुओं का निर्माण है जहां पहले केवल एक ही था।

यदि आप बर्ट्रेंड मेयर्स कमांड क्वेरी पृथक्करण के संदर्भ में सोचते हैं , तो आप मॉडल को दो अलग-अलग इंटरफेस के रूप में सोच सकते हैं, एक जो कमांड का समर्थन करता है, और एक जो प्रश्नों का समर्थन करता है।

interface IChangeTheModel {
    void createUser(string username)
    void followUser(int userAId, int userBId)
    void createPost(int userId, string text)
}

interface IDontChangeTheModel {
    Iterable<Post> getPosts(int userId)
    Iterable<Follower> getFollowers(int userId)
    Iterable<FollowedUser> getFollowedUsers(int userId)
}

class TheModel implements IChangeTheModel, IDontChangeTheModel {
    // ...
}

ग्रेग यंग की अंतर्दृष्टि थी कि आप इसे दो अलग-अलग वस्तुओं में अलग कर सकते हैं

class WriteModel implements IChangeTheModel { ... }
class ReadModel  implements IDontChangeTheModel {...}

ऑब्जेक्ट्स को अलग करने के बाद, अब आपके पास डेटा संरचनाओं को अलग करने का विकल्प है जो ऑब्जेक्ट स्टेट को मेमोरी में रखता है, ताकि आप प्रत्येक केस के लिए ऑप्टिमाइज़ कर सकें; या पढ़ने की स्थिति को लिखने की स्थिति से अलग स्टोर / जारी रखें।

प्रश्न # 1: क्या वास्तव में "राइट मॉडल" शब्द का उपयोग करना सही है, जिस तरह से वे इसका उपयोग करते हैं? या ES के मामले में "इवेंट मॉडल" हमेशा "इवेंट स्टोर" के लिए खड़ा है? यदि हां, तो क्या मुझे कमांड को संभालने के लिए आवश्यक डेटा और प्रश्नों को संभालने के लिए आवश्यक डेटा के बीच किसी प्रकार का अलगाव है?

शब्द WriteModel को आमतौर पर मॉडल का उत्परिवर्तनीय प्रतिनिधित्व समझा जाता है (अर्थात: वस्तु, दृढ़ता का भंडार नहीं)।

TL; DR: मुझे लगता है कि आपका उपयोग ठीक है।

यहाँ एक प्रश्न # 2 है: क्या यह व्यावहारिक रूप से ठीक है अगर मैं राइट मॉडल की सूची का उपयोग यहां करता हूं?

वह "ठीक" है - ईश। वैचारिक रूप से, रीड मॉडल के साथ कुछ भी गलत नहीं है और समान संरचनाओं को साझा करने वाला मॉडल लिखें।

व्यवहार में, क्योंकि मॉडल को लिखना आमतौर पर परमाणु नहीं होता है, संभावित रूप से एक समस्या होती है जब एक धागा मॉडल की स्थिति को संशोधित करने की कोशिश कर रहा होता है जबकि दूसरा धागा इसे पढ़ने की कोशिश कर रहा होता है।

यहां प्रश्न # 3 है: कनेक्शन की सूची प्राप्त करने के लिए मुझे किस मॉडल का उपयोग करना चाहिए? क्या मुझे लेखन मॉडल का उपयोग करना चाहिए? क्या मुझे रीड मॉडल - GetFollowersQuery / GetFollowedUserQuery का उपयोग करना चाहिए? या क्या मुझे GetFriendFeedRecordsQuery मॉडल को स्वयं UserFollowedEvent को हैंडल करना चाहिए और सभी कनेक्शनों की अपनी सूची को बनाए रखना चाहिए?

राइट मॉडल का उपयोग करना गलत उत्तर है।

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

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

आपकी विशिष्ट परिस्थिति में, जहां आप अभी भी पैटर्न सीख रहे हैं, मेरा सुझाव आपके डिजाइन को "सरल" बनाए रखने के लिए होगा - एक रीड मॉडल है जो राइट मॉडल के डेटा संरचना को साझा नहीं करता है।


1

मैं आपको यह विचार करने के लिए प्रोत्साहित करूंगा कि आपके पास एक वैचारिक डेटा मॉडल है।

फिर लेखन मॉडल उस डेटा मॉडल का एक भौतिककरण है जिसे लेनदेन संबंधी अपडेट के लिए अनुकूलित किया गया है। कभी-कभी इसका मतलब सामान्यीकृत संबंधपरक डेटाबेस होता है।

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


(# 1) CQRS के लिए, लिखने के मॉडल में इवेंट स्टोर नहीं है।

(# 2) मुझे उम्मीद नहीं है कि पढ़े गए मॉडल को लिखने वाले मॉडल में ऐसा कुछ भी स्टोर करने की उम्मीद नहीं होगी, क्योंकि CQRS में, कोई भी फॉरवर्डिंग मैकेनिज्म को छोड़कर रीड मॉडल को अपडेट नहीं करता है जो रीड मॉडल को परिवर्तनों के साथ सिंक में रखता है। मॉडल लिखें।

(# 3) CQRS में, प्रश्नों को रीड मॉडल के विरुद्ध जाना चाहिए। आप अलग कर सकते हैं: यह ठीक है, बस CQRS का पालन नहीं कर रहा है।


सारांश में, केवल एक वैचारिक डेटा मॉडल है। CQRS कमांड नेटवर्क और क्षमताओं को क्वेरी नेटवर्क और क्षमताओं से अलग करता है। यह देखते हुए कि लेखन मॉडल और रीड मॉडल को अलग-अलग करने से प्रदर्शन अनुकूलन के रूप में विभिन्न तकनीकों का उपयोग करके होस्ट किया जा सकता है।

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