MySQL الحد والإزاحة مع الأمثلة
⚡ ملخص ذكي
استخدم MySQL تحدد الكلمة المفتاحية LIMIT عدد الصفوف التي تُرجعها الاستعلامات، بينما تحدد قيمة OFFSET الصف الذي تبدأ منه النتائج. يساهم هذان العاملان معًا في الحفاظ على صغر حجم مجموعات النتائج، وتسريع تحميل الصفحات، ودعم ترقيم الصفحات سجلًا تلو الآخر.

ما هي الكلمة المفتاحية LIMIT في MySQL?
استخدم مما سيحدث تحدد الكلمة المفتاحية عدد الصفوف المُعادة في نتيجة الاستعلام. ويمكن استخدامها مع عبارات SELECT وUPDATE وDELETE، لذا فهي تحدد عدد الصفوف التي يقرأها الاستعلام وكذلك عدد الصفوف التي تؤثر عليها عملية الكتابة.
صيغة الكلمة المفتاحية LIMIT هي كما يلي.
SELECT {fieldname(s) | *} FROM tableName(s) [WHERE condition] LIMIT N;
هنا
- "اختر {اسم الحقل (الأسماء) | *} من اسم (أسماء) الجدول" هي اختيار البيان تحتوي على الحقول التي نرغب في إرجاعها في استعلامنا.
- "[أين الشرط]" هذا الخيار اختياري، ولكن عند تحديده، فإنه يحدد عامل تصفية على مجموعة النتائج. حيث الشرطية يتم تطبيقها قبل LIMIT، لذلك تتم عملية التصفية أولاً ويتم تطبيق الحد الأقصى على ما يتبقى.
- "الحد N" الكلمة المفتاحية هي، و N أي عدد يبدأ من 0. وضع 0 كحد أقصى لا يُرجع أي سجلات على الإطلاق. وضع عدد مثل 5 يُرجع خمسة سجلات. إذا كان الجدول يحتوي على عدد سجلات أقل من N، فسيتم إرجاع جميع السجلات ولن يظهر أي خطأ.
الصيغة مختصرة، ولكن من الجدير بالذكر سبب وجودها قبل الأمثلة.
لماذا يجب علينا استخدام الكلمة المفتاحية LIMIT؟
لنفترض أننا نقوم بتطويرping التطبيق الذي يعمل على قاعدة بيانات myflixdb. طلب منا مصممو النظام تحديد عدد السجلات المعروضة في الصفحة الواحدة بـ 20 سجلاً، وذلك لتجنب بطء التحميل. كيف يمكننا تنفيذ نظام يلبي هذا الشرط؟
تُعالج الكلمة المفتاحية LIMIT هذه الحالة تحديدًا. فبدلًا من جلب جميع صفوف الأعضاء إلى التطبيق وتجاهل معظمها، يُعيد الاستعلام 20 سجلًا في كل صفحة، وتتولى قاعدة البيانات المهمة. ويترتب على ذلك ثلاث فوائد.
- استجابة أسرع: يتم قراءة بيانات أقل من القرص، كما يتم نقل بيانات أقل عبر الشبكة.
- انخفاض استخدام الذاكرة: يحتوي التطبيق على صفحة واحدة من الصفوف، وليس الجدول بأكمله.
- يكتب سيفر: حدٌّ على التحديث أو حذف يحدد البيان الحد الأقصى لعدد الصفوف التي يمكن أن يؤثر عليها الخطأ.
MySQL أمثلة على استعلامات LIMIT
تُطبَّق الأمثلة أدناه على جدول الأعضاء في قاعدة بيانات myflixdb. يُعيد المثال الأول صفين فقط.
SELECT * FROM members LIMIT 2;
| رقم العضوية | الأسماء الكاملة | جنس | تاريخ الميلاد | تاريخ التسجيل | العنوان الفعلي | العنوان البريدي | رقم الاتصال | البريد الإلكتروني | رقم البطاقة الائتمانية |
|---|---|---|---|---|---|---|---|---|---|
| 1 | جانيت جونز | أنثى | 21-07-1980 | اغية | الشارع الأول قطعة رقم 4 | حقيبة خاصة | 0759-253-542 | جانيتجونز@yagoo.cm | اغية |
| 2 | جانيت سميث جونز | أنثى | 23-06-1980 | اغية | ميلروز 123 | اغية | اغية | jj@fstreet.com | اغية |
كما يظهر في النتيجة أعلاه، لم يتم إرجاع سوى عضوين.
الحصول على قائمة تضم عشرة (10) أعضاء من قاعدة البيانات
لنفترض أننا نريد قائمة بأول 10 أعضاء مسجلين من قاعدة بيانات Myflix. يطلب البرنامج النصي أدناه هذه القائمة.
SELECT * FROM members LIMIT 10;
يؤدي تنفيذ البرنامج النصي إلى النتيجة الموضحة أدناه.
| رقم العضوية | الأسماء الكاملة | جنس | تاريخ الميلاد | تاريخ التسجيل | العنوان الفعلي | العنوان البريدي | رقم الاتصال | البريد الإلكتروني | رقم البطاقة الائتمانية |
|---|---|---|---|---|---|---|---|---|---|
| 1 | جانيت جونز | أنثى | 21-07-1980 | اغية | الشارع الأول قطعة رقم 4 | حقيبة خاصة | 0759-253-542 | جانيتجونز@yagoo.cm | اغية |
| 2 | جانيت سميث جونز | أنثى | 23-06-1980 | اغية | ميلروز 123 | اغية | اغية | jj@fstreet.com | اغية |
| 3 | روبرت فيل | ذكر | 12-07-1989 | اغية | الشارع الثالث 3 | اغية | 12345 | rm@tstreet.com | اغية |
| 4 | غلوريا ويليامز | أنثى | 14-02-1984 | اغية | الشارع الثاني 2 | اغية | اغية | اغية | اغية |
| 5 | ليونارد هوفستاتر | ذكر | اغية | اغية | وودكريست | اغية | 845738767 | اغية | اغية |
| 6 | شيلدون كوبر | ذكر | اغية | اغية | وودكريست | اغية | 976736763 | اغية | اغية |
| 7 | راجيش كوثرابالي | ذكر | اغية | اغية | وودكريست | اغية | 938867763 | اغية | اغية |
| 8 | ليزلي وينكل | ذكر | 14-02-1984 | اغية | وودكريست | اغية | 987636553 | اغية | اغية |
| 9 | هوارد ولويتز | ذكر | 24-08-1981 | اغية | ساوث بارك | صندوق بريد P.O. Box 4563 | 987786553 | lwolowitz[at]email.me | اغية |
تم إرجاع 9 أعضاء فقط، لأن قيمة N في عبارة LIMIT أكبر من عدد السجلات في الجدول. طلب 9 صفوف بشكل صريح يُنتج نفس مجموعة النتائج.
SELECT * FROM members LIMIT 9;
💡 نصيحة: يحدد الأمر LIMIT الصفوف من أي ترتيب يُنتجه الخادم. أضف ترتيب حسب الشرط كلما كانت هوية الصفوف مهمة، وإلا فإن عبارة "أول 10 أعضاء" لا تضمن أن تعني نفس الأشخاص التسعة مرتين.
يُعدّ تحديد عدد الصفوف النصف الأول من الميزة، بينما يُعدّ اختيار مكان بدء النافذة النصف الثاني.
استخدام قيمة الإزاحة في استعلام الحد
استخدم الأوفست تُستخدم القيمة غالبًا مع الكلمة المفتاحية LIMIT. وهي تحدد الصف الذي يبدأ الخادم في استرجاع البيانات منه، وبالتالي يتم تخطي الصفوف التي تسبق ذلك الصف.
لنفترض أننا نريد عددًا محدودًا من الأعضاء بدءًا من منتصف الجدول. يبدأ البرنامج النصي أدناه من الصف الثاني ويقتصر على سجلين فقط.
SELECT * FROM `members` LIMIT 1, 2;
تنفيذه في MySQL طاولة العمل يعطي الأمر التالي مقابل قاعدة بيانات myflixdb النتيجة التالية.
| رقم العضوية | الأسماء الكاملة | جنس | تاريخ الميلاد | تاريخ التسجيل | العنوان الفعلي | العنوان البريدي | رقم الاتصال | البريد الإلكتروني | رقم البطاقة الائتمانية |
|---|---|---|---|---|---|---|---|---|---|
| 2 | جانيت سميث جونز | أنثى | 23-06-1980 | اغية | ميلروز 123 | اغية | اغية | jj@fstreet.com | اغية |
| 3 | روبرت فيل | ذكر | 12-07-1989 | اغية | الشارع الثالث 3 | اغية | 12345 | rm@tstreet.com | اغية |
لاحظ ذلك هنا تعويض = 1وبالتالي، فإن الصف رقم 2 هو أول صف يتم إرجاعه، و الحد = 2وبالتالي، لم يتم العثور إلا على سجلين فقط.
في صيغة الوسيطين، يتم كتابة الإزاحة أولاً ثم عدد الصفوف ثانياً، وهو أمر يسهل عكسه عن طريق الخطأ. MySQL كما يقبل شكلاً صريحاً يزيل الغموض، وهو الشكل المفضل في التعليمات البرمجية الجديدة.
SELECT * FROM `members` LIMIT 2 OFFSET 1;
كلا العبارتين تُرجعان نفس الصفين. وبفهم الإزاحة، يتضح نمط الترقيم الذي تعتمد عليه كل شاشة عرض نتائج البحث بشكل مباشر.
كيفية تقسيم نتائج الاستعلام إلى صفحات باستخدام LIMIT و OFFSET
تقسم الترقيم مجموعة النتائج الكبيرة إلى صفحات مرقمة، وتُستخدم خاصيتا LIMIT و OFFSET لتحقيق ذلك. يتحكم في كل طلب صفحة قيمتان: حجم الصفحة، وهو عدد السجلات التي تظهر على الشاشة الواحدة، ورقم الصفحة الذي يطلبه المستخدم.
يتم اشتقاق الإزاحة منها باستخدام صيغة واحدة.
-- OFFSET = page_size * (page_number - 1) SELECT membership_number, full_names FROM members ORDER BY membership_number ASC LIMIT 20 OFFSET 0; -- page 1
تحافظ الصفحة الثانية على نفس الحد وتحرك الإزاحة للأمام بمقدار حجم صفحة واحد.
SELECT membership_number, full_names FROM members ORDER BY membership_number ASC LIMIT 20 OFFSET 20; -- page 2
ثلاث قواعد تضمن صحة وسرعة عرض القائمة المرقمة.
- فرز دائمًا: يمكن للاستعلام المُرقّم بدون عبارة ORDER BY أن يُظهر نفس السجل على صفحتين مختلفتين ويخفي سجلاً آخر تمامًا، لأن الخادم حر في تغيير ترتيب الصفوف بين الاستدعاءات.
- فرز حسب عمود فريد: يؤدي تساوي القيم في عمود الفرز إلى عدم تحديد ترتيب الصفوف المتساوية. ويحل الفرز بناءً على المفتاح الأساسي، أو إضافته كمعيار لكسر التعادل، هذه المشكلة.
- تصفح الصفحات العميقة: إزاحة ١٠٠٠٠٠ قوة MySQL قراءة مئة ألف سطر ثم حذفها قبل إعادة العشرين سطراً التالية. يزداد وقت الاستجابة مع رقم الصفحة.
في حالة الترقيم العميق جداً، يتجنب ترقيم الصفحات باستخدام مجموعة المفاتيح الإزاحة تماماً. فبدلاً من حساب الصفوف المراد تخطيها، يتذكر الاستعلام المفتاح الأخير من الصفحة السابقة ويطلب الصفوف التي تليه.
SELECT membership_number, full_names FROM members WHERE membership_number > 20 -- last id from the previous page ORDER BY membership_number ASC LIMIT 20;
يظل هذا النموذج سريعًا مهما كان عمقه، لأن الفهرس ينتقل مباشرةً إلى مفتاح البداية بدلًا من تصفح الصفوف التي أمامه. لكن المقابل هو ضرورة تصفح الصفحات بالتسلسل، لذا فإن الانتقال...ping لم يعد من الممكن الانتقال مباشرة إلى الصفحة 500.
الحد في MySQL ضد الأعلى واجلب أولاً
لا يُعدّ LIMIT جزءًا من كل لهجة من لهجات SQL، وهو أمر مهم بمجرد أن يتعين على الاستعلام الانتقال بين محركات قواعد البيانات. MySQL, PostgreSQLو SQLite تتشارك الكلمة المفتاحية LIMIT. يستخدم SQL Server الكلمة المفتاحية TOP، و Oracle يستخدم هذا الأسلوب عبارة FETCH FIRST القياسية. يقارن الجدول أدناه بين الأساليب الثلاثة.
| بند | المكينة | مثال | يتخطى الصفوف |
|---|---|---|---|
| الحد … الإزاحة | MySQL, PostgreSQL, SQLite | حدد * من جدول الأعضاء بحد أقصى 20 وإزاحة 40؛ | نعم، مع الإزاحة |
| اذهب للأعلى | ملقم SQL | حدد أفضل 20 * من الأعضاء؛ | لا، الإزاحة... يلزم جلب البيانات |
| جلب أولا | OracleDb2، SQL القياسي | حدد * من جدول الأعضاء، واجلب أول 20 صفًا فقط؛ | نعم، مع إزاحة … صفوف |
السلوك واحد في كل حالة: تحديد عدد الصفوف، واختياريًا، تخطي عدد من الصفوف أولًا. الاختلاف الوحيد هو في طريقة الكتابة. لذا، ينبغي للاستعلام الذي يجب تشغيله على أكثر من محرك واحد عزل عبارة تحديد عدد الصفوف بدلًا من توزيعها في أجزاء مختلفة من قاعدة التعليمات البرمجية.
