16

اي الطريقتين اسرع واخف ومعتمدة اكثر للتعامل مع قواعد البيانات؟

  • NPro

غالبا ما تواجهني مواقع مثل آرابيا، واتساءل دائما كيف تعتمد هذه المواقع على حساب نقاط السمعة للعضو

تدور ببالي غالبا طريقتان، الاولى وهي كلما يضغط عضو على زر التقييم، يتم عمل استعلامتين لقواعد البيانات، الاولى لمشاركة العضو (لاضافة التقييم في المشاركة) والثانية لجدول الاعضاء، حيث توجد خانة تحتوي نقاط السمعة، تقوم باضافة او انقاص نقطة واحدة، وهذه الخانة هي التي تظهر في صفحة العضو.

الطريقة الثانية هي وجود جدول كامل خاص بنقاط السمعة، يحتوي على كل نقاط السمعة، وفي كل مرة يحصل فيها العضو على +1 يتم تسجيلها في هذا الجدول، وعند طلب صفحة العضو او التعليق، يتم عمل الحسابات الضرورية لاظهار النقاط المتحصل عليها.

ما رايكم؟ اي هاتين الطريقتين هي المعتمدة في الويب الحديث والتي تنصحوني باعتمادها؟

يرجى الدخول لحسابك أو تسجيل حساب لتستطيع إضافة تعليق
حساب جديد دخول

التعليقات

17

Arabia I/O يستخدم الطريقتين بنفس الوقت وفعلياً كلاهما ضروري وكل منهم له غرض. يوجد جدول يخزن جميع النقاط لكل موضوع ولكل تعليق وهذا يفيد في الكثير من الأمور منها دقة المعلومات وعدم تكرارها وهو الأساس، ويوجد أيضاً خانة لكل عضو ولكل موضوع ولكل تعليق تحتفظ بالقيمة الاجمالية للتخفيف على قاعدة البيانات في بعض الاستعلامات مثل ترتيب التعليقات حسب الأكثر تقييماً.

أيضاً لتسريع الأمور، يتم اضافة indexes لهذه الجداول ويتم الاعتماد على memcached و background jobs تعمل بفترات متفرقة لأمور تتطلب حساباً مثل ترتيب المواضيع في الرئيسية فهو يتم حسب عدة عوامل كتاريخ العضو بالموقع ومساهماته السابقة، تقييم المستخدمين للموضوع، الوقت الذي مضى على اضافة الموضوع والتعليقات التي فيه.

نفس الذى أستخدمه فى الكثير من برمجياتى ... جدول للتفاصيل أو إعادة إحتساب النقاط إن أردت .. وفى نفس الوقت +1 للعداد لمنع كثرة ال joins

10

في البرمجة هناك مفهوم يُسمّى مصدر وحيد للحقيقة (Single Source of Truth)، ومعناه باختصار أن تخزّن البيانات في موضع واحد وتبني عليه كل الحسابات الأخرى والتفاصيل لئلا يحدث اختلاف في النتائج عند اختلاف طريقة الوصول للبيانات، عمليًّا كثيرًا ما يتخلّى المطوّرون عن هذا المبدأ ويعيدون تكرار البيانات في أكثر من جدول لعدة أسباب أهمها الأداء. لاحظت مثلاً أنه عندما يحذف تعليق ما من قبل المشرفين في هذا الموقع، فإن عداد تعليقات المواضيع لا يتغير، وهو يعني أن عدد التعليقات يزاد بمقدار واحد عند كل إضافة لتعليق وليس يُحسب في كلّ مرة يُوصل فيها إلى الصفحة الحاوية على عدد التعليقات.

أغلب الضن أن التعليقات لا تحذف لكن يتم إخفاؤها فقط , جدول قاعدة البيانات الذي يحتوي ثقوب قد يصعب القيام ببعض الإستعلامات المعقدة , لهذا أضن أنه لن تجد إستعلام DELETE FROM في أربيا .

حسب ما قرأت من تعليق عبد المهيمن [1] ومحاولة فهم طريقة تفكيره وتمشيه البرمجي، اعتقد ان جدول المواضيع يحتوي على خانة تسمى عدد التعليقات، يتم اضافة +1 عند كل تعليق، لكن يتم نسيان ازالة 1 في صورة حذفه.

المشكل في هذه الطريقة هو ان تطور الموقع وتضخم عدد ال functions قد ينسيك امورا اساسية. مثلا، اذا تم حذف تعليق يحتوي على 10 تقييمات، لابد من انقاص عدد التقييمات هذه في خانة نقاط السمعة من جدول الاعضاء. هذه الامور من الصعب التفطن اليها اذا ما كبر الكود البرمجي الخاص بالموقع..

[1]

صدقت، ويزيد الأمر تعقيدا إن كنت تريد حظر التعليق، فقط وليس حذفه.

يكون معقداً إن لم تكن محترفاً و متقناً و مرتباً لعملك البرمجي .. لأنه مهما كبر العمل البرمجى فطالما هو منظم و مرتب و مكتوب بصبر وعناية و دقة .. فلن يكون من المعقد أبداً على من كتبه أن قوم بالتعديل فيه .. كمثال على ذلك :

يستخدم أحدهم دالة واحدة للحصول على بيانات عضو من قاعدة البيانات و هذه الدالة يضعها فى model إسمه users_model

و الآخر كلما أراد أن يحصل على بيانات عضو ما .. قام بكتابة إستعلام جديد فى ال controller و الدالة التى يتواجد فيها

الأول إن أراد أن يمنع عضوية معينه من التعامل مع البرمجية فكل ما عليه أن يتوجه إلى دالة الحصول على بيانات العضو ويقوم بتعديلها و من ثم فإنه ستتعدل فى كل الأماكن التى يتم مناداتها فيها

أما الثانى فعليه أن يقوم بالتعديل فى كافة أنحاء الموقع و كل الأماكن البرمجية التى ذكر فيها إستعلاماته عن الأعضاء

و هكذا المبدأ فى كل أنحاء الكود

هذا جدال لا ينتهي .. مثل فكرة معدل الطالب, هل نقوم بعمل خانة للمعدل, ام نقوم بحساب قيمة المعدل في كل مرة يتم الاستعلام عنه ؟

بلنسبة لي ..

لو كانت القيمة تتغير باستمرار والاستعلامات عليها كثيرة فأستعمل الطريقة الثانية, اما لو كانت القيمة تتغير بشكل قليل, او ان الاستعلامات عليها نادرة فأستعمل الطريقة الاولى ..

حسناً هذا انا في المجال النظري .. لكن حقيقةً غالباً ما اتبع الطريقة الثانية.

والافضل ان لا يضيع الوقت في امور مثل هذه, الاهم ان ينجز العمل بسرعة, في ما بعد نستطيع تغيير وتطوير ما نريد :)

ألا ترى أن بناء الموقع على قاعدة بيانات ليست مبنية بطريقة مثلى ، قد يعيق تطوير لاحقاً .

-

عن واقع تجربة بتطويري لعدد من المواقع بنية مسبقاً من قبل مبرمج أخر وقاعدة البيانات هزيلة ، عانيت العديد في وقت تطويرها ومعالجة البيانات .

-

لا يجب أن نستخدم في الموقع كل ما تحتويه قاعدة البيانات من جداول أو أو ، لكن على الأقل أرى أنه من الأفضل أن نبنيها على أسلوب وتوسع متين ، ولو كان الأمر الوقت مهم ، نقتصر أهم وأبرز ما نريد في الموقع ونطور الموقع لاحقاً لا قاعدة البيانات .

اخي العزيز .. هذا الامر لا علاقة له بطريقة مثلى ام لا ..

في كلا الحاليتين يجب تخزين المصوتين بلتقييم الايجابي او السلبي في قاعدة البيانات, لكن الفكرة في ان نضيف خانة اضافية لتخفيف الاستعلامات والموارد المستهلكة ام لا ..

وما يعيق التطوير هو بناء كود وقاعدة بيانات غير قابلين للتطوير, لا في بناء قاعدة بيانات او كود غير كامل.

لم تفهم قصدي أستاذي ، فما أقصده ، لو مثلاً قمنا بجمع التقييمات في حقل في جدول المواضيع ، أو قمنا فقط بتخزين المحصلة ، حين نقوم بتطوير الموقع ليسجل عمليات التقييم ، فالمواضيع الأولى ستكون فاقدة لأي تفاصيل ، وسيكون علينا مثلاً كتابة شرط أن يظهر فقط محصلة التقييم للمواضيع قبل تاريخ محدد ، أما إن كان يخزن رقم العضو مع التقييم ، فسيحتاج لمعالجة وتخزين من جديد .

-

ما قصدته بمثلى هي بناء قاعدة قابلة للتطوير ، فلا يوجد ما يسمى كود كامل ، فمالثالي هو أفضل ما يمكن الوصول به في الوقت الآني للعمل .

نعم اخي .. كلامك صحيح 100%

لكن فقط كنت اريد ان اقول لك ان ما اقصده هنا هو وضع خان ة اضافية ام لا ^_^

الثانية ، وذلك لمنع تقييم المتكرر والعديد من الامور ، فيجب أن يكون هناك جدول مخصص لتسجيل كل عمليات التقييم .

-

يمكن إنشائه بإعتماد طريقتيين تسجيل - حسب رأيي - :

  1. لكل مشاركة صف واحد ويتم تسجيل كل عمليات التقييم به .

  2. لكل عملية تقييم صف .

أود إضافة أمر ، الطريقة ثانية تفيد بأمر أهم ، وهو خوارزميات الترتيب .

فلا يعقل أن تنشأ خوارزمية ترتيب للمشاركات - اقصد المواضيع - ، دون تسجيل تفاصيل ، فلو كان بنفس جدول الموضوع ، فلا يمكن حساب ما هي المدة التي حصل فيها على نقاط ، الاعضاء المقييمين وما إلى ذلك .

-

أرابيا أتوقع تستخدم الطريقة الثانية ، وتوقعت ذلك ، بسبب الإشعارات الخاصة بإخبارك بان مشاركتك مميزة وما إلى ذلك ، فهو يحسب المدة التي حصلت بها على نقاط .

أظن أن آرابيا يستخدم التالي بالنسبة للإشعارات

عند كل تقييم جديد يتم مقارنة القيمة هل هي أكثر من 5، أو 10 إذا نعم، فيقوم بمقارنة الوقت الحالي ووقت إضافة التعليق هل هو أقل من 24 ساعة، إذا نعم فيقوم بإرسال إشعار

حسناً وكيف تفسر أننا لا يمكننا تقييم مرة أخرى ؟

يجب أن يتم تسجيل معرف كل حساب ، ليقارن به :)

يتم تسجيل IDs كل الأعضاء المصوتيين في array مثلما تسجل قيمة التقييم، ثم عند كل تصويت يتم مقارنة ID المصوت التي يتم إرساله بالموجود مسبقا، تتم بضع المقارنات المنطقية مثلا إذا أراد التصويت بالإيجاب وقد صوت بالسلب من قبل وهكذا

وكيف يتم معرفة ما نوع تقييم ، فلو أفترضنا أن هناك عامود في جدول المواضيع ، ويتم فيه تسجيل على طريقة تالية :

للإيجابي :

0:idUser,0:idUser2

للسلبي : 1:idUser,0:idUser2

-

أشعر بأن جدول منفصل يحسب كل تقييمات أفضل .

بل أي موقع يريد أن يرى إحصائيات أفضل عن الموقع وتطوره وحركة العمليات يجب أن يعتمد ع الثاني .

-

من ناحيتي أشعر أن أي موقع يريد أن يكون له مكانة ، سيبني قاعدة البيانات على أكبر قدر من تجميع تفاصيل مع تقليل من تراكم العشوائيات :)

حسنا سأقول لك بالطريقة التي استخدمتها أنا مع ووردبريس ومع comment meta و user meta

لكل تعليق جديد سوف يملك 3 comment meta (اعتبرهم 3 خانات في قاعدة البيانات)

الخانة الأولى، قيمة التعليق (int) (value)

الخانة الثانية، من قام بالتصويت الإيجابي (array) (upvoters)

الخانة الثالثة، من قام بالتوصيت السلبي (array) (downvoters)

الآن عندما يريد العضو 15 التصويت بشكل إيجابي، يتم إرسال طلب يحتوي (ID التعليق، ID المعلق، نوع التصويت)

يتم أولا مقارنة ID المصوت مع ID صاحب التعليق إذا كان متشابهان، فيخرج

وإلا، يتم تحديد نوع التصويت، هل هو إيجابي أو سلبي ليتم التفصيل أكثر

بعدها، إذا كان إيجابي مثلا، يتم مقارنة ID العضو في قائمة الأعضاء أصحاب التصويت الإيجابي upvoters إذا كان موجود فيها فيتم الخروج

وإلا، الآن يتم مقارنة ID العضو من قائمة أصحاب التصويت السلبي، إذا كان موجود فيها فيتم

رفع قيمة التعليق value

حذف ID العضو من قائمة التصويت السلبي downvoters

ثم الخروج

وإلا

رفع قيمة التعليق value

إضافة ID العضو إلى قائمة المصوتيين الإيجابيين upvoters

نفس الأمر بالنسبة إذا كان تصويت سلبي ولكن العكس فحسب

الطريقة جميلة ، ومختصرة ومفيدة .

-

قد يكون الفرق بينها وبين بناء جدول منفصل هو وجود تفاصيل أكثر ، وجمع كل تقييمات لكل شيء في جدول ، وجعل للتقيمات مكان واحد للجلب .

للسلبي : 1:idUser,0:idUser2

للسلبي :

1:idUser,1:idUser2

وأيضاً كيف يتم ترتيب في صفحة الرئيسية لأرابيا ، لآ أتوقع سيحسب كم عدد تقييمات خلال 24 ساعة ، لأنها لن تكون بنفس الدقة التي عليها الان .

خوارزمية الصفحة الرئيسية تعتمد على عدد التقييمات + عدد التعليقات والمتحكم الأكبر هو قدم الموضوع، في البداية تتشاجر عدد التقييمات وعدد التعليقات فيما بينها، ولكن بعد مرور زمن معين، ينخفظ الموضوع مباشرة مهما حصل بعدها على تقييمات

كنت أتوقع أن الخوارزمية تعتمد على نشاط الموضوع ، فمثلاً لو يوجد موضوع بعد 12 ساعة حصل ع 7 تقييمات ، وفي نفس الوقت هناك مواضيع حديثة حصلت على 7 تقييمات أو 6 ولكنها أحدث ، فأتوقع أن الأقدم الذي حصل على عدد تقييمات في وقت قصير ولو قديم هو الأولى بالظهور على الجديد الذي يكون قد حصل على تقييمات بشكل متفارق ، هذا لو أردنا الترتيب حسب نشاط الموضوع .

هذا الموقع يستعمل الطريقة الأولى و هي الطريقة المختصرة

أنا افضل الطريقة الثانية (لاسباب متعددة) ولا داعي لاستخدام الطريقة الثانية الا اذا كان تحديد نقاط السمعة امر مهم فعلا (و لا أقصد انه هنا غير مهم)

أنا استخدمت الطريقة الأولى، أو شيء أشبه بهذا (في ووردبريس)

عند الضغظ على تقييم إيجابي أو سلبي، يتم استعلام إلى قاعدة البيانات ليتم رفع أو إنزال قيمة التصويت الخاصة بالتعليق، أي هناك خانة لكل تعليق تحتوي قيمة التصويت

ويتم عمل استعلام لرفع أو تقليل قيمة السمعة لعضو ما عبر ID الخاص به

وعند الإظهار يتم سحب سحب القيمة مع التعليق، وعند الدخول لصفحة العضو يتم حسب قيمة السمعة الكلية

عند حذف تعليق فيتم إطلاق دالة قبل الحذف حيث تأخذ قيمة التصويت للتعليق وتطرحها من قيمة تصويت العضو الإجمالية ثم يتم حذف التعليق

الموضوع مشابه لمعدل الطالب مثل ما ذكر احد الاعضاء، هذه البيانات تكون نتيجة لعمليات حسابية، ومثل هذه النتائج لا تحفظ في قاعدة البيانات بل تحسب برمجيا ويتم حسابها في وقت تنفيذ البرنامج، او يتم استدعائها عن طريق procedure او ممكن يكون لها جدول افتراضي View المهم انه لا تكون في هيكلة قاعدة البيانات الاساسية، والسبب لعدة امور اهمها تقليل الضغط على قاعدة البيانات و هيكلة قاعدة البيانات تكون بشكل سليم.

حتى في الواقع الحقيقي مثل هذه البيانات لا تحفظ لانها بيانات تنتج وفق عمليات حسابيات وليس بيانات ثابته، مثلا في العمل لو قررت المنشئة مكافئة العمال المواظبين على الحظور، لا يتم تسجيل في ملف الشخص ان هذا الشخص مواظب على حضورة ام لا، لكن يتم حسابه عن طريق ساعات العمل التي حضرها وساعات العمل المقرره لينتج هل هو مواظب على الحضور ام لا.