الدرس 9: تسوية قواعد البيانات (Normalization) - من 1NF إلى 3NF | تحليل ملف التصميم

admin
الصفحة الرئيسية
الدرس 9: تحسين النموذج (Normalization) - القواعد الكاملة والأشكال العادية
تسوية قواعد البيانات (Normalization) - من 1NF إلى 3NF

تسوية قواعد البيانات (Normalization) - من 1NF إلى 3NF

--------------------------

الدرس 9: تحسين النموذج (Normalization)

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

1. مقدمة حول التسوية

أ. تعريف التسوية وأهدافها الأساسية

التسوية (Normalization) هي عملية منهجية لتنظيم الجداول في قاعدة بيانات علائقية لتقليل تكرار البيانات (Data Redundancy) وتحسين التكامل المرجعي (Referential Integrity). بعبارة أخرى، هي فن تقسيم الجداول الكبيرة إلى جداول أصغر وأكثر تنظيمًا، مع الحفاظ على العلاقات بينها.

الأهداف الأساسية للتسوية:

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

ب. المشاكل التي تحلها التسوية في قواعد البيانات

التسوية تعالج مجموعة من المشاكل المعروفة باسم "الشذوذ" (Anomalies):

  1. التكرار (Redundancy): تخزين نفس المعلومة في عدة أماكن.
  2. شذوذ الإدراج (Insertion Anomaly): عدم القدرة على إدخال معلومات عن كيان ما دون وجود معلومات عن كيان آخر.
  3. شذوذ التحديث (Update Anomaly): الحاجة إلى تحديث نفس البيانات في عدة أماكن مختلفة.
  4. شذوذ الحذف (Deletion Anomaly): فقدان معلومات مهمة عن كيان ما عند حذف سجل مرتبط به.

ج. العلاقة بين التسوية وتصميم قواعد البيانات الفعالة

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

2. مشاكل قواعد البيانات غير المسواة (أمثلة عملية)

لنأخذ مثالاً لجدول "غير مسوّى" لنرى هذه المشاكل بوضوح:

جدول تفاصيل_الطلاب_والمقررات (غير مسوّى)
رقم_الطالباسم_الطالبتاريخ_الميلادرقم_المقرراسم_المقررساعات_المقرراسم_الاستاذقسم_الاستاذ
101أحمد سعيد2003-05-15CS101برمجة 13محمد عليعلوم الحاسب
101أحمد سعيد2003-05-15MA202رياضيات متقدمة4سارة خالدالرياضيات
102ليلى محمد2004-11-22CS101برمجة 13محمد عليعلوم الحاسب
103كريم علي2003-01-30EC303اقتصاد كلي3ريم فهدالاقتصاد

3. الأشكال العادية (Normal Forms)

الأشكال العادية (Normal Forms - NFs) هي مجموعة من القواعد أو المستويات التي تساعدنا على تنظيم الجداول وتقليل الشذوذ. الهدف عادةً هو الوصول إلى 3NF.

أ. الشكل العادي الأول (1NF - First Normal Form)

القواعد: القيم الذرية (Atomic Values)، عدم تكرار المجموعات، كل عمود له اسم فريد، كل صف له مفتاح أساسي فريد.

ب. الشكل العادي الثاني (2NF - Second Normal Form)

القاعدة: يجب أن يكون الجدول في 1NF، ويجب ألا يكون هناك تبعية جزئية (Partial Dependency) لأي عمود غير مفتاحي على جزء من المفتاح الأساسي المركب.

ج. الشكل العادي الثالث (3NF - Third Normal Form)

القاعدة: يجب أن يكون الجدول في 2NF، ويجب ألا يكون هناك تبعية متعدية (Transitive Dependency) لأي عمود غير مفتاحي على المفتاح الأساسي.

د. أشكال عادية متقدمة (اختياري)

توجد أشكال متقدمة مثل BCNF, 4NF, 5NF لمعالجة حالات خاصة ومعقدة تتجاوز متطلبات معظم التصميمات العملية.

4. المفاهيم الأساسية المساعدة

  • التبعية الوظيفية (Functional Dependency - FD): قيمة عمود (A) تحدد بشكل فريد قيمة عمود آخر (B). نرمز لها: A → B.
  • المفاتيح الأساسية (Primary Keys): العمود الذي يحدد بشكل فريد كل صف.
  • المفاتيح المرشحة (Candidate Keys): أي عمود يمكن أن يعمل كمفتاح أساسي.
  • المفاتيح الخارجية (Foreign Keys): عمود يشير إلى المفتاح الأساسي في جدول آخر.
  • التبعية المتعدية (Transitive Dependency): A → B و B → C (حيث B ليس جزءًا من المفتاح الأساسي).
  • التبعية الجزئية (Partial Dependency): عمود غير مفتاحي يعتمد على جزء فقط من المفتاح الأساسي المركب.

5. عملية التسوية خطوة بخطوة

  1. ابدأ بجدول واحد (أو مجموعة جداول أولية).
  2. حدد جميع المفاتيح والتبعيات الوظيفية.
  3. طبّق قواعد 1NF: تأكد من أن كل عمود يحتوي على قيم ذرية.
  4. طبّق قواعد 2NF: ابحث عن التبعيات الجزئية وقم بتقسيم الجدول.
  5. طبّق قواعد 3NF: ابحث عن التبعيات المتعدية وقم بتقسيم الجدول.
  6. التحقق من سلامة البيانات بعد التسوية.

6. أمثلة تطبيقية شاملة

هنا ملخص لكيفية تسوية المثالين المذكورين في النص الأصلي للوصول إلى 3NF.

مثال 1: نظام إدارة الطلاب والمقررات

النتيجة النهائية (في 3NF):

  • الطلاب: (StudentID, StudentName, StudentDOB)
  • المقررات: (CourseID, CourseName, CourseHours, ProfessorID (FK))
  • تسجيلات_المقررات: (StudentID (FK), CourseID (FK))
  • الاساتذة: (ProfessorID, ProfessorName, DeptName (FK))
  • الاقسام: (DeptName)

مثال 2: نظام المبيعات والعملاء

النتيجة النهائية (في 3NF):

  • العملاء: (CustomerID, CustomerName, CustomerAddress)
  • المنتجات: (ProductID, ProductName, ProductPrice)
  • الطلبات: (OrderID, OrderDate, CustomerID (FK))
  • تفاصيل_الطلب: (OrderID (FK), ProductID (FK), Quantity)

7. أمثلة تطبيقية شاملة (مع الحل التفصيلي)

سنقوم الآن بتطبيق عملية التسوية خطوة بخطوة على المثالين المذكورين في النص، لنرى كيف ننتقل من جدول غير مسوّى إلى مجموعة جداول في الشكل العادي الثالث (3NF).


مثال 1: نظام إدارة الطلاب والمقررات

أ. الحالة الأولية (جدول غير مسوّى)

الجدول الأصلي: Student_Course_Info

المفتاح الأساسي الافتراضي: مركب من (StudentID, CourseID).

StudentIDStudentNameStudentDOBCourseIDCourseNameCourseHoursProfessorNameProfessorDept
101أحمد سعيد2003-05-15CS101برمجة 13محمد عليعلوم الحاسب

ب. تحديد التبعيات الوظيفية (FDs)

  • StudentID → StudentName, StudentDOB (معلومات الطالب تعتمد على رقم الطالب)
  • CourseID → CourseName, CourseHours, ProfessorName (معلومات المقرر تعتمد على رقم المقرر)
  • ProfessorName → ProfessorDept (قسم الأستاذ يعتمد على اسم الأستاذ)

ج. التحويل إلى 1NF

الجدول بالفعل في 1NF لأن كل حقل يحتوي على قيمة ذرية (فردية) ولا توجد مجموعات متكررة.

د. التحويل إلى 2NF (حل التبعية الجزئية)

نلاحظ أن هناك تبعيات جزئية لأن بعض الأعمدة لا تعتمد على المفتاح الأساسي المركب (StudentID, CourseID) بأكمله:

  • StudentName و StudentDOB يعتمدان فقط على StudentID.
  • CourseName, CourseHours, ProfessorName يعتمدون فقط على CourseID.

الحل: نقوم بتقسيم الجدول الأصلي إلى ثلاثة جداول جديدة للتخلص من هذه التبعيات الجزئية.

الجداول الناتجة في 2NF:

  1. جدول الطلاب: Students(StudentID, StudentName, StudentDOB)
  2. جدول المقررات: Courses(CourseID, CourseName, CourseHours, ProfessorName, ProfessorDept)
  3. جدول تسجيل المقررات (ربط): Course_Enrollments(StudentID, CourseID)

هـ. التحويل إلى 3NF (حل التبعية المتعدية)

نركز الآن على الجداول الناتجة. نجد أن جدول Courses لا يزال يعاني من مشكلة: تبعية متعدية.

CourseID → ProfessorName → ProfessorDept

هنا، ProfessorDept (عمود غير مفتاحي) يعتمد على ProfessorName (عمود غير مفتاحي آخر)، وليس مباشرة على المفتاح الأساسي CourseID.

الحل: نقوم بتقسيم جدول Courses مرة أخرى، ومن الأفضل استخدام ProfessorID كمعرف فريد للأستاذ.

و. النتيجة النهائية (في 3NF)

بعد إتمام عملية التسوية، نحصل على خمسة جداول منظمة:

  • الطلاب: Students(StudentID, StudentName, StudentDOB)
  • الأقسام: Departments(DeptName)
  • الأساتذة: Professors(ProfessorID, ProfessorName, DeptName (FK))
  • المقررات: Courses(CourseID, CourseName, CourseHours, ProfessorID (FK))
  • تسجيلات_المقررات: Course_Enrollments(StudentID (FK), CourseID (FK))

مثال 2: نظام المبيعات والعملاء

أ. الحالة الأولية (جدول غير مسوّى)

الجدول الأصلي: Sales_Order

المفتاح الأساسي الافتراضي: مركب من (OrderID, ProductID).

ب. تحديد التبعيات الوظيفية (FDs)

  • OrderID → OrderDate, CustomerID, CustomerName, CustomerAddress
  • CustomerID → CustomerName, CustomerAddress
  • ProductID → ProductName, ProductPrice
  • (OrderID, ProductID) → Quantity (الكمية تعتمد على الطلب والمنتج معاً)

ج. التحويل إلى 2NF (حل التبعية الجزئية)

لدينا تبعيات جزئية واضحة:

  • معلومات الطلب والعميل تعتمد فقط على OrderID.
  • معلومات المنتج تعتمد فقط على ProductID.

الحل: نقسم الجدول إلى ثلاثة جداول.

الجداول الناتجة في 2NF:

  1. جدول الطلبات: Orders(OrderID, OrderDate, CustomerID, CustomerName, CustomerAddress)
  2. جدول المنتجات: Products(ProductID, ProductName, ProductPrice)
  3. جدول تفاصيل الطلب: Order_Details(OrderID, ProductID, Quantity)

د. التحويل إلى 3NF (حل التبعية المتعدية)

نركز على جدول Orders. نجد فيه تبعية متعدية:

OrderID → CustomerID → (CustomerName, CustomerAddress)

CustomerName و CustomerAddress يعتمدان على CustomerID (عمود غير مفتاحي)، وليس مباشرة على OrderID.

الحل: نقسم جدول Orders.

هـ. النتيجة النهائية (في 3NF)

بعد إتمام التسوية، نحصل على أربعة جداول نظيفة ومنظمة:

  • العملاء: Customers(CustomerID, CustomerName, CustomerAddress)
  • المنتجات: Products(ProductID, ProductName, ProductPrice)
  • الطلبات: Orders(OrderID, OrderDate, CustomerID (FK))
  • تفاصيل_الطلب: Order_Details(OrderID (FK), ProductID (FK), Quantity)
google-playkhamsatmostaqltradent