كيف يمكن ترجمة متطلبات العمل إلى هياكل بيانات محددة باستخدام مثال لتصميم قاعدة "من الصفر" للرسول؟

لن تكون قاعدة البيانات الخاصة بنا كبيرة وموزعة
مثل قاعدة بيانات
VKontakte أو
Badoo ، ولكن "لتكون" ، لكنها جيدة - وظيفية وسريعة
وتتناسب مع خادم PostgreSQL
واحد - بحيث يمكنك نشر نسخة منفصلة من الخدمة في مكان ما على الجانب ، على سبيل المثال.
لذلك ، لن نتطرق إلى مشكلات التقاسم والتكرار والنظم الجغرافية الموزعة ، بل نركز على حلول الدوائر داخل قاعدة البيانات.
الخطوة 1: قليلا من خصوصية العمل
لن نقوم بتصميم مراسلاتنا في الملخص ، لكننا سنضمّنها في بيئة
الشبكة الاجتماعية للشركات . بمعنى أن الأشخاص في مكاننا ليسوا "مجرد رسائل نصية" ، ولكن التواصل مع بعضهم البعض في سياق حل بعض مشكلات العمل.
وما هي تحديات الأعمال؟ .. دعونا نلقي نظرة على مثال فاسيلي ، رئيس قسم التطوير.
- "نيكولاي ، هذا التصحيح يحتاج إلى هذا التصحيح اليوم!"
لذلك ، يمكن إجراء المراسلات في سياق المستند . - "كوليا ، اذهب إلى DotA في المساء؟"
أي أنه حتى مع وجود زوج واحد من المحاورين ، يمكن إجراء الاتصالات في نفس الوقت حول مواضيع مختلفة . - "بيتر ، نيكولاي ، انظر إلى ملحق السعر على الخادم الجديد."
لذلك ، يمكن أن تحتوي رسالة واحدة على عدة مستلمين . في هذه الحالة ، قد تحتوي الرسالة على ملفات مرفقة . - "سيميون ، وأنت تبدو أيضًا."
ويجب أن يكون من الممكن دعوة عضو جديد إلى المراسلات الحالية.
دعونا نتطرق إلى قائمة الاحتياجات "الواضحة" هذه.
بدون فهم التفاصيل المطبقة للمهمة والقيود التي تحددها ، من المستحيل عملياً تصميم مخطط قاعدة بيانات فعال لحلها.
الخطوة 2: الحد الأدنى من المنطق
حتى الآن ، يبدو كل شيء مشابهًا جدًا لمراسلات البريد الإلكتروني - وهي أداة أعمال تقليدية. لذا ، نعم ، "خوارزميًا" ، تتشابه العديد من مهام العمل مع بعضها البعض ، وبالتالي ستكون أدوات حلها متشابهة من الناحية الهيكلية.
دعونا إصلاح المخطط المنطقي الناتج عن العلاقات بين الكيانات. لسهولة فهم نموذجنا ، سنستخدم الخيار الأكثر بدائية لعرض
نموذج ER دون تعقيدات تدوينات UML أو IDEF:

في مثالنا ، يكون الشخص والمستند و "النص" الثنائي للملف كيانات "خارجية" موجودة بشكل مستقل دون خدمتنا. لذلك ، سوف نعتبرهم ببساطة في المستقبل بعض الروابط "في مكان ما" بواسطة UUID.
ارسم المخططات بأكبر قدر ممكن - معظم أولئك الذين ستظهر لهم ليسوا خبراء في قراءة UML / IDEF. ولكن - تأكد من التعادل.
الخطوة 3: رسم هيكل الجدول
حول الجدول وأسماء الحقوليمكن التعامل مع الأسماء "الروسية" للحقول والجداول بشكل مختلف ، ولكن هذه مسألة ذوق. نظرًا لعدم وجود مطورين أجانب
في "Tensor" ، ويسمح لنا PostgreSQL بإعطاء أسماء حتى مع الحروف الهيروغليفية ، إذا كانت
مرفقة بعلامات اقتباس ، فنحن نفضل تسمية الكائنات بشكل لا لبس فيه بوضوح ، حتى لا يكون هناك سوء فهم.
نظرًا لأن العديد من الأشخاص يكتبون الرسائل في وقت واحد ، يمكن للبعض منهم القيام بذلك في وضع
عدم الاتصال ، فإن الخيار الأسهل هو
استخدام UUIDs كمعرفات ليس فقط للكيانات الخارجية ، ولكن لجميع الكائنات داخل خدمتنا. علاوة على ذلك ، يمكن إنشاؤها حتى من جانب العميل - سيساعدنا ذلك في دعم إرسال الرسائل مع عدم إمكانية الوصول إلى قاعدة البيانات على المدى القصير ، واحتمال حدوث تصادم ضئيل للغاية.
سيبدو الهيكل التقريبي للجداول في قاعدة البيانات لدينا كما يلي:
الجداول: RUCREATE TABLE ""( "" uuid PRIMARY KEY , "" uuid , "" text ); CREATE TABLE ""( "" uuid PRIMARY KEY , "" uuid , "" uuid , "" timestamp , "" text ); CREATE TABLE ""( "" uuid , "" uuid , PRIMARY KEY("", "") ); CREATE TABLE ""( "" uuid PRIMARY KEY , "" uuid , "BLOB" uuid , "" text );
الجداول: EN CREATE TABLE theme( theme uuid PRIMARY KEY , document uuid , title text ); CREATE TABLE message( message uuid PRIMARY KEY , theme uuid , author uuid , dt timestamp , body text ); CREATE TABLE message_addressee( message uuid , person uuid , PRIMARY KEY(message, person) ); CREATE TABLE message_file( file uuid PRIMARY KEY , message uuid , content uuid , filename text );
أسهل طريقة لوصف التنسيق هي البدء في "إزالة" الرسم البياني للروابط من الجداول التي لا تشير إلى أي شخص آخر.
الخطوة 4: اكتشاف متطلبات غير واضحة
هذا كل شيء ، لقد قمنا بتصميم قاعدة يمكنك من خلالها الكتابة والقراءة
بطريقة أو بأخرى .
دعونا نضع أنفسنا في مكان مستخدم خدمتنا - ماذا نريد أن نفعل به؟
- المشاركات الأخيرة
هذا هو سجل لرسائل "بلدي" مرتبة زمنيا حسب الخصائص المختلفة. أين أنا واحد من المستلمين ، حيث أنا المؤلف ، حيث كتبوا إلي ، لكنني لم أرد ، حيث لم يردوا ... - المراسلات المشاركين
من يشارك في هذه الدردشة الطويلة الطويلة؟
هيكلنا يتيح لنا حل كل من هذه المشاكل "بشكل عام" ، ولكن بسرعة - لا. تكمن المشكلة في أنه بالنسبة للفرز كجزء من المهمة الأولى ،
من المستحيل إنشاء فهرس مناسب لكل من المشاركين (وسيكون عليك استرداد جميع السجلات) ، ولحل المشكلة الثانية ، تحتاج
إلى استرداد جميع الرسائل المتعلقة بالموضوع.
يمكن لمهام المستخدم غير المتوقعة وضع حد للإنتاجية .
الخطوة 5: إزالة الصواب المعقول
ستساعد كلتا مشكلتنا في حل الجداول الإضافية ، حيث سنقوم
بتكرار جزء من البيانات اللازمة لتشكيل فهارس مناسبة لمشاكلنا عليها.

الجداول: RU CREATE TABLE ""( "" uuid , "" smallint , "" timestamp , "" uuid , PRIMARY KEY("", "", "") ); CREATE INDEX ON ""("", "", "" DESC); CREATE TABLE ""( "" uuid , "" uuid , PRIMARY KEY("", "") );
الجداول: EN CREATE TABLE message_registry( owner uuid , registry smallint , dt timestamp , message uuid , PRIMARY KEY(owner, registry, message) ); CREATE INDEX ON message_registry(owner, registry, dt DESC); CREATE TABLE theme_participant( theme uuid , person uuid , PRIMARY KEY(theme, person) );
قمنا هنا بتطبيق طريقتين نموذجيتين تستخدم لإنشاء الجداول المساعدة:
- سجلات الضرب
نقوم بتكوين عدة سجلات مصدر دفعة واحدة من سجل مصدر واحد للرسالة إلى أنواع مختلفة من السجلات لأصحابها المختلفين - لكل من المرسل والمستلم. لكن كل سجل من السجلات يضع الآن على الفهرس - لأننا في الحالة النموذجية نريد أن نرى فقط الصفحة الأولى. - سجل فريد من نوعه
في كل مرة ترسل فيها رسالة داخل موضوع معين ، يكفي التحقق من وجود مثل هذا الإدخال بالفعل. إذا لم يكن كذلك ، فأضفه إلى "قاموسنا".
في الجزء التالي من المقالة ، سنناقش
تنفيذ التقسيم في بنية قاعدة البيانات الخاصة بنا.