مجاني · بدون تسجيل · يدعم ملفات ‎.mmd

محرر مخططات الكيانات بـ Mermaid

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

مخطط طلبات مطبَّع بجدول وصل

الجزء الجدير بالانتباه هو `}o--||` عند سطر الطلب: فهكذا تُعبَّر علاقة متعدد إلى متعدد تعبيرًا صادقًا، عبر جدول وصل له أعمدته الخاصة، بدل التظاهر بأن جدولين يرتبطان مباشرة. وحفظ السعر في السطر لا في المنتج وحده هو بالضبط نوع القرار الذي ينبغي للمخطط أن يُظهره. ولاحظ أيضًا أن كل تسمية علاقة بين علامتَي اقتباس: وهذا في العربية ليس اختياريًا.

erDiagram
    عميل ||--o{ طلب : "يقدّم"
    طلب ||--|{ سطر_طلب : "يتكون من"
    منتج ||--o{ سطر_طلب : "يظهر في"
    عميل ||--o{ عنوان : "يُشحن إلى"
    طلب ||--o| فاتورة : "تصدر عنه"

    عميل {
        int معرف PK
        string بريد UK "يُحفظ بأحرف صغيرة"
        string اسم
        string رقم_ضريبي
        datetime تاريخ_الإنشاء
    }
    طلب {
        int معرف PK
        int معرف_العميل FK
        string حالة
        decimal الإجمالي
    }
    سطر_طلب {
        int معرف_الطلب PK, FK
        int معرف_المنتج PK, FK
        int كمية
        decimal سعر "السعر وقت تقديم الطلب"
    }
    منتج {
        int معرف PK
        string رمز_الصنف UK
        string اسم
    }
    عنوان {
        int معرف PK
        int معرف_العميل FK
        string رمز_بريدي
    }
    فاتورة {
        int معرف PK
        string رقم_الفاتورة UK
        decimal ضريبة
    }
افتح هذا في المحرر
إعلان

أمثلة مشروحة

١. كيانان وعلاقة واحدة

كل علاقة في مخطط الكيانات تطلب تسمية بعد النقطتين — وهي ليست اختيارية بخلاف حافة مخطط التدفق. وتُقرأ كجملة: عميل يقدّم طلبًا.

erDiagram
    عميل ||--o{ طلب : "يقدّم"
افتح في المحرر

٢. إضافة الأعمدة

كل سطر خاصية على صورة `نوع اسم` وكلا الجزأين إلزامي. والرموز `PK` و`FK` و`UK` تؤشّر المفاتيح؛ والنص بين علامتَي اقتباس في النهاية تعليق على العمود.

erDiagram
    عميل ||--o{ طلب : "يقدّم"
    عميل {
        int معرف PK
        string بريد UK
        string اسم
    }
    طلب {
        int معرف PK
        int معرف_العميل FK
        datetime تاريخ_التقديم "بتوقيت UTC"
    }
افتح في المحرر

٣. تعدّدية تقول شيئًا

الرمزان الأقرب إلى كل كيان هما تعدّديته. ويقول هذا المثال إن الطلب يجب أن يكون له سطر واحد على الأقل، بينما قد لا يكون للعميل أي طلب: وهو قيد حقيقي ينبغي للمخطط أن يفرضه وللرسم أن يُظهره.

erDiagram
    عميل ||--o{ طلب : "يقدّم"
    طلب ||--|{ سطر_طلب : "يتكون من"
    سطر_طلب }o--|| منتج : "يشير إلى"
افتح في المحرر

٤. متعدد إلى متعدد عبر جدول وصل

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

erDiagram
    طالب ||--o{ تسجيل : "يسجّل في"
    مقرر ||--o{ تسجيل : "يُدرّس عبر"
    تسجيل {
        int معرف_الطالب PK, FK
        int معرف_المقرر PK, FK
        datetime تاريخ_التسجيل
        string تقدير "فارغ حتى الاختبار"
    }
    طالب {
        int معرف PK
        string اسم
    }
    مقرر {
        int معرف PK
        string رمز UK
    }
افتح في المحرر

٥. علاقات الكيان بنفسه

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

erDiagram
    موظف ||--o{ موظف : "يشرف على"
    موظف {
        int معرف PK
        int معرف_المدير FK "فارغ للإدارة العليا"
        string اسم
        string مسمى_وظيفي
    }
افتح في المحرر

ملخص صياغة مخطط الكيانات

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

الصياغةالمعنى
erDiagramيفتح المخطط. حساس لحالة الأحرف: `erdiagram` لا يعمل.
A ||--o{ B : "تسمية"علاقة. والتسمية إلزامية.
||واحد بالضبط.
o|صفر أو واحد.
}|واحد أو أكثر.
}oصفر أو أكثر.
--علاقة معرِّفة — خط متصل.
..علاقة غير معرِّفة — خط متقطع.
A { ... }كتلة خصائص الكيان A.
int معرف PKخاصية: النوع أولًا، ثم الاسم، ثم علامة المفتاح إن وُجدت.
PK / FK / UKمفتاح أساسي، أجنبي، فريد.
int معرف PK, FKعدة علامات مفاتيح تفصلها فاصلة.
string بريد "تعليق"النص بين علامتَي اقتباس في النهاية تعليق على العمود.
A ||--o{ B : "ينتمي إلى"علامتا الاقتباس إلزاميتان بمجرد أن تحتوي التسمية على مسافة. وبدونهما تُقتطع التسمية عند أول مسافة وتصير كل كلمة باقية كيانًا وهميًا.
إعلان

الأخطاء الستة التي تُفسد مخطط الكيانات

مخطط الكيانات أشد الأنواع الستة صرامةً في صياغته: فما يمرّ في المخططات الأخرى يُرفض هنا صراحةً. لكن فيه أيضًا خطأً صامتًا يقع فيه من يكتب بالعربية بيسر خاص. وكل ما هنا أُعيد إنتاجه على Mermaid 11.12.2.

ما تراه

يُرسم المخطط، والتسمية مقتطعة، وتظهر كيانات لم تكتبها

لماذا

تسمية العلاقة فيها مسافة وليست بين علامتَي اقتباس. وهذا أكثر ما سيعترضك في العربية، لأن عبارات العلاقة عندنا تكاد تكون دائمًا من عدة كلمات: «ينتمي إلى»، «يظهر في»، «يُشحن إلى». قِيس: `عميل ||--o{ طلب : ينتمي إلى` لا يبلّغ عن أي خطأ، بل يختصر التسمية إلى «ينتمي» وينشئ كيانًا فارغًا اسمه «إلى». ومع ثلاث كلمات يولد كيانان وهميان. فيُرسم جدولان في صورة أربعة مستطيلات ولا شيء ينبّهك — سوى أن الإطار يقفز من 128 إلى 356 بكسل.

الحل

ضع بين علامتَي اقتباس كل تسمية فيها مسافة. وهذا في العربية يعني كل تسمية عمليًا؛ واتخاذه قاعدة أيسر من الترجيح في كل مرة.

خطأ
erDiagram
    عميل ||--o{ طلب : ينتمي إلى
صحيح
erDiagram
    عميل ||--o{ طلب : "ينتمي إلى"

ما تراه

Parse error ينتهي بـ: Expecting 'COLON', 'STYLE_SEPARATOR', got 'NEWLINE'

لماذا

علاقة بلا تسمية. فبخلاف حافة مخطط التدفق، النقطتان والتسمية إلزاميتان: وبدونهما ينتهي السطر قبل أوانه ببساطة.

الحل

أضف نقطتين وعبارة فعلية، بين علامتَي اقتباس إن كانت فيها مسافة.

خطأ
erDiagram
    عميل ||--o{ طلب
صحيح
erDiagram
    عميل ||--o{ طلب : "يقدّم"

ما تراه

Parse error ينتهي بـ: got 'UNICODE_TEXT'

لماذا

رمز تعدّدية غير صالح. فالصحيح `||` و`o|` و`}|` و`}o` فقط (ومقابلاتها المرآتية)؛ وأي شيء غيرها يسقط. والرمز `oo` خطأ مطبعي نمطي، ينشأ من افتراض أن الترميز متناظر.

الحل

استعمل أحد الأزواج الأربعة. و`||--o{` — واحد بالضبط إلى صفر أو أكثر — يغطي أغلب المفاتيح الأجنبية.

خطأ
erDiagram
    عميل ||--oo{ طلب : "يقدّم"
صحيح
erDiagram
    عميل ||--o{ طلب : "يقدّم"

ما تراه

Parse error ينتهي بـ: Expecting 'ATTRIBUTE_WORD', got 'BLOCK_STOP'

لماذا

خاصية لها اسم وليس لها نوع. فخصائص مخطط الكيانات تُكتب `نوع اسم`، والنوع ليس اختياريًا — وهذا يفاجئ القادمين من قواعد البيانات بلا مخطط.

الحل

امنح كل خاصية نوعًا. واختلقه إن لم يكن في المخطط الفعلي: `string` أو `int` أو `json`.

خطأ
erDiagram
    عميل {
        بريد
    }
صحيح
erDiagram
    عميل {
        string بريد
    }

ما تراه

Parse error ينتهي بـ: Expecting 'NON_IDENTIFYING', 'IDENTIFYING', got 'UNICODE_TEXT'

لماذا

الخط بين علامتَي التعدّدية خاطئ. ويجب أن يكون بمحرفين بالضبط: `--` للعلاقة المعرِّفة أو `..` لغير المعرِّفة. والشرطة الواحدة ليست اختصارًا لـ `--` بل خطأ صياغي.

الحل

اكتب `--` أو `..` بين زوجَي التعدّدية.

خطأ
erDiagram
    عميل ||-o{ طلب : "يقدّم"
صحيح
erDiagram
    عميل ||--o{ طلب : "يقدّم"

ما تراه

تُرسم التعدّدية، لكنها تصف القيد المعكوس

لماذا

الرمزان الأقرب إلى كل كيان يخصّان ذلك الكيان بعينه، وقراءتهما بالمقلوب سهلة جدًا. فـ `عميل ||--o{ طلب` تقول إن للعميل الواحد صفرَ طلبات أو أكثر. واقلبها إلى `عميل }o--|| طلب` فأنت تزعم أن كل عميل ينتمي إلى طلب واحد بالضبط، وهذا لا معنى له — ويُرسم دون أدنى اعتراض.

الحل

اقرأ من الداخل إلى الخارج: الرموز الملامسة لـ «عميل» تصف كم عميلًا، لا كم طلبًا.

خطأ
erDiagram
    عميل }o--|| طلب : "يقدّم"
صحيح
erDiagram
    عميل ||--o{ طلب : "يقدّم"

ملاحظات على الرسم

مقيس على Mermaid 11.12.2، وهي النسخة التي يستعملها هذا الموقع.

التخطيط تمليه العلاقات لا عدد الكيانات

سلسلة كيانات يرتبط كل منها بالذي يليه تُرسم عمودًا مرتفعًا: فأربعون كيانًا تعطي إطارًا يقارب 116×7315، مقابل 116×470 عند ثلاثة. لكن الأربعين نفسها إذا ارتبطت كلها بجدول مركزي واحد أعطت شيئًا أعرض بكثير وأقصر. وهذا هو النوع الوحيد هنا الذي يغيّر فيه شكلُ بياناتك شكلَ الصورة أكثر مما يغيّر حجمها، فالمخطط الذي لا يتسع يُصلَح غالبًا بتغيير أيّ العلاقات ترسم لا بتغيير عددها.

في العربية تحتاج كل تسمية تقريبًا إلى علامتَي اقتباس

يستحق هذا التكرار، لأنه أغلى خطأ صامت في هذه الصفحة. فتسميات العلاقات الإنجليزية قد تكون كلمة واحدة — places وcontains وreferences — ولذلك تبدو علامتا الاقتباس في التوثيق الإنجليزي زينة. أما في العربية فأغلبها عبارات من عدة كلمات وتتفكك بدون علامتَي الاقتباس. والقاعدة العملية: ضع التسمية دائمًا بين علامتَي اقتباس وكفّ عن التفكير في الأمر.

أسماء الكيانات معرّفات، فاختر أسلوبًا والزمه

الأسماء العربية تعمل أسماءَ كيانات وأعمدة دون مشكلة — جُرّب `عميل` و`طلب` و`منتج`. لكن اسم الكيان معرّف، فالمسافة ممنوعة فيه: اختر الشرطة السفلية مثل `سطر_طلب` أو الوصل، ثم الزم اختيارك في المخطط كله. ولا يفرض Mermaid أي عرف هنا، لكن خلط الأسلوبين يولّد كيانين متمايزين دون أي تحذير، تمامًا كما يفعل خلط الأحرف الكبيرة والصغيرة في اللاتينية.

الصياغة أشد صرامة من الأنواع الستة كلها

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

التسميات HTML، فتصدير PNG يعيد الرسم

تُرسم جداول خصائص الكيانات داخل `<foreignObject>` في ملف SVG، فلا تستطيع المتصفحات تحويلها مباشرة إلى صورة نقطية على لوحة canvas. وكان تصدير PNG في هذا الموقع يعيد ملف SVG بصمت؛ أما الآن فيعيد رسم المخطط أولًا بتسميات نصية SVG صِرفة وينتج ملف PNG صحيحًا بحجمه الكامل، بتنضيد يختلف اختلافًا بالكاد يُلحظ.

متى يكون مخطط آخر أنسب

إن كنت تحتاج وراثة أو واجهات أو دوالّ فهذا هو المخطط الخاطئ: فمخطط الكيانات لا يعرف شيئًا من هذه المفاهيم. استعمل مخطط الأصناف واقبل أنه ينمذج شيفرتك لا جداولك.

وإن كان المخطط كبيرًا، فمخطط كيانات للمخطط كله يصير ملصقًا جداريًا لا يقرؤه أحد. ارسم الجداول الخمسة التي تمسّ ما تشرحه في تلك اللحظة واترك الباقي خارج الإطار؛ فالمخطط حجة لا جرد.

وإن كان السؤال الحقيقي كيف تتدفق البيانات بين الأنظمة لا كيف تُخزَّن، فالذي يجيب عنه مخطط تدفق فيه مجموعة فرعية لكل نظام، لا مخطط الكيانات.

أنواع المخططات الأخرى

بقلم Dominik Malsch · آخر تحديث:

افتح المحرر ←