SQLite / المتوسط: بنية الاستعلام وتصميم المعاملة / الدرس 7
الاستعلامات الفرعية والتعبيرات الجدولية المشتركة والعروض
عبّر عن اختبارات الوجود والتحويلات متعددة المراحل، وميّز اسم الاستعلام المحلي للعبارة والعرض الدائم عن البيانات الوسيطة المخزنة فعلياً.
في هذه الصفحة
أهداف الدرس
- اختيار EXISTS لاختبار الوجود والغياب.
- تسمية مراحل الاستعلام باستخدام CTE.
- شرح سلوك العروض وحدود تجسيد النتائج.
استخدم الاستعلام المتداخل لإظهار مرحلة منطقية
يوفر الاستعلام الفرعي قيمة مفردة أو مجموعة صفوف أو شرط وجود. حدّد عدد نتائجه المتوقع وارتباطه بالصف الخارجي. بحث العميل الذي يغفل مساواة customer_id يسأل عن جدول الطلبات كله. اقرأ الشرط المرتبط «طلب لهذا العميل» لا «يوجد طلب»، حتى تبقى العلاقة المطلوبة واضحة.
للاستعلام الفرعي المفرد في SQLite سلوك محدد عند توفر صفوف متعددة؛ فلا تستخدم بحثاً غير مقيد لاختيار قيمة اعتباطية. افرض التفرد، أو ترتيباً وحداً صريحين يجيبان عن السؤال الفعلي. يحسن التداخل الصحة بإظهار مستوى الصف ونطاقه، وقد يخفي التداخل العميق علاقة خاطئة إذا لم تتضح مسؤوليات مراحله.
لا تضاعف صفوف الأصل للإجابة عن سؤال وجود
تسأل EXISTS هل يجد الاستعلام الفرعي أي صف؛ والثابت المختار داخله ليس النتيجة التجارية. للعميل1 طلبان في البرنامج الأول ويظهر مرة واحدة خارجياً، وتعيد NOT EXISTS العميل2 بلا طلبات. يعبّر ذلك عن الوجود والغياب مباشرة، بدلاً من مضاعفة الأصول بربط ثم الاعتماد على DISTINCT لإزالة تكرارها.
قد تتصرف NOT IN خلاف المتوقع إذا شملت مجموعة المقارنة NULL، لأن المقارنات المجهولة قد تمنع مطابقة غياب متوقعة. اختر قاعدة غياب مرتبطة صراحة واختبر المفاتيح المفقودة. ليست EXISTS تحسين أداء عاماً تلقائياً؛ فما زالت الفهارس والبيانات والمحسن مؤثرة، وفائدتها هنا وضوح مطابقة السؤال.
CREATE TABLE customer(id INTEGER PRIMARY KEY);
CREATE TABLE purchase(id INTEGER PRIMARY KEY,customer_id INTEGER);
INSERT INTO customer VALUES(1),(2);
INSERT INTO purchase VALUES(10,1),(11,1);
SELECT c.id FROM customer AS c WHERE EXISTS
(SELECT 1 FROM purchase AS p WHERE p.customer_id=c.id) ORDER BY c.id;
SELECT c.id FROM customer AS c WHERE NOT EXISTS
(SELECT 1 FROM purchase AS p WHERE p.customer_id=c.id) ORDER BY c.id;
id
1
id
2
لا تنتج مطابقتا الفرع إلا نتيجة وجود واحدة للعميل1، بينما يعيد الاستعلام المكمل العميل2 الذي لا يملك طلباً.
افصل التعبير المسمى عن الصفوف المخزنة
تسمي CTE العادية تعبير استعلام لعبارة واحدة، وتحفظ CREATE VIEW تعريفاً يعاد استخدامه في المخطط. لا يعني الاسم وحده تخزين الصفوف دائماً. قد تدمج SQLite العمل أو تنفذه بأسلوب co-routine أو تجسده وفق قواعدها وخطتها. أما الجدول المؤقت فيخزن الصفوف الوسيطة صراحة، مع كتابات ودورة حياة خاصة.
يعرف البرنامج الثاني عرضاً لمجاميع الطلبات المفتوحة، ثم يستخدم CTE لترشيحه. مجموع South هو40 ومجموع North هو30، ويتحكم ORDER BY النهائي في العرض. عروض SQLite للقراءة فقط ما لم توفر محفزات INSTEAD OF المناسبة سلوك تعديل؛ فلا تنقل افتراض التحديث التلقائي من قواعد أخرى. والعرض ليس أيضاً حد صلاحيات خادم في نموذج قاعدة مضمنة يعتمد على الوصول للملف.
CREATE TABLE purchase(region TEXT,status TEXT,amount INTEGER);
INSERT INTO purchase VALUES('North','open',10),('North','open',20),
('North','closed',100),('South','open',40);
CREATE VIEW open_total AS SELECT region,SUM(amount) AS total
FROM purchase WHERE status='open' GROUP BY region;
WITH selected AS (SELECT region,total FROM open_total WHERE total>=30)
SELECT region,total FROM selected ORDER BY total DESC,region;
region|total
South|40
North|30
يستبعد العرض الطلب المغلق بقيمة100. تحتفظ CTE بالمجموعين الإقليميين المؤهلين، ثم يرتبهما الاستعلام الخارجي.
حد العمل العودي وحدد الدورات
تجمع CTE العودية جزء بداية وجزءاً عودياً، وغالباً باستخدام UNION ALL، لاجتياز تسلسل هرمي أو توليد سلسلة محدودة. اذكر شرط الانتهاء وراعِ البيانات الدورية أو غير الصحيحة. قد يحوي تسلسل يفترض أنه شجرة دورة إذا لم تحمِ قيود المخطط والتطبيق هذه الخاصية، وقد تضاعف المسارات المتكررة النتائج أيضاً.
لتوليد السلسلة من1 إلى3، يمكن البدء بالقيمة1 ثم إنتاج value+1 ما دامت value<3. ليست العودية غير المحدودة مثالاً آمناً. ضع حماية عمق أو عضوية صريحة تلائم الاجتياز المقصود، واشرح هل التكرارات ذات معنى. حدود الموارد دفاع إضافي وليست بديلاً عن حجة انتهاء توافق نموذج البيانات.
راجع الوضوح والعمل المتكرر منفصلين
لا تثبت سهولة قراءة CTE أن نتيجة وسيطة مكلفة تنفذ مرة واحدة فقط. افحص EXPLAIN QUERY PLAN وقياسات ممثلة عندما تهم إعادة الاستخدام. توفر الإصدارات المدعومة تلميحات للتجسيد، لكن يجب فهم معناها الموثق وموازنتها مع التحسين، لا نسخها كخيارات سرعة عامة. لا تفرض استراتيجية قبل تأكيد صحة النتائج.
اختبر الأصول المفقودة والفروع المتعددة والمدخل الخالي والمطابقات المفردة المتعارضة. أظهر اعتماديات العروض أثناء ترحيل المخطط، فقد تؤثر إعادة التسمية أو البناء في المستهلكين. يحدد الاستعلام المرحلي المفيد ما يمثله الصف بعد كل خطوة، ويصرح بالترتيب النهائي، ويبرر حفظ التعريف أو النتيجة الوسيطة بدلاً من إخفاء التعقيد خلف اسم جديد.
الأخطاء الشائعة وإصلاحها
لا يتاح اسم CTE في العبارة التالية.
- لماذا يحدث؟
- انتهى نطاق الاسم بانتهاء العبارة التي عرفته.
- كيف تصلحه؟
- عرّف CTE أخرى، أو استخدم عرضاً أو جدولاً مؤقتاً يوفر مدة الحياة المطلوبة.
- كيف تتجنب تكراره؟
- وثق نطاق كل اسم استعلام.
يختار استعلام الوجود جميع العملاء.
- لماذا يحدث؟
- أغفل الاستعلام الفرعي شرط ربطه بالصف الخارجي.
- كيف تصلحه؟
- أضف العلاقة التي تربطه بالعميل الخارجي.
- كيف تتجنب تكراره؟
- اختبر أصلاً له مطابقات وآخر بلا مطابقات.
لا ينتهي اجتياز التسلسل الهرمي.
- لماذا يحدث؟
- تفتقد العودية حداً صالحاً أو تعود إلى دورة.
- كيف تصلحه؟
- استخدم اجتيازاً منتهياً مع حماية عمق أو مسار تناسب النموذج.
- كيف تتجنب تكراره؟
- اختبر الدورات والمسارات المتكررة في بيئة معزولة.
اختبر فهمك
1. لماذا تتجنب EXISTS تكرار صف العميل بينما قد ينتج الربط صفوفاً عدة؟
اعرض الحل المشروح
تختبر هل يوجد أي فرع مرتبط، بدلاً من إخراج كل زوج مطابق. يظل الطلبان قرار وجود صحيحاً واحداً للعميل الخارجي. أبقِ ربط العميل صريحاً؛ وإلا أصبح السؤال هل يوجد أي طلب في أي مكان، لا هل يملك هذا العميل طلباً.
2. اختر بين CTE وعرض وجدول مؤقت لنتيجة مكلفة تعاد الاستفادة منها في عبارات عدة.
اعرض الحل المشروح
تعيش CTE عبارة واحدة ولا تعد بمخبأ. يحفظ العرض تعريفاً وقد يعيد العمل. يخزن الجدول المؤقت الصفوف صراحة لسير عمل أطول ضمن الاتصال، لكنه يضيف كلفة كتابة وفهرسة وتنظيف يجب قياسها.
أهم ما تعلمته
- يجب أن تحفظ اختبارات الوجود مستوى الصف الخارجي المقصود.
- لـCTE والعروض والجداول المؤقتة عقود مختلفة للنطاق والتخزين.
- تحتاج العودية حجة انتهاء إلى جانب الصياغة الصحيحة.