نمذجة البيانات ومخططات الكيانات والعلاقات

الكيانات والخصائص

18 دقيقة الدرس 2 من 10

الكيانات والخصائص

قبل أن ترسم خطاً واحداً في نموذج البيانات، تحتاج إلى الإجابة على سؤال بسيط في ظاهره معقّد في جوهره: ما الأشياء التي يحتاج هذا النظام إلى تذكّرها؟ تأتي الإجابة في طبقتين. أولاً تُحدّد الأشياء — أي الأسماء والكيانات التي يتتبعها النظام. ثم، لكل شيء، تُحدّد الحقائق المتعلقة به التي يجب على النظام تخزينها. في نمذجة العلاقات بين الكيانات، تُسمى تلك الأشياء كيانات (Entities) وتُسمى الحقائق خصائص (Attributes).

الإتقان في هذين الخطوتين هو جوهر فن نمذجة البيانات. مجموعة الكيانات المختارة جيداً تُترجَم إلى جداول قاعدة بيانات سهلة الاستعلام والصيانة. أما المجموعة المختارة بشكل رديء فتُفضي إلى تكرار والتباس وإعادة هيكلة مكلفة لاحقاً.

ما هو الكيان؟

الكيان (Entity) هو فئة من الأشياء أو المفاهيم الواقعية التي يحتاج النظام إلى تخزين بيانات عنها. ثلاث علامات تُميّز الكيان الحقيقي:

  1. له هوية. يمكنك تمييز نسخة عن أخرى. مريض يمكن تمييزه عن مريض آخر. منتج يمكن تمييزه عن منتج آخر.
  2. له نسخ متعددة. نوع الكيان يمثل فئة كاملة من الأشياء، لا كائناً واحداً محدداً. Patient نوع كيان؛ أما أحمد الراشدي (رقم المريض 4821) فهو نسخة (تُسمى أيضاً سجلاً أو صفاً).
  3. له خصائص تستحق التخزين. يحتاج النظام إلى تسجيل حقائق عنه. إذا لم تستطع التفكير في خاصيتين ذواتَي معنى على الأقل، فالمرشح على الأرجح ليس كياناً حقيقياً — ربما يكون مجرد خاصية لشيء آخر.
الكيان مقابل النسخة: نوع الكيان Doctor يصف الفئة. أما النسخة د. سارة حامد، رقم 017، قسم القلب فهي صف واحد في جدول الأطباء. تُنمذج مخططات ERD النوع لا الصفوف الفردية.

إيجاد الكيانات في سيناريو عملي

أسلوب موثوق هو قراءة المتطلبات وتسطير كل اسم مهم. فكر في هذا الوصف الموجز لنظام حجز مواعيد عيادة:

"يحجز المرضى مواعيد مع الأطباء في فروع عيادات محددة. كل موعد لتخصص طبي واحد. بعد الزيارة يسجّل الطبيب التشخيص ويصف الأدوية."

يعطي فرز الأسماء هذه المرشحات: Patient, Appointment, Doctor, Clinic Branch, Medical Specialty, Diagnosis, Medication. طبّق الآن العلامات الثلاث للتصفية والتأكيد:

  • Patient (مريض) — له هوية (رقم المريض)، نسخ متعددة، خصائص وفيرة (الاسم، تاريخ الميلاد، الهاتف). كيان مؤكّد.
  • Appointment (موعد) — له هوية (رقم الموعد)، نسخ متعددة، خصائص رئيسية (التاريخ، الوقت، الحالة). كيان مؤكّد.
  • Doctor (طبيب) — له هوية (رقم الموظف)، نسخ متعددة، خصائص (الاسم، التخصص، رقم الترخيص). كيان مؤكّد.
  • Clinic Branch (فرع العيادة) — له هوية (كود الفرع)، نسخ متعددة، خصائص (العنوان، الهاتف، ساعات العمل). كيان مؤكّد.
  • Medication (دواء) — له هوية (كود الدواء)، نسخ متعددة، خصائص (الاسم، الصيغة الدوائية، التركيز). كيان مؤكّد.

أنواع الخصائص

بمجرد تحديد الكيان، عليك تعريف الحقائق التي ستُخزَّن بعناية. الخصائص ليست كلها متشابهة — فهي تنتمي إلى فئات مختلفة، وفهم تلك الفئات يمنع أخطاء التصميم.

الخصائص البسيطة (الذرية)

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

الخصائص المركّبة

الخاصية المركّبة مؤلَّفة منطقياً من مكوّنات أصغر، لكل منها معنى مستقل. full_name المؤلف من first_name وlast_name هو المثال الكلاسيكي. address المؤلف من street وcity وpostal_code وcountry مثال آخر. قرار التصميم هو: هل تُخزّن المركّبة ككل أم تُقسّمها إلى أجزاء؟ قسّمها حين تحتاج إلى البحث أو الترتيب بناءً على مكوّنات فردية — وأنت تريد دائماً تقريباً البحث عن المرضى حسب المدينة أو ترتيب الطلبات حسب الرمز البريدي، لذا يجب دائماً تفكيك العنوان.

الخصائص المشتقة

الخاصية المشتقة يمكن حسابها من بيانات مُخزَّنة أخرى، لذا لا تحتاج عموداً مستقلاً. age يمكن اشتقاقه من date_of_birth وتاريخ اليوم. total_price يمكن اشتقاقه بضرب quantity في unit_price. في ترميز ER، تُعرض الخصائص المشتقة ببيضاوي منقّط. عملياً يجب أن تقرر إن كنت ستُخزّنها على أي حال (لأداء الاستعلامات) أم تحسبها دائماً في اللحظة.

قاعدة عامة: تجنب تخزين الخصائص المشتقة ما لم يكن ثمة مبرر واضح للأداء أو التدقيق. تخزين age جنباً إلى جنب مع date_of_birth يُنشئ عبئاً في الصيانة — فالعمر المُخزَّن يصبح خاطئاً فور مرور عيد الميلاد ما لم تُحدّثه باستمرار.

ترميز ERD: رسم مربعات الكيانات

في ترميز ER القياسي (وبأسلوب crow-foot المستخدم في الأدوات الحديثة)، يُرسم الكيان كمستطيل. يظهر اسم الكيان في الترويسة بصيغة المفرد: Patient لا Patients. تُدرج الخصائص داخل المربع، سطراً لكل خاصية. تُوسَم خصائص المفتاح الأساسي بـPK وتُسطَّر أو تُوضع في الأعلى. والمفاتيح الأجنبية تُوسَم بـFK.

يعرض المخطط أدناه ثلاثة كيانات مؤكّدة من سيناريو العيادة مع خصائصها المُصنَّفة. لاحظ كيف فُكّك العنوان المركّب إلى أعمدة منفصلة، وكيف ظهرت age كخاصية مشتقة (منقّطة).

ERD Entity Boxes: Patient, Doctor, Appointment Patient PK patient_id first_name last_name date_of_birth age (derived) phone email address_street address_city address_postal_code composite Doctor PK doctor_id first_name last_name specialty license_number phone email hire_date years_experience (derived) Appointment PK appointment_id FK patient_id FK doctor_id appointment_date appointment_time status reason_for_visit branch_id FK Legend PK Primary Key — المعرّف الفريد FK Foreign Key — رابط لكيان آخر italic / dashed = خاصية مشتقة composite = مركّب مُفكَّك
ثلاثة مربعات كيانات من نظام حجز مواعيد العيادة. يعرض Patient عنواناً مركّباً مُفكَّكاً وخاصية age مشتقة. يحمل Appointment مفتاحين أجنبيين يربطانه بـ Patient وDoctor.

اختيار مستوى التفاصيل الصحيح

من أشيع الأخطاء المبكرة تخزين قيمة مركّبة في عمود نصي واحد. فكر في كيان Patient يُخزَّن فيه العنوان كسلسلة نصية واحدة "12 شارع العروبة، الرياض، 11421". يبدو ذلك جيداً حتى تحتاج إلى:

  • إيجاد جميع المرضى في مدينة بعينها.
  • ترتيب المرضى حسب الرمز البريدي لحملة بريدية.
  • عرض اسم المدينة فقط على خريطة لوحة التحكم.

تتحول العمليات الثلاث إلى مشكلات تحليل نصي مكلفة بدلاً من عمليات بحث بسيطة في الأعمدة. والحل — تفكيك العنوان إلى address_street وaddress_city وaddress_postal_code وaddress_country — يجب أن يحدث وقت التصميم، لا بعد أن تمتلئ قاعدة البيانات بملايين الصفوف.

لا تُخزّن قوائم في خاصية واحدة. إذا وجدت نفسك مغرياً بكتابة phone_numbers = "0501234567, 0559876543" في عمود واحد، فهذا يشير إلى أنك تحتاج كياناً منفصلاً PatientPhone (أو على الأقل عموداً منفصلاً phone_secondary إذا كان الحد الأقصى رقمَين ثابتَين). العمود الذي يحمل قائمة مفصولة بفواصل ينتهك القاعدة الأساسية بأن كل خلية يجب أن تحمل قيمة ذرية واحدة بالضبط.

مثال ثانٍ: المتجر الإلكتروني

لترسيخ الأسلوب، فكر في متجر إلكتروني مبسط. قراءة المتطلبات — "يُقدّم العملاء طلبات لمنتجات. كل طلب له بنداً واحداً أو أكثر. المنتجات تنتمي إلى فئات." — تُنتج هذه الكيانات المؤكّدة:

Online Store — Entity Boxes: Customer, Product, Order Customer PK customer_id first_name last_name email phone registration_date total_orders (derived) billing_city billing_postal_code Product PK product_id product_name description unit_price stock_quantity sku category_id FK Order PK order_id FK customer_id order_date status shipping_address order_total (derived) أنواع الخصائص الموضّحة: Simple (بسيطة) — معظم الحقول | Derived — محسوبة من بيانات أخرى | Composite — مُفكَّكة إلى أعمدة فرعية أسماء الكيانات بصيغة المفرد (Customer, Product, Order) — لا الجمع
مربعات كيانات المتجر الإلكتروني تعرض Customer وProduct وOrder مع أنواع الخصائص. الخاصيتان المشتقتان total_orders وorder_total تُحسبان وقت الاستعلام؛ وقد فُكّكت الخاصية المركّبة للعنوان إلى billing_city وbilling_postal_code.

تقاليد التسمية المهمة

التسمية المتسقة تمنع الالتباس على امتداد فريق المشروع بأكمله:

  • أسماء الكيانات أسماء مفردة بتنسيق PascalCase: Customer، Appointment، لا Customers ولا tbl_appointment.
  • أسماء الخصائص بتنسيق snake_case لأعمدة قاعدة البيانات: date_of_birth، unit_price.
  • تقليد المفتاح الأساسي: استخدم entity_id (مثل patient_id، order_id). بعض الفرق تستخدم id فحسب — كلاهما مقبول بشرط الاتساق.
  • الخصائص المنطقية (Boolean) تستخدم بادئة is_ أو has_: is_active، has_insurance.
  • تجنب الاختصارات في أسماء الكيانات والخصائص. pt_dob غامضة؛ patient_date_of_birth لا لبس فيها.

خلاصة

  • الكيان هو فئة من الأشياء الواقعية التي يجب على النظام تذكّرها. له هوية ونسخ متعددة وخصائص ذات معنى.
  • ابحث عن الكيانات بمسح المتطلبات للأسماء المهمة، ثم طبّق اختبار العلامات الثلاث.
  • الخصائص البسيطة حقائق ذرية أحادية القيمة. الخصائص المركّبة لها مكوّنات فرعية ويجب تفكيكها إلى أعمدة منفصلة. الخصائص المشتقة تُحسب من البيانات المُخزَّنة ولا تُخزَّن عادةً بشكل مستقل.
  • في ترميز ERD، الكيانات مستطيلات بترويسة مسمّاة. تُدرج الخصائص بداخلها؛ وعلامتا PK وFK تُحددان أعمدة المفاتيح.
  • احصل على مستوى التفاصيل الصحيح وقت التصميم: تقسيم الخاصية المركّبة لاحقاً مكلف؛ وتخزين قائمة في عمود واحد يُنشئ ألماً دائماً في الاستعلامات.