MySQL وتصميم قواعد البيانات

طرق العرض (Views)

13 دقيقة الدرس 20 من 40

طرق العرض (Views)

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

ما هو العرض (View)؟

العرض هو استعلام SQL محفوظ يظهر كجدول افتراضي. عندما تستعلم عن عرض، ينفذ MySQL الاستعلام الأساسي SELECT ويرجع النتائج.

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

إنشاء طرق عرض أساسية

استخدم عبارة CREATE VIEW لتحديد عرض:

-- عرض بسيط يُظهر المنتجات النشطة CREATE VIEW active_products AS SELECT product_id, product_name, price, stock_quantity FROM products WHERE status = 'active'; -- استعلام العرض مثل جدول عادي SELECT * FROM active_products WHERE price > 50;

طرق العرض مع عمليات JOIN

طرق العرض ممتازة لتبسيط الاستعلامات المعقدة مع عدة JOINs:

-- عرض يجمع معلومات الطلبات CREATE VIEW order_details AS SELECT o.order_id, o.order_date, c.customer_name, c.email, p.product_name, oi.quantity, oi.unit_price, (oi.quantity * oi.unit_price) AS line_total FROM orders o JOIN customers c ON o.customer_id = c.customer_id JOIN order_items oi ON o.order_id = oi.order_id JOIN products p ON oi.product_id = p.product_id; -- الآن استعلام البيانات المعقدة بسيط SELECT * FROM order_details WHERE customer_name LIKE 'John%' ORDER BY order_date DESC;
نصيحة: استخدم طرق العرض لإخفاء JOINs المعقدة عن مطوري التطبيقات. يمكنهم الاستعلام عن العرض دون فهم علاقات الجداول الأساسية.

الحقول المحسوبة في طرق العرض

يمكن أن تتضمن طرق العرض أعمدة محسوبة وبيانات مجمعة:

-- عرض مع حقول محسوبة CREATE VIEW product_inventory_value AS SELECT product_id, product_name, stock_quantity, cost_price, (stock_quantity * cost_price) AS inventory_value, CASE WHEN stock_quantity = 0 THEN 'Out of Stock' WHEN stock_quantity < 10 THEN 'Low Stock' ELSE 'In Stock' END AS stock_status FROM products; -- عرض مع تجميعات CREATE VIEW monthly_sales_summary AS SELECT DATE_FORMAT(order_date, '%Y-%m') AS month, COUNT(*) AS total_orders, SUM(total_amount) AS total_revenue, AVG(total_amount) AS avg_order_value FROM orders GROUP BY DATE_FORMAT(order_date, '%Y-%m');

طرق العرض القابلة للتحديث

بعض طرق العرض تسمح بعمليات INSERT و UPDATE و DELETE. يكون العرض قابلاً للتحديث إذا استوفى معايير محددة:

-- عرض قابل للتحديث (جدول واحد، بدون تجميعات) CREATE VIEW high_value_customers AS SELECT customer_id, customer_name, email, total_spent FROM customers WHERE total_spent > 1000; -- يمكنك التحديث من خلال هذا العرض UPDATE high_value_customers SET email = 'newemail@example.com' WHERE customer_id = 5; -- التحديث يؤثر على جدول العملاء الأساسي
مهم: طرق العرض مع JOINs أو DISTINCT أو GROUP BY أو HAVING أو UNION أو دوال التجميع ليست قابلة للتحديث.

خوارزميات العرض

يوفر MySQL ثلاث خوارزميات لمعالجة طرق العرض:

-- MERGE: دمج استعلام العرض مع استعلام المستخدم (افتراضي) CREATE ALGORITHM=MERGE VIEW customer_orders AS SELECT c.customer_name, o.order_id, o.order_date FROM customers c JOIN orders o ON c.customer_id = o.customer_id; -- TEMPTABLE: إنشاء جدول مؤقت (مطلوب للتجميعات) CREATE ALGORITHM=TEMPTABLE VIEW sales_by_category AS SELECT category, COUNT(*) AS product_count, SUM(price) AS total_value FROM products GROUP BY category; -- UNDEFINED: دع MySQL يختار (موصى به) CREATE ALGORITHM=UNDEFINED VIEW recent_orders AS SELECT * FROM orders WHERE order_date > DATE_SUB(NOW(), INTERVAL 30 DAY);
نصيحة أداء: MERGE أسرع ولكن ليس ممكناً دائماً. يُستخدم TEMPTABLE عندما لا يمكن تطبيق MERGE (مثل التجميعات).

الأمان مع طرق العرض

يمكن لطرق العرض تقييد الوصول إلى البيانات الحساسة:

-- عرض الأعمدة الآمنة فقط لمستخدمي التطبيق CREATE VIEW public_user_info AS SELECT user_id, username, email, created_at FROM users; -- تجزئة كلمة المرور والأسئلة الأمنية وما إلى ذلك مخفية -- منح الوصول إلى العرض ولكن ليس إلى الجدول الأساسي GRANT SELECT ON database_name.public_user_info TO 'app_user'@'localhost'; -- عرض مع أمان على مستوى الصف CREATE VIEW employee_department_view AS SELECT employee_id, employee_name, salary, department_id FROM employees WHERE department_id IN ( SELECT department_id FROM user_departments WHERE user_id = CURRENT_USER() );

إدارة طرق العرض

-- إظهار جميع طرق العرض في قاعدة البيانات الحالية SHOW FULL TABLES WHERE Table_type = 'VIEW'; -- إظهار تعريف العرض SHOW CREATE VIEW active_products; -- تعديل عرض موجود CREATE OR REPLACE VIEW active_products AS SELECT product_id, product_name, price, stock_quantity, category FROM products WHERE status = 'active' AND price > 0; -- حذف عرض DROP VIEW IF EXISTS active_products; -- التحقق من وجود العرض قبل الإنشاء DROP VIEW IF EXISTS order_summary; CREATE VIEW order_summary AS SELECT order_id, customer_id, order_date, total_amount FROM orders;

مفهوم طرق العرض المادية

لا يحتوي MySQL على طرق عرض مادية مدمجة، ولكن يمكنك محاكاتها:

-- إنشاء جدول لتخزين نتائج العرض CREATE TABLE cached_sales_summary AS SELECT DATE_FORMAT(order_date, '%Y-%m') AS month, COUNT(*) AS total_orders, SUM(total_amount) AS total_revenue FROM orders GROUP BY DATE_FORMAT(order_date, '%Y-%m'); -- إضافة فهارس للأداء CREATE INDEX idx_month ON cached_sales_summary(month); -- تحديث العرض المادي (تشغيل دوري) TRUNCATE TABLE cached_sales_summary; INSERT INTO cached_sales_summary SELECT DATE_FORMAT(order_date, '%Y-%m') AS month, COUNT(*) AS total_orders, SUM(total_amount) AS total_revenue FROM orders GROUP BY DATE_FORMAT(order_date, '%Y-%m');

طرق العرض مع CHECK OPTION

منع التحديثات التي من شأنها أن تجعل الصفوف تختفي من العرض:

-- عرض مع CHECK OPTION CREATE VIEW active_products_view AS SELECT product_id, product_name, price, status FROM products WHERE status = 'active' WITH CHECK OPTION; -- هذا التحديث ينجح UPDATE active_products_view SET price = 29.99 WHERE product_id = 10; -- هذا التحديث يفشل (سيجعل الصف يختفي من العرض) UPDATE active_products_view SET status = 'inactive' WHERE product_id = 10; -- خطأ: فشل CHECK OPTION

أمثلة واقعية لطرق العرض

-- عرض إحصائيات لوحة التحكم CREATE VIEW dashboard_stats AS SELECT (SELECT COUNT(*) FROM orders WHERE order_date = CURDATE()) AS today_orders, (SELECT SUM(total_amount) FROM orders WHERE order_date = CURDATE()) AS today_revenue, (SELECT COUNT(*) FROM customers WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)) AS new_customers_week, (SELECT AVG(rating) FROM product_reviews WHERE created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)) AS avg_rating_month; -- عرض القيمة الدائمة للعميل CREATE VIEW customer_lifetime_value AS SELECT c.customer_id, c.customer_name, c.email, COUNT(DISTINCT o.order_id) AS total_orders, SUM(o.total_amount) AS lifetime_value, AVG(o.total_amount) AS avg_order_value, MAX(o.order_date) AS last_order_date, DATEDIFF(NOW(), MAX(o.order_date)) AS days_since_last_order FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id, c.customer_name, c.email;

تمرين عملي:

إنشاء عرض أداء المنتج:

  1. أنشئ عرضاً يسمى 'product_performance' يُظهر:
    • معرف المنتج واسمه
    • إجمالي الكمية المباعة
    • إجمالي الإيرادات المحققة
    • متوسط التقييم من المراجعات
    • عدد مرات المراجعة
  2. أضف عموداً محسوباً 'performance_score' (الكمية * متوسط التقييم)
  3. اختبر العرض بالاستعلام عن أفضل 10 منتجات أداءً

أفضل الممارسات

✓ استخدم أسماء وصفية للعروض (مثل vw_customer_orders) ✓ وثق الغرض والتبعيات للعرض ✓ تجنب طرق العرض المتداخلة (عروض مبنية على عروض أخرى) ✓ استخدم طرق العرض لتبسيط الاستعلامات المعقدة ✓ استفد من طرق العرض للأمان وتجريد البيانات ✓ ضع في اعتبارك تأثير الأداء على طرق العرض المعقدة ✓ استخدم الفهارس على الجداول الأساسية ✗ لا تستخدم طرق العرض لهياكل البيانات المتغيرة بشكل متكرر ✗ تجنب الكثير من الأعمدة المحسوبة في طرق العرض

الملخص

في هذا الدرس، تعلمت:

  • طرق العرض هي جداول افتراضية تعتمد على استعلامات SELECT
  • طرق العرض تبسط الاستعلامات المعقدة وتعزز الأمان
  • بعض طرق العرض قابلة للتحديث (جدول واحد، بدون تجميعات)
  • خوارزميات العرض: MERGE و TEMPTABLE و UNDEFINED
  • WITH CHECK OPTION يمنع التحديثات غير الصالحة
  • يمكن لطرق العرض إخفاء البيانات الحساسة عن المستخدمين
  • يمكن محاكاة طرق العرض المادية بالجداول
التالي: في الدرس التالي، سنتعلم عن الإجراءات المخزنة لتغليف منطق الأعمال المعقد في قاعدة البيانات!