لماذا أنا أكره الـStored Procedures « مغامرات برمجية

لماذا أنا أكره الـStored Procedures

نّشر في: 2012/04/01
تعليقات: 11 تعليق

أنا أعرف أن عنوان المدونة يبدو كنوع من الهرطقة أو التجديف، بالذات لنا نحن مبرمجي تطبيقات الأعمال الذي تم ترسيخ فكرة أن الـstored procedures بأهمية الماء للعطشان في عقولنا من خلال مئات الدروس والدورات والمؤتمرات. قد يراود البعض الشك في أن هذا العنوان هو مجرد أسلوب رخيص لجذب الانتباه، على طريقة الصحافة الصفراء والمنتديات الوردية. ولكنني هنا لأؤكد لكم أنني، كمبرمج تطبيقات له عشرة سنوات في هذا المجال وبكامل قواه العقلية والجسدية والبرمجية، أكره الـstored procedures كره العمى وأتجنب استخدامها. ولب هذه المدونة هي حججي وبراهيني. وأرحب بجميع الانتقادات والتعليقات.

لنبدأ أولاً بسرد الأسباب الكلاسيكية التي يسردها الجميع كحجة لاستخدام الـstored procedures ونحفظها كلنا كإكليشة نستخدمها في المقابلات الشخصية:

1. كطبقة ولوج إلى قاعدة البيانات منفصلة عن بقية البرنامج، أو ما يسموه الفرنجة Data Access Layer، تطبيقاً لهيكلة تعدد الطبقات n-Tier Architecture.

2. في معظم قواعد البيانات يتم عمل شئ شبيه بالـcompile للـstored procedures (يدعى execution plan) يسرع من عملها مقارنةً بجمل الـSQL العادية.

 

شئ جميل جداً وصحيح أيضاً. إذن ما هو سبب تحفظي ما دمت أتفق معكم أن النقطتين بعاليه صحيحتين؟

السبب هو نفس السبب الذي يجعلنا لم نعد نقوم ببرمجة تطبيقات كاملة بلغى الأسيمبلي: التكلفة.

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

لننظر أولاً إلى النقطة الأولى: الـstored procedures كفصل للطبقات البرمجية.

أنا من أكبر مشجعي فكرة بتقسيم البرنامج إلى ما يدعى loosely coupled objects. يمكنني ترجمة هذا المصطلح كـ”الكائنات الضعيفة الترابط”. ما يعنيه هذا هو تقسيم البرنامج إلى أجزاء يسهل فصلها عن بعض. وبعد ذلك تركيبها مع بعض مرة أخرى أو حتى مع أجزاء مختلفة. التقسيم الكلاسيكي (لكن حتماً ليس الوحيد) هو إلى ثلاثة أجزاء رئيسية: طبقة واجهة الاستخدام، طبقة قوانين ومنطق العمل، وطبقة الولوج في قاعدة البيانات. بهذه الطريقة إذا قررت مثلاً تحويل تطبيقك الويب إلى تطبيق WPF مثلاً، ليس عليك سوى إعادة برمجة جزء واحد فقط وهو واجهة المستخدم. واستخدام الـstored procedures كطبقة ولوج قاعدة البيانات هي فكرة ممتازة.

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

من ناحية أخرى، الـstored procedure ليست ضعيفة الارتباط تماماً. هناك ارتباط قوي ووثيق جداً بينها وبين قاعدة البيانات. رغم أن لغة SQL قياسية، إلا أن كل قاعدة بيانات تستخدمها بطريقة مختلفة وتضيف إليها أشياء جديدة قد لا تكون موجودة بنفس الشكل (إذا كانت موجودة أصلاً) في قواعد البيانات الأخرى. الترقيم الآلي مثلاً يتم عمله في SQL Server بشكل مختلف تماماً عن طريقة عمله في Oracle ولا يمكن ترجمته بسهولة. لذا، إذا غيرنا قاعدة البيانات التي نستخدمها في تطبيقنا لأي سبب من الأسباب ستجد أنك ستحتاج لاستبدال جميع الـstored procedures.

لنكمل إلى النقطة الثانية: الـstored procedure كعامل تسريع. لا يوجد شك أن الـstored procedure أسرع من استخدام الـSQL العادية. ولكن كما ذكرت هناك عامل تكلفة. لنتحدث عن هذا.

في التطبيق العادي ستجد عشرات الجداول في قاعدة البيانات. وقد تصل إلى المئات في بعض التطبيقات الضخمة. بطبيعة الحال سيكون عدد العمليات التي يتم إجراؤها على هذه الجداول أضعاف هذا الرقم. أي أننا نتحدث عن مئات الـstored procedures. لنتغاضى الآن عن تكلفة برمجتها. هناك العديد من الأدوات التي تقوم بإنشاء الـstored procedures آلياً، وبرمجة مثل هذه الأدوات ليس بتلك الصعوبة. ولكن لننظر إلى ما هو أدهى: الصيانة.

البرامج والتطبيقات مثل الكائنات الحية. لا تحيا في فراغ وتحتاج من وقت لآخر لبعض الاهتمام، بالذات في بداية حياتها. عندما تقوم بتغيير شئ في كود البرنامج العادي، فإنه من السهل معرفة الأشياء المرتبطة به. لكن الأمر ليس بهذه السهولة في الـstored procedures. نعم يمكننا حل هذه المشكلة بتوثيق الارتباطات الفرعية بين الـstored procedures والجداول وغيرها، ولكن هذه تكلفة إضافية.

وماذا عن التحكم في المصدر source control وإدارة الإصدارات versioning؟ عندما يكون لديك تطبيق كبير هذا يعني بالضرورة أكثر من مبرمج واحد (إلا إذا كنت في أحد تلك الشركات، عندها ليس لدي سوى إعراب تعازي الحارة). وعندما يكون لديك أكثر من مبرمج واحد علينا إدارة كيفية تغيير البرنامج. وإذا كنا نفكر في تطوير البرنامج أكثر وإنتاج إصدارات مستقبلية، عندها يصبح من الضروري التحكم في محتوى هذه الإصدارات والتغييرات فيما بينها. بالنسبة للكود هناك العديد والعديد من الأدوات مثل TFS وSubversion وMercurial (الأخيرتين مجانيتين)، لكن ماذا عن الـstored procedures؟ لا توجد طريقة سهلة للقيام بهذا العمل. وهذه تكلفة إضافية.

إذا أردت تخزين الكود وأرشفته فهذا موضوع سهل لدرجة أنك لا تحتاج أن تفكر فيه. ماذا عن الـstored procedures؟ إذا أدرت أرشفتها بشكل منفصل عن قاعدة البيانات فعليك تحويلها إلى ملفات script. تكلفة إضافية.

إذا كانت لديك إصلاحات في الكود لتطبيق قائم، فتطبيق هذه الإصلاحات سهل، وقد لا يعدو إيقاف البرنامج ونسخ ملفات جديدة وتشغيل البرنانج ثانية. ولكن في الـstored procedure، كونها جزئاً من قاعدة البيانات الحساسة جداً فعليك أن تكون أكثر حرصاً, عليك وضع خطة عمل دقيقة جداً لتطبيق أي تغيير بحيث لا يؤثر في البيانات الحية. تكلفة إضافية!

سيقول البعض: ولكن ماذا في ذلك؟ تكلفة إضافية، تكلفة إضافية، تكلفة إضافية! أليس هذا ثمناً بخساً لما نحصل عليه؟

جوابي هو: ليس دائماً!

دعني أضيف أحد أشهر الحٍكم في عالم البرمجة وأقربها إلى قلبي:

“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil”

- Donald Knuth

علينا أن ننسى كفائات العمل الصغيرة، في حوالي 97% من المرات: تحسين الأداء المبكر هو أساس كل الشرور.”

- دونالد كنوث

 

التفكير في تحسين الأداء قبل حتى أن نعرف ما هو الشئ الذي نحتاج تحسينه هو أسرع طريق لتعقيد البرنامج أكثر من اللزوم، وبالتالي زيادة تكلفته. لهذا السبب أنا أتعامل مع الـstored procedures كما أتعامل مع الأسيمبلي: كشئ خطر أستخدمه وقت الضرورة فقط.

قبل أن يذهب فكركم بعيداً أنا لا أنادي بعدم استخدام الـstored procedures بتاتاً وإلى الأبد. كما ذكرت في تشبيهي السابق بلغة الأسمبلي: الـstored procedures أداة مهمة جداً ولها مكانها. عندما يكون لدي جزء في برنامجي أحتاج فيه إلى تحسين الأداء (بعد التجربة على أرض الواقع) ألجاً حينها إلى الـstored procedure. حين تكون هناك عملية مرتبطة ارتباطاً وثيقاً بقاعدة البيانات نفسها، عندها ألجأ إلى الـstored procedures.

ما أرفض عمله هو استخدام الـstored procedures في كل صغيرة وكبيرة. وأن أبني تطبيقاً كاملاً مبنياً على طبقة هشة كتلك.

ولأكون واضحاً أيضاً، أنا ضد تلك البرامج التي تتناثر فيها جمل الـSQL في كل مكان من غير ترابط أو ترتيب منطقي. مما ينتج عنه مشاكل إضافية لا تقل خطورة عن تلك التي تحدثت عنها في الـstored procedures. لحسن الحظ هذه الأيام هناك الكثير من حلول الـORM (وهي برمجيات هدفها تحويل إجراءات قواعد البيانات إلى كود) في متناول اليد لجميع اللغات والـplatforms، لذا أصبح من السهل بناء طبقة الولوج من الكود بشكل كامل.

أترككم بنصيحة واحدة: إذا كان ولابد من استخدام الـstored procedures، فعاملوها بكثير من الحذر والاهتمام!

Post to Twitter

11 تعليق - أضف تعليق
  1. Wael Dalloul قال:

    يسلم فمك, التكلفة اصبح عامل مهم جداً عند بناء اي تطبيق, الشيئ المعقد فعلاً هو إذا أردت تغيير بعض الحقول في قاعدة البيانات, هنا عليك إعادة فحص أغلب الاجراءات المخزنة و من ثم تعديلها عند الزبائن, ولو عن طريق الخطأ قمت بكتابة تعليمة غير صحيحة…
    إيضاًَ عند بناء تطبيقات الأعمال للأجهزة الكفية(Windows Mobile لا يمكنك الاستفادة من الاجراءات المخزنة كون SQLCE لا يتعامل معها.

  2. Mosh قال:

    لكن لم تظهر البديل، انا اتفق معك بنقطة واحدة (هي الصيانة على الكود في تطبيق قائم) تلك ستكون صعبة بعض الشيء، لكن ال SP تمثل ال Centralization لقواعد البيانات، اليس كذلك؟

    • System Down قال:

      البديل هو التعامل مع قاعدة البيانات مباشرة من الكود. إما باستخدام جمل الـSQL مباشرة (لكن حذاري من الـSQL Injection!) أو باستخدام برمجيات الـORM أو ما شابه.

      بالنسبة للـcentralization، عن أي centralization نتحدث هنا؟ تلك الخاصة بالبيانات وتخزينها؟ هذه ما زالت تحت سيطرة قاعدة البيانات. الـdata access layer ليست سوى همزة وصل بينها وبين منطق البرنامج. أي أننا عندما ننقل جزءاً من منطق البرنامج إلى قاعدة البيانات فنحن نضعف centralization أخرى، تلك الخاصة بمنطق البرنامج أو ما يدعى Business Layer أو Logic Layer.

  3. محمد سميح قال:

    السلام عليكم ورحمه الله وبركاته
    جزاكم الله الخير كله اخى الحبيب على هذة المقالة واسال الله ان يجعلها فى ميزان حسناتك باذن الله

    متفق معك على ان تكلفة ال Stored procedure وهى مشكلة كبيرة

    ولكن لى سوال بخصوص ال VCS كيف يتم ادراج ال DB والتعامل معها فى ال VCS

    • System Down قال:

      ماذا تقصد بـVCS؟

      • محمد سميح قال:

        اقصد بال VCS
        Version control systems

        • System Down قال:

          مشكلة الـDB (وبالتالي الـstored procedures) هي أنها جزء حي ومتغير من النظام، لذا يصعب أرشفتها. قد تستطيع إضافة أحد الـbackups أو ملفات الـscript الخاصة به، ولكن لا أعلم بطريقة أفضل من ذلك.

  4. معتز قال:

    أشاركك كرهي للـ Stored Procedure وفي آخر البرامج التي صرت أكتبها صرت أتجنت الـ Stored procedure، مثلاً قُمت بكتابة نظام حسابات ومخازن بإستخدام قاعدة البيانات فيربيرد ليس فيه أي Stored Procedures. والأسباب وراء كرهي لها بالإضافة لما ذكرت هو:
    - أنها structured وأحب أن استخدم فقط الـ Object Oriented في التعامل مع البيانات
    - احس أن البرنامج معرض للخطر، حيث يمكن أن يتم تغير stored procedure بواسطة أي برنامج من برامج إدارة قواعد البيانات فيتغير ناتج البرنامج.
    - كما ذكرت تعديل النُسخ، فعندما تكون طبقة التعامل مع البيانات داخل البرنامج يسهل تعديلها وإعادة توزيعها أو عمل Upgrade بالنسبة للمستخدمين دون الحاجة لعمل تغيير في قاعدة البيانات.
    - قاعدة البيانات هي هيكل بيانات وبيانات فقط وليس الهدف منها أن يكون فيها جزء من الكود.

  5. This article will help the internet visitors for building up new webpage
    or even a blog from start to end.

  6. The single defining characteristic of tax advantaged investments is this: the investor receives a cash flow from the investment, but this cash flow is subject
    to a tax rate that is lower than the investor’s personal tax rate for ordinary income.
    There are two broad types of investments that have some form of preference to the taxable investor: tax
    advantaged investments and tax deferred investments. Managing a single project is difficult enough for a project manager but
    when a project manager is responsible for
    managing multiple projects, this task can become absolutely terrifying.

أضف تعليق

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

*

يمكنك استخدام أكواد HTML والخصائص التالية: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


مرحباً , تاريخ اليوم هو الخميس, 2017/03/23