ايهما افضل:الاستعلامات المخصصة أو الإجراءات المخزنة؟[مغلق]

StackOverflow https://stackoverflow.com/questions/22907

  •  09-06-2019
  •  | 
  •  

سؤال

بافتراض أنك لا تستطيع استخدام LINQ لأي سبب كان، هل من الأفضل وضع استعلاماتك في الإجراءات المخزنة، أم أنها ممارسة جيدة للتنفيذ مخصصة الاستعلامات ضد قاعدة البيانات (على سبيل المثال، SQL Server من أجل الحجة)؟

هل كانت مفيدة؟

المحلول

في تجربتي في كتابة تطبيقات WinForms Client/Server، هذه هي الاستنتاجات البسيطة التي توصلت إليها:

استخدام الإجراءات المخزنة:

  1. لأي عمل بيانات معقدة.إذا كنت ستفعل شيئًا يتطلب حقًا مؤشرًا أو جداول مؤقتة، فعادةً ما يكون من الأسرع القيام بذلك ضمن SQL Server.
  2. عندما تحتاج إلى تأمين الوصول إلى البيانات.إذا لم تمنح حق الوصول إلى الجدول للمستخدمين (أو الدور أو أي شيء آخر)، فيمكنك التأكد من أن الطريقة الوحيدة للتفاعل مع البيانات هي من خلال مقدمي الخدمة الذين تقوم بإنشائهم.

استخدم الاستعلامات المخصصة:

  1. بالنسبة إلى CRUD عندما لا تحتاج إلى تقييد الوصول إلى البيانات (أو تفعل ذلك بطريقة أخرى).
  2. لعمليات البحث البسيطة.يعد إنشاء SP لمجموعة من معايير البحث أمرًا صعبًا ويصعب الحفاظ عليه.إذا كان بإمكانك إنشاء استعلام بحث سريع إلى حد معقول، فاستخدم ذلك.

في معظم تطبيقاتي، استخدمت كلاً من SP وad-hoc sql، على الرغم من أنني أجد أنني أستخدم SP's بشكل أقل فأقل حيث ينتهي بهم الأمر إلى أن يصبحوا تعليمات برمجية تمامًا مثل C#، إلا أنه من الصعب التحكم في الإصدار واختباره وصيانته.أوصي باستخدام SQL المخصص ما لم تتمكن من العثور على سبب محدد لعدم القيام بذلك.

نصائح أخرى

لا أستطيع التحدث إلى أي شيء آخر غير SQL Server، ولكن وسيطة الأداء هي لا صالح بشكل كبير هناك إلا إذا كنت تستخدم الإصدار 6.5 أو ما قبله.يقوم SQL Server بتخزين خطط التنفيذ المخصصة مؤقتًا منذ ما يقرب من عقد من الزمن.

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

من خلال تضمين الاستعلامات في تطبيقك، فإنك تربط نفسك بإحكام بنموذج البيانات الخاص بك.

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

من الناحية الأمنية، من الممارسات الجيدة عدم السماح بـ db_datareader وdb_datawriter من التطبيق الخاص بك والسماح فقط بالوصول إلى الإجراءات المخزنة.

أعتقد أن هذا صراع أساسي بين الأشخاص الذين يجب عليهم الحفاظ على قاعدة البيانات والأشخاص الذين يقومون بتطوير واجهات المستخدم.

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

قواعد البيانات ليست موجهة للكائنات، والتعليمات البرمجية التي تبدو جيدة من منظور موجه للكائنات يمكن أن تكون سيئة للغاية من منظور قاعدة البيانات.

يخبرنا مطورونا أنهم سعداء لأن كل الوصول إلى قاعدة البيانات لدينا يتم من خلال procs لأنه يجعل إصلاح الأخطاء التي تركز على البيانات أسرع بكثير ثم تشغيل proc ببساطة في بيئة الإنتاج بدلاً من إنشاء فرع جديد من التعليمات البرمجية وإعادة الترجمة والترجمة إعادة التحميل للإنتاج.نحن نطلب أن تكون جميع عملياتنا في حالة تخريب، لذا فإن التحكم بالمصدر ليس مشكلة على الإطلاق.إذا لم يكن في Subversion، فسيتم إسقاطه بشكل دوري بواسطة dbas، لذلك لا توجد مقاومة لاستخدام التحكم في المصدر.

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

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

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

أود أن أقتبس من Tom Kyte من Oracle هنا...إليك قاعدته حول مكان كتابة التعليمات البرمجية...على الرغم من أنها غير ذات صلة بعض الشيء ولكن من الجيد معرفتها على ما أعتقد.

  1. ابدأ بالإجراءات المخزنة في PL/SQL...
  2. إذا كنت تعتقد أنه لا يمكن تنفيذ شيء ما باستخدام الإجراء المخزن في PL/SQL، فاستخدم إجراء Java المخزن.
  3. إذا كنت تعتقد أنه لا يمكن تنفيذ شيء ما باستخدام إجراء Java Stored، ففكر في Pro*c.
  4. إذا كنت تعتقد أنك لا تستطيع تحقيق شيء ما باستخدام Pro*C، فقد ترغب في إعادة التفكير في ما تحتاج إلى إنجازه.

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

  • بسهولة الحصول على كافة الاستعلامات تحت التحكم في الإصدار
  • لإجراء التغييرات المطلوبة على كل استعلام لخوادم قواعد البيانات المختلفة
  • يلغي تكرار نفس رمز الاستعلام من خلال الكود الخاص بنا

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

إجابتي من مختلف بريد:الإجراءات المخزنة هي أكثر قابلة للصيانة بسبب:

  • ليس عليك إعادة ترجمة تطبيق C# الخاص بك عندما تريد تغيير بعض SQL
  • ينتهي بك الأمر إلى إعادة استخدام كود SQL.

تكرار الكود هو أسوأ الشيء الذي يمكنك القيام به عندما تحاول إنشاء تطبيق قابل للصيانة!

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

في رأيي، تعتبر مكاسب الأداء والأمان ميزة إضافية. لا يزال بإمكانك كتابة إجراءات SQL المخزنة غير الآمنة/غير الفعالة.

أسهل في النقل إلى قاعدة بيانات أخرى - لا توجد إجراءات للمنفذ

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

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

إن الحجة القائلة بأن الإجراءات المخزنة أكثر كفاءة لم تعد صالحة بعد الآن.نص الرابط

سيؤدي إجراء google للإجراءات المخزنة مقابل الاستعلام الديناميكي إلى إظهار الحجج المناسبة في كلتا الحالتين وربما يكون الأفضل بالنسبة لك لاتخاذ قرارك ...

يجب استخدام إجراءات المتجر قدر الإمكان، إذا كانت كتابتك لـ SQL في التعليمات البرمجية تهيئ نفسك بالفعل للصداع في العقود الآجلة.يستغرق كتابة SPROC نفس الوقت تقريبًا كما هو الحال في كتابته في التعليمات البرمجية.

ضع في اعتبارك استعلامًا يتم تشغيله بشكل رائع تحت حمل متوسط، ولكن بمجرد دخوله مرحلة الإنتاج بدوام كامل، يؤدي الاستعلام المحسّن بشكل سيئ إلى ضرب النظام وإحضاره إلى الزحف.في معظم خوادم SQL، أنت لست التطبيق/الخدمة الوحيدة التي تستخدمها.جلب طلبك الآن مجموعة من الأشخاص الغاضبين إلى باب منزلك.

إذا كانت لديك استفساراتك في SPROCs، فإنك تسمح أيضًا لـ DBA الصديق الخاص بك بالإدارة والتحسين دون إعادة ترجمة تطبيقك أو تعطيله.تذكر أن DBA هم خبراء في هذا المجال، وهم يعرفون ما يجب عليهم فعله وما لا يفعلونه.فمن المنطقي الاستفادة من معرفتهم أكبر!

يحرر:قال أحدهم أن إعادة الترجمة هي عذر كسول!نعم، دعنا نرى مدى شعورك بالكسل عندما يتعين عليك إعادة ترجمة تطبيقك ونشره على آلاف أجهزة سطح المكتب، كل ذلك لأن مسؤول قواعد البيانات (DBA) أخبرك أن استعلامك المخصص يستهلك الكثير من وقت الخادم!

قال أحدهم أن إعادة الترجمة هي عذر كسول!نعم، دعنا نرى مدى شعورك بالكسل عندما يتعين عليك إعادة ترجمة تطبيقك ونشره على آلاف أجهزة سطح المكتب، كل ذلك لأن مسؤول قواعد البيانات (DBA) أخبرك أن استعلامك المخصص يستهلك الكثير من وقت الخادم!

هل هي بنية نظام جيدة إذا سمحت بتوصيل 1000 جهاز كمبيوتر مكتبي مباشرة بقاعدة البيانات؟

بعض الأشياء التي يجب التفكير فيها هنا: من الذي يحتاج إلى الإجراءات المخزنة، على أي حال؟

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

تعتبر الإجراءات المخزنة رائعة لأنه يمكن تغييرها دون إعادة الترجمة.سأحاول استخدامها كلما كان ذلك ممكنا.

أنا فقط أستخدم المخصص للاستعلامات التي يتم إنشاؤها ديناميكيًا بناءً على إدخال المستخدم.

Procs للأسباب التي ذكرها الآخرون وأيضًا من الأسهل ضبط proc باستخدام ملف التعريف أو أجزاء من proc.بهذه الطريقة لن تضطر إلى إخبار شخص ما بتشغيل تطبيقه لمعرفة ما يتم إرساله إلى خادم SQL

إذا كنت تستخدم استعلامات مخصصة، فتأكد من أنها ذات معلمات

SQL أو SPROC ذات المعلمات... لا يهم من وجهة نظر الأداء... يمكنك الاستعلام عن تحسين أي منهما.

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

ما زلت أفضّل SQL ذات المعلمات بالرغم من ذلك ...

لم أجد أي حجة مقنعة لاستخدام الاستعلامات المخصصة.خاصة تلك التي تم خلطها مع كود C#/Java/PHP الخاص بك.

تعد وسيطة أداء sproc موضع نقاش - حيث تستخدم أفضل 3 وحدات RDBM التخزين المؤقت لخطة الاستعلام وقد كانت كذلك لفترة من الوقت.وقد تم توثيقه...أم أن عام 1995 لا يزال؟

ومع ذلك، فإن تضمين SQL في تطبيقك يعد تصميمًا سيئًا أيضًا - يبدو أن صيانة التعليمات البرمجية مفهوم مفقود بالنسبة للكثيرين.

إذا كان من الممكن أن يبدأ التطبيق من الصفر باستخدام ORM (التطبيقات الجديدة متباعدة وقليلة بين بعضها البعض!) فهو خيار رائع حيث أن نموذج صفك يحرك نموذج قاعدة البيانات الخاص بك - ويوفر الكثير من الوقت.

إذا لم يكن إطار عمل ORM متاحًا، فقد اتخذنا نهجًا مختلطًا لإنشاء ملف XML لمورد SQL للبحث عن سلاسل SQL عندما نحتاج إليها (ثم يتم تخزينها مؤقتًا بواسطة إطار عمل المورد).إذا احتاج SQL إلى أي معالجة بسيطة، فسيتم ذلك في التعليمات البرمجية - إذا كانت هناك حاجة إلى معالجة رئيسية لسلسلة SQL، فإننا نعيد التفكير في النهج.

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

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

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

@تيرابين:أعتقد أن تأكيدك على أن حقيقة أنك لست مضطرًا إلى إعادة ترجمة تطبيقك لإجراء تعديلات يجعل الإجراءات المخزنة خيارًا أفضل هو أمر غير مبدئي.قد تكون هناك أسباب لاختيار الإجراءات المخزنة على الاستعلامات المخصصة، ولكن في غياب أي شيء آخر مقنع، تبدو مشكلة الترجمة وكأنها كسل وليست سببًا حقيقيًا.

تجربتي هي أن 90% من الاستعلامات و/أو الإجراءات المخزنة لا ينبغي كتابتها على الإطلاق (على الأقل يدويًا).

يجب أن يتم إنشاء الوصول إلى البيانات بطريقة أو بأخرى تلقائيا.يمكنك أن تقرر ما إذا كنت ترغب في إنشاء الإجراءات بشكل ثابت في وقت الترجمة أو ديناميكيًا في وقت التشغيل ولكن عندما تريد إضافة عمود إلى الجدول (خاصية الكائن) يجب عليك تعديل ملف واحد فقط.

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

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

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

في هذه الأيام نادرًا ما أستخدم الإجراءات المخزنة.أنا أستخدمها فقط لاستعلامات SQL المعقدة التي لا يمكن إجراؤها بسهولة في التعليمات البرمجية.

أحد الأسباب الرئيسية هو أن الإجراءات المخزنة لا تعمل بشكل جيد مع مصممي الخرائط أو.

أعتقد أنك تحتاج في هذه الأيام إلى سبب وجيه جدًا لكتابة تطبيق عمل/نظام معلومات لا يستخدم نوعًا ما من مخططات OR.

يعمل الإجراء المخزن ككتلة من التعليمات البرمجية، لذا بدلاً من الاستعلام المخصص، فإنه يعمل بسرعة.هناك شيء آخر هو الإجراء المخزّن ، يعطي خيار إعادة ترجمة والذي أفضل جزء من SQL الذي تستخدمه فقط للإجراءات المخزنة لا شيء مثل هذا في استعلام Adhoc.

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

يجب استخدام الإجراء المخزن للمشاريع الكبيرة لتحسين الأداء.

كان لدي 420 إجراءً في مشروعي وكان الأمر جيدًا بالنسبة لي.أعمل منذ 3 سنوات في هذا المشروع.

لذا استخدم الإجراءات فقط لأية معاملة.

هل هي بنية نظام جيدة إذا سمحت بتوصيل 1000 أجهزة سطح المكتب مباشرة إلى قاعدة البيانات؟

لا، من الواضح أنه لا، ربما يكون مثالًا سيئًا ولكن أعتقد أن النقطة التي كنت أحاول توضيحها واضحة، حيث يعتني DBA الخاص بك بالبنية التحتية لقاعدة البيانات الخاصة بك، حيث تكون خبرتهم، وحشو SQL في التعليمات البرمجية يقفل الباب أمامهم وخبراتهم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top