شرح - where in sql




يمكن اختيار*استخدام أي مبرر؟ (14)

لطالما وعظت لمطوري بأن SELECT * شر ويجب تجنبه مثل الطاعون.

هل هناك أي حالات يمكن تبريرها؟

لا أتحدث عن COUNT(*) - والتي يمكن لأغلب المحسنين اكتشافها.

تصحيح

أنا أتحدث عن رمز الإنتاج.

وكان أحد الأمثلة الرائعة التي رأيتها من هذه الممارسة السيئة هو تطبيق ASP القديم الذي استخدم select * في إجراء مخزن ، واستخدم ADO للتكرار خلال السجلات التي تم إرجاعها ، ولكن حصلت على الأعمدة حسب الفهرس. يمكنك تخيل ما حدث عندما تمت إضافة حقل جديد في مكان آخر غير نهاية قائمة الحقول.


  1. لقد احتجت عدة مرات لعرض البيانات من جدول كانت أسماء الأعمدة الخاصة به غير معروفة. لذلك فعلت SELECT * وحصلت على أسماء الأعمدة في وقت التشغيل.

  2. لقد تسلمت تطبيقًا قديمًا حيث كان الجدول يحتوي على 200 عمودًا وكان عرضه 300. كان التعرض للمخاطرة من SELECT * ليس أسوأ من إدراج جميع الأعمدة البالغ عددها 300 عمود بشكل صريح.


أعتقد أن استخدام select * في فقرة exists أمر مناسب:

select some_field from some_table 
where exists 
 (select * from related_table [join condition...])

يحب بعض الأشخاص select 1 في هذه الحالة ، ولكنه ليس أنيقًا ، ولا يشتري أي تحسينات في الأداء (الضربات المبكرة للتحسين مرة أخرى).


إذا كنت تريد العثور على جميع الأعمدة وترتيب الطلبات ، فيمكنك القيام بما يلي (على الأقل إذا كنت تستخدم MySQL):

SHOW COLUMNS FROM mytable FROM mydb; (1)

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

"select " + fieldNames[0] + ", fieldNames[1]" + ", fieldNames[2] from mytable". (2)

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


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

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

لن أكون مندهشًا لو أن معظم المطورين ذهبوا إلى مسيرتهم الكاملة دون وجود استخدام مشروع لـ SELECT * في كود الإنتاج بالرغم من ذلك.


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


في رمز الإنتاج ، أميل إلى الموافقة بنسبة 100٪ معك.

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


كيف يضمن مطورو phpmyadmin عرض جميع حقول جداول DB؟


لا شيء يمكنني التفكير فيه ، إذا كنت تتحدث عن كود حي.

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

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


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

إذا كنت تعيش في وقت التعداد ، تأكد من كتابة جميع أسماء الأعمدة. لكن لماذا تتوقف عند هذا الحد؟ أعد كتابة تطبيقك في dbms بدون تخطيط. الجحيم ، اكتب dbms الخاصة بك في التجميع. That 'حقا تظهر' م.


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

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

عمليًا ، ألتزم بـ SELECT * في 3 حالات (بعضها ورد ذكره في إجابات أخرى:

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

هناك العديد من السيناريوهات حيث SELECT * هو الحل الأمثل. تشغيل استعلامات مخصصة في Management Studio فقط للحصول على البيانات التي تعمل بها. الاستعلام عن الجداول حيث لا تعرف أسماء الأعمدة بعد لأنها المرة الأولى التي تعمل فيها مع مخطط جديد. إنشاء أدوات quick'n'dirty يمكن التخلص منها لإجراء ترحيل لمرة واحدة أو تصدير بيانات.

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


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

select * 
into staging.aTable 
from remotedb.dbo.aTable

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


يعتمد على سياق برنامج الإنتاج.

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

وبعبارة أخرى ، إذا اخترت التعامل مع "اختيار الحقول" من خلال بعض الوسائل الأخرى (كما هو الحال في الفلاتر الآلية أو المحددة من قبل المستخدم بعد استرداد النتائج) ، فيبدو الأمر على ما يرام.

من ناحية أخرى ، فإننا نتحدث عن نوع من برامج الشركات مع قواعد العمل ، ومخطط محدد ، وما إلى ذلك ... ثم أوافق على أن * SELECT ** فكرة سيئة.

تحرير: أوه وعندما يكون الجدول المصدر إجراء مخزناً لمشغل أو عرض ، يجب أن يكون "* SELECT **" جيدًا لأنك تقوم بإدارة resultset عبر وسائل أخرى (تعريف العرض أو resultset proc's المخزنة).


Select * في رمز الإنتاج له ما يبرره في أي وقت:

  • انها ليست عنق الزجاجة الأداء
  • وقت التطوير أمر بالغ الأهمية

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

لماذا أريد حتى أن أفكر فيما إذا كنت قد اخترت الحقول المناسبة أم لا ، عندما تكون الغالبية العظمى من الوقت أريد معظمها على أية حال ، والغالبية العظمى من المرات القليلة التي لا أفعلها ، شيء آخر هو عنق الزجاجة؟

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

تحرير .. بعد المناقشة ، أعتقد أنني سأضيف إلى هذا:

... وحيث لم يفعل الناس أشياء أخرى غير مرغوب فيها مثل حاول الوصول إلى الأعمدة (ط) ، والتي يمكن أن تكسر في حالات أخرى على أي حال :)





select