الانتقال إلى المحتوى الرئيسي

استيراد الملفات وتصديرها

استيراد ملفات خارجية​

يمكن استيراد خمسة تنسيقات من القائمة الفرعية Import في قائمة السياق للوحة الرسم:

  • json
  • Schema SQL
  • GraphQL
  • DBML
  • AML

يقع Import and Add أسفل Import مباشرةً، ويضيف الملف إلى المخطط بدلًا من استبداله، راجع استيراد وإضافة.
تحتوي شاشة الترحيب التي يعرضها المخطط الفارغ على العنصر Import الذي يضم التنسيقات الخمسة نفسها، راجع شاشة الترحيب.

تُطابَق الامتدادات دون مراعاة حالة الأحرف. ويؤدي اختيار ملف لا يطابق امتداده التنسيق المختار إلى إلغاء الاستيراد وإظهار Only <format> files can be imported، حيث يُكتب التنسيق json أو sql أو graphql أو dbml أو aml، كما في Only sql files can be imported.

يستبدل Import المستند الحالي بدلًا من الدمج فيه، وتراجع واحد يعيد المخطط السابق.
يجلب ملف JSON إعداداته معه، بما فيها أقفاله. وحيث يقفل الملف علامة التبويب أو لغة منشئ التعليمات البرمجية أو نمط تسمية أو نوع علامات الاقتباس، تظل ترى ما كان لديك، لكن القيمة المقفلة في الملف هي التي تُحفظ. أما العرض، مقفلًا كان أم لا، فينتقل إلى الموضع الذي يحدده الملف. ويُستورد ملف JSON المحفوظ قبل وجود الأقفال مع تفعيل جميع الأقفال وضبط العرض على 100%.
أما التنسيقات الأخرى فتُبقي على إعداداتك الحالية، بما فيها الأقفال، باستثناء العرض الذي يبدأ عند 100%.
لا تفشل محللات GraphQL وDBML وAML أبدًا: فالملف الذي لا تستطيع قراءته ينتج مخططًا فارغًا بدلًا من خطأ.

يحتفظ ملف JSON بالمواضع الموجودة فيه. أما جداول ملف مخطط SQL أو GraphQL أو DBML أو AML فتُرتَّب قبل أن يتغير المخطط:

  • عندما يحتوي الملف على جدولين أو أكثر وعلاقة واحدة على الأقل، تُرتَّب الجداول بالخيار Flow في التخطيط التلقائي، من اليسار إلى اليمين على امتداد العلاقات، بدءًا من الزاوية العلوية اليسرى للوحة الرسم. وتُحتسب العلاقة التي تربط جدولًا بنفسه.
  • وإلا فتُرتَّب في صفوف بدءًا من الزاوية العلوية اليسرى، وتأتي الجداول ذات أقل عدد من الأعمدة أولًا.
  • إذا استغرق التخطيط أكثر من 6 ثوانٍ، يظهر الإشعار Placing tables مع الزر Cancel. ويؤدي Cancel، أو Escape أثناء ظهور الإشعار، إلى التخلي عن التخطيط وترتيب الجداول في صفوف بدلًا منه. وتُستخدم الصفوف أيضًا، دون إشعار، عندما يفشل التخطيط، أو عندما لا يعود أي تخطيط خلال 60 ثانية، أو عندما لا يشغّل المضيف SharedWorker، راجع Web Workers.

ثم يُستبدل المخطط في خطوة واحدة، فلا يظهر أي شيء في المرحلة الوسيطة. ويُحتفظ بأي إعداد تغيّره أثناء ترتيب الجداول، مثل علامة التبويب، وإذا استوردت ملفًا آخر في هذه الأثناء، فإن الاستيراد الذي بدأ أخيرًا هو الذي يُعتمد.

في محرر للقراءة فقط، لا يحمّل Import أي شيء، ولا يُعرض Import and Add.

استيراد وإضافة​

يُبقي Import and Add على المخطط ويضيف ملفًا أسفله. ويوجد في قائمة السياق للوحة الرسم وفي البحث السريع في علامة تبويب ERD، ويعرض التنسيقات الخمسة نفسها مع التحقق نفسه من الامتداد الذي يجريه Import.

إضافة ملف SQL من Import and Add &gt; Schema SQL، واستقرار جداوله أسفل المخطط مرتبةً على امتداد علاقاتها ومحددةً

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

تستقر الكتلة المضافة أسفل كل ما يحتويه المخطط مباشرةً، بمحاذاة حافته اليسرى، أو في الزاوية العلوية اليسرى إذا كان المخطط فارغًا. وتُحتسب كذلك الملاحظات ومجموعات الجداول المخفية عبر خيارات العرض، لأنها لا تزال قائمة في مواضعها.
داخل الكتلة، يحتفظ ملف JSON بترتيبه الخاص، بما فيه مجموعات الجداول. أما التنسيقات الأخرى فتُرتَّب كما يرتّبها Import، بالخيار Flow أو في صفوف وفق القواعد نفسها، ويُضبط مربع كل مجموعة جداول ليحيط بجداولها. وتأتي الجداول والملاحظات المضافة فوق كل ما هو موجود مسبقًا في ترتيب التراص.

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

إذا أُضيفت عدة ملفات مخطط SQL أو GraphQL أو DBML أو AML بينما لا يزال أحدها قيد الترتيب، فإنها تستقر جميعًا بالترتيب الذي بدأت به. أما ملف JSON المضاف في هذه الأثناء فيستقر فور قراءته، قبلها. ويؤدي Import، أو تحميل مستند آخر، إلى استبعاد أي ملفات لا تزال قيد الترتيب.

يضيف وكلاء البرمجة ملفًا بالطريقة نفسها عبر الوضع append في أدوات الاستيراد في MCP، الذي يحتفظ بترتيب ملف JSON لكنه يرتّب جداول التنسيقات الأخرى في صفوف، ولا يستخدم Flow أبدًا، راجع الاستيراد.

JSON​

يمكنك استيراد الملفات المكتوبة وفق تنسيق المخطط المعرّف في المحرر. يجب أن ينتهي اسم الملف بالامتداد .json، لذا يُستورد الملف المُصدَّر باسم <database name>-<timestamp>.erd.json مجددًا كما هو؛ أما الملف ذو الامتداد .erd أو .vuerd وحده فلا يُقبل هنا. وتُقرأ أيضًا الملفات المحفوظة بالإصدارات السابقة.

استيراد ملف محفوظ من Import &gt; json، واستبدال مستند المسودة مع إعداداته

مخطط SQL​

يمكنك أيضًا استيراد ملفات المخطط المعرّفة بلغة SQL.
رغم أن المحللات صُمّمت لتكون مرنة قدر الإمكان بصرف النظر عن نظام قاعدة البيانات، فقد توجد بعض الصيغ غير المدعومة.
يجب أن ينتهي اسم الملف بالامتداد .sql.
يمكن الاطلاع على الصيغ المدعومة هنا.

استيراد ملف SQL من Import &gt; Schema SQL، وترتيب جداوله على امتداد علاقاتها، ثم التصغير لعرضها

تأتي الأعمدة من CREATE TABLE فقط. ولا يُقرأ العمود المضاف بواسطة ALTER TABLE ... ADD COLUMN.
تُتخطى عناصر CREATE TABLE التي ليست أعمدة بدلًا من قراءتها كأعمدة: CHECK (...) بلا اسم، وLIKE وEXCLUDE في PostgreSQL، وFULLTEXT وSPATIAL في MySQL حين يُكتبان دون INDEX أو KEY، وPERIOD FOR في T-SQL، وSUPPLEMENTAL LOG DATA في Oracle.
ومع ذلك يُستورد العمود الذي يحمل اسم أحدها إذا تلا الاسمَ نوعٌ مدمج، كما في exclude BOOLEAN، أو إذا كان الاسم مقتبسًا، كما في "check" int. أما like غير المقتبس الذي يليه نوع غير مدمج، مثل like citext، فيُقرأ على أنه LIKE في PostgreSQL ويُتخطى.
أما قيود CHECK نفسها فلا تُستورد، لأن المحرر لا يملك مكانًا لحفظها.

أنواع البيانات​

يُحتفظ بنوع بيانات العمود، بما في ذلك قائمة وسائطه، حتى عندما لا يكون نوعًا مدمجًا في أي قاعدة بيانات مدعومة.
ويشمل ذلك نوع التعداد أو النوع المركّب المُنشأ باستخدام CREATE TYPE، والنطاق المُنشأ باستخدام CREATE DOMAIN، وأنواع الإضافات مثل hstore وcitext وltree، والأسماء المؤهلة باسم المخطط مثل public.mood، والأسماء المقتبسة أو الموضوعة بين أقواس مربعة مثل "MyType" و[dbo].[Phone]، التي تحتفظ بعلامات اقتباسها أو أقواسها. أما عبارات CREATE TYPE وCREATE DOMAIN وCREATE EXTENSION نفسها فتُتخطى.
أما النوع المدمج فتُزال عنه علامات الاقتباس أو الأقواس المربعة، فيُستورد [int] على أنه int و[nvarchar](50) على أنه nvarchar(50). ويحتفظ "char" و"bit" في PostgreSQL بعلامات اقتباسهما، لأنهما نوعان مختلفان عن char وbit.
تبقى لواحق المصفوفات على أي نوع: integer[] وtext[3][3] وinteger ARRAY وmood[]. ويُستورد UNSIGNED BIG INT في SQLite كاملًا.
يبقى UNSIGNED وZEROFILL في MySQL وMariaDB، عند كتابتهما مباشرةً بعد النوع ووسائطه، جزءًا من النوع كما كُتب: INT UNSIGNED وSMALLINT(5) UNSIGNED ZEROFILL وint unsigned الذي يكتبه mysqldump. ويُزال SIGNED، وهو القيمة الافتراضية، فيُستورد TINYINT SIGNED على أنه TINYINT. ويُزال مُعدِّل النوع المكتوب بعد خيار عمود آخر، كما في INT NOT NULL UNSIGNED الذي يرفضه MySQL.
تحتفظ قيم ENUM(...) وSET(...) بعلامات اقتباسها، مع مضاعفة علامة الاقتباس الواقعة داخل القيمة، كما في ENUM('a','it''s'). ويُستورد 'it\'s' المهرَّب بشرطة مائلة عكسية في MySQL مضاعفًا بالطريقة نفسها. وفي النوع STRUCT<...> من Databricks، تحتفظ أسماء الحقول المقتبسة وCOMMENT الخاص بالحقل بعلامات اقتباسها.
يبقى العمود المكتوب دون نوع، مثل عمود SQLite بلا نوع أو عمود محسوب باستخدام AS، بلا نوع: فلا تُقرأ كلمة مفتاحية مثل NOT أو NULL أو DEFAULT أو PRIMARY أو REFERENCES، ولا سلسلة نصية بين علامتي اقتباس مفردتين، على أنها نوع.

القيم الافتراضية​

يحتفظ DEFAULT الخاص بالعمود بتعبيره كاملًا، مثل now() أو 0.5 أو CURRENT_TIMESTAMP أو ARRAY[]::text[]، حتى خيار العمود التالي أو الفاصلة أو قوس الإغلاق. ويُقرأ CASE ... END كاملًا.
تُزال الأقواس المحيطة بالتعبير كله، فيُستورد ((0)) في SQL Server على أنه 0 و(getdate()) على أنه getdate(). ويُزال كذلك تحويل النوع المطبق على قيمة حرفية، فيُستورد 'draft'::character varying الذي يكتبه pg_dump على أنه 'draft' وNULL::character varying على أنه NULL؛ أما عمليات تحويل النوع الأخرى فتبقى، كما في ARRAY[]::text[] وlower('A'::text).
يُزال ON UPDATE CURRENT_TIMESTAMP في MySQL، لأن العمود لا يملك مكانًا له، وتبقى القيمة الافتراضية التي تسبقه. ويُستورد DEFAULT ON NULL 0 في Oracle، مع FOR INSERT ONLY أو FOR INSERT AND UPDATE أو بدونهما، على أنه 0.
تُقرأ السلسلة النصية ذات البادئة، مثل N'x' أو E'x' أو B'0' أو X'ff' أو U&'x' أو _utf8mb4'x'، على أنها سلسلة نصية واحدة، حتى لو احتوت على قوس.

يكتب SQL Server Management Studio القيم الافتراضية في سكربتاته بعد الجداول، على النحو ALTER TABLE [dbo].[t] ADD CONSTRAINT [DF_x] DEFAULT ((1)) FOR [col]. وتضبط عبارة كهذه القيمة الافتراضية لذلك العمود، وهي 1 هنا، ويُزال اسم القيد الخاص بها.

يعيد تصدير مخطط SQL الأقواس حيث لا تقرأ قاعدة البيانات تعبير القيمة الافتراضية إلا داخلها، راجع القيم الافتراضية.

التزايد التلقائي​

يفعّل كلٌّ من AUTO_INCREMENT وAUTOINCREMENT وIDENTITY الخيار Auto Increment للعمود، وكذلك GENERATED ALWAYS AS IDENTITY وGENERATED BY DEFAULT AS IDENTITY، اللذان لا يتركان أي قيمة افتراضية.
وكذلك تفعل القيمة الافتراضية المكونة من استدعاء واحد للدالة nextval() في PostgreSQL، وهي القيمة الافتراضية التي يحصل عليها عمود من النوع serial، وتُكتب nextval('s') أو، كما يكتبها pg_dump، nextval('s'::regclass). ولا يُحتفظ باسم التسلسل. أما القيمة الافتراضية التي تكتفي باستخدام تسلسل، مثل nextval('s') + 1 أو NEXT VALUE FOR s في SQL Server، فتبقى قيمة افتراضية عادية.
يكتب pg_dump كلتا الحالتين بعد الجداول، على النحو ALTER TABLE [ONLY] t ALTER [COLUMN] c SET DEFAULT nextval('s'::regclass) وALTER TABLE t ALTER [COLUMN] c ADD GENERATED ... AS IDENTITY. وتفعّل كلٌّ من العبارتين الخيار Auto Increment لذلك العمود وتمسح قيمته الافتراضية. وتُتخطى CREATE SEQUENCE وALTER SEQUENCE وكل إجراء آخر من إجراءات ALTER COLUMN.
أما العمود الذي يُحدَّد نوعه في تعريفه مباشرةً على أنه serial أو bigserial أو smallserial فيحتفظ بذلك النوع، مع بقاء Auto Increment معطّلًا.

لا يحتفظ المحرر إلا بالعلامة Auto Increment، وتكتب كل قاعدة بيانات صيغتها الخاصة عند التصدير، راجع التزايد التلقائي. ويكتب تصدير PostgreSQL العبارة GENERATED ALWAYS AS IDENTITY على عمود smallint أو integer أو bigint، أيًّا كانت الصيغة التي استُوردت، أما على أي نوع آخر، مثل INT UNSIGNED، فلا يكتب إلا سطر تعليق بعد الجدول. وتضيع خيارات التسلسل مثل START WITH 100.
يُستورد الجدول الذي يحتوي على عدة أعمدة serial أو identity بعدة أعمدة ذات تزايد تلقائي، ويرفض MySQL وMariaDB وSQL Server مثل هذا الجدول عند تشغيل تصديره.

المفاتيح الأساسية​

يضع المفتاح الأساسي المضاف بعد جدوله، ALTER TABLE t ADD [CONSTRAINT n] PRIMARY KEY (...)، علامة المفتاح الأساسي على أعمدته.
يُتجاوز عند القراءة CLUSTERED أو NONCLUSTERED في SQL Server وUSING BTREE في MySQL قبل قائمة الأعمدة، لذا فإن ALTER TABLE [dbo].[Users] ADD CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC) WITH (...) ON [PRIMARY] الذي يكتبه SQL Server Management Studio في سكربتاته يجعل Id مفتاحًا أساسيًا. ولا يُقرأ PRIMARY KEY NONCLUSTERED HASH (...) الخاص بالجدول المحسَّن للذاكرة، لا في ALTER TABLE ولا في CREATE TABLE.

المفاتيح الفريدة والفهارس​

يصبح UNIQUE المطبق على عمودين أو أكثر فهرسًا فريدًا واحدًا، بأي صيغة كُتب: UNIQUE (a, b) وUNIQUE KEY n (a, b) وUNIQUE INDEX n (a, b) وCONSTRAINT n UNIQUE (a, b) وINDEX n UNIQUE (a, b) المضمّن في SQL Server وALTER TABLE t ADD [CONSTRAINT n] UNIQUE (a, b).
يأخذ الفهرس اسم فهرس المفتاح، وإلا فاسم CONSTRAINT الخاص به، وإلا فلا اسم له، ويحتفظ بترتيب الفرز لكل عمود. ومثل هذا الفهرس مفتاح بديل.
أما UNIQUE المطبق على عمود واحد، بأي من تلك الصيغ، فيجعل ذلك العمود فريدًا بدلًا من ذلك ولا يضيف أي فهرس، لذا يعود القيد UQ_<table name>_<column name> الذي يكتبه التصدير إلى العلامة التي كُتب انطلاقًا منها. ويبقى CREATE UNIQUE INDEX المطبق على عمود واحد فهرسًا فريدًا.

تحتفظ عبارة ALTER TABLE التي تضيف عدة مفاتيح دفعة واحدة، كما في ADD PRIMARY KEY (id), ADD UNIQUE KEY uq_a (a, b), ADD UNIQUE KEY uq_c (c) الذي يكتبه phpMyAdmin، بكل مفتاح فريد فيها: يُستورد uq_a على أنه فهرس فريد باسم uq_a، وuq_c على أنه علامة فريد للعمود c. ولا يسمّي اسم CONSTRAINT إلا المفتاح الوارد في بنده. وتُقرأ أيضًا ADD UNIQUE INDEX IF NOT EXISTS n (...) في MariaDB وALTER TABLE t WITH CHECK ADD ... وWITH NOCHECK ADD ... في SQL Server.
تُقرأ CREATE INDEX وCREATE UNIQUE INDEX مع الأسماء المؤهلة مثل public.t و[dbo].[t]، وCLUSTERED وNONCLUSTERED في SQL Server، وCONCURRENTLY وIF NOT EXISTS وON ONLY وUSING btree في PostgreSQL، ودون أي اسم للفهرس كذلك. وتُتجاهل مجموعة الملفات ON [PRIMARY] في SQL Server.
لا تُعامَل خيارات المفتاح مثل NULLS NOT DISTINCT أو USING BTREE خطأً على أنها اسم المفتاح. وفي قائمة أعمدة المفتاح، لا تسمّي العمودَ إلا الكلمة الأولى، لذا فإن b DESC NULLS LAST وb text_pattern_ops وb COLLATE "C" كلها تجعل b عمودًا في المفتاح، مع بقاء DESC ترتيبَ الفرز الخاص به. ويُتجاوز طول البادئة مثل email(191) عند القراءة، لكن المفتاح الذي يتضمن جزءًا هو تعبير، مثل lower(email)، يُتخطى كاملًا.

يُستورد الفهرس الفريد الجزئي، CREATE UNIQUE INDEX ... WHERE ... أو INDEX n UNIQUE (...) WHERE ... المضمّن في SQL Server، على أنه فهرس عادي بالاسم والأعمدة نفسها، لأن مفتاحًا فريدًا على مستوى الجدول كله سيكون أكثر صرامة من المفتاح المقيَّد بشرط التصفية الذي يعلنه الملف. والاستثناء هو شرط تصفية لا يتكون إلا من اختبارات IS NOT NULL على أعمدة المفتاح مربوطة بالعامل AND، وهو الشرط الذي يحتاجه SQL Server ليسمح لعمود فريد بأن يحمل أكثر من قيمة NULL واحدة: فذلك المفتاح يبقى فريدًا.
يُستبعد المفتاح الفريد الذي يسمّي عمودًا غير موجود في الجدول، مثل عمود مضاف بواسطة ALTER TABLE ... ADD COLUMN، كاملًا بدلًا من اختصاره إلى الأعمدة الموجودة. أما الفهرس العادي فيحتفظ بالأعمدة الموجودة.

يكتب SQL Developer وDBMS_METADATA في Oracle الفهرسَ الخاص بالمفتاح على شكل CREATE UNIQUE INDEX منفصل، يحمل اسم المفتاح، أو، للمفتاح الذي لا اسم له ويليه USING INDEX، اسمًا يولّده النظام مثل SYS_C0012345. ويقرأ الاستيراد مثل هذا الفهرس، والفهرس الذي يسمّيه ADD CONSTRAINT ... USING INDEX، بوصفه جزءًا من مفتاحه: فيُستورد المفتاح الفريد المركّب على أنه فهرس فريد واحد، والمفتاح الأساسي أو المفتاح الفريد ذو العمود الواحد على أنه علامات أعمدة دون فهرس إضافي. وعند التصدير مجددًا إلى Oracle يُنشأ الفهرس مرة واحدة.

يعود تصدير مخطط SQL عند استيراده بعلامات فريد والفهارس نفسها في MySQL وMariaDB وMSSQL وOracle وPostgreSQL وSQLite.
لا يملك Snowflake فهارس ثانوية، لذا لا يعيد تصديره إلا المفاتيح الفريدة: المركّب منها على أنه فهرس فريد، وذو العمود الواحد على أنه علامة فريد للعمود. ولا يعلن تصدير Databricks أي تفرّد، لذا لا يعود منه شيء.

المفاتيح الخارجية​

يصبح المفتاح الخارجي علاقةً إذا كُتب بإحدى هذه الصيغ:

  • FOREIGN KEY (...) REFERENCES t (...) على مستوى الجدول، مع CONSTRAINT name أو بدونه.
  • ALTER TABLE ... ADD [CONSTRAINT name] FOREIGN KEY (...) REFERENCES t (...)، بما في ذلك ALTER TABLE t WITH CHECK ADD ... وWITH NOCHECK ADD ... اللذان يكتبهما SQL Server Management Studio في سكربتاته.
  • REFERENCES t (col) المضمّن في تعريف العمود، كما في user_id INT REFERENCES users (id)، وFOREIGN KEY REFERENCES t (col) الذي يسمح به SQL Server وSnowflake في الموضع نفسه. ويُتخطى المرجع المضمّن الذي يشير إلى أكثر من عمود واحد.

لا تعطي عبارة ALTER TABLE أكثر من علاقة واحدة، ولا تعطيها إلا عندما يضيف بندها الأول مفتاحًا خارجيًا: فلا يُقرأ بند FOREIGN KEY الوارد بعد بند ADD PRIMARY KEY أو ADD UNIQUE في العبارة نفسها. وعندما تضيف عبارة واحدة عدة مفاتيح خارجية، كما في ADD CONSTRAINT fk1 FOREIGN KEY ..., ADD CONSTRAINT fk2 FOREIGN KEY ... الذي يكتبه phpMyAdmin، لا يُقرأ إلا آخرها.

يشير REFERENCES t دون قائمة أعمدة إلى المفتاح الأساسي للجدول t عندما يتكون ذلك المفتاح من عمود واحد. أما مع مفتاح أساسي مركّب فيُتخطى المفتاح الخارجي.
يُتخطى المفتاح الخارجي، ولا تُوضع علامة المفتاح الخارجي على أي من أعمدته، عندما لا يُعثر على أي من أعمدته المُشار إليها، أو عندما يختلف عدد الأعمدة التي يُعثر عليها في الجدولين، كما لو كان عمود مفقودًا من أحدهما فقط. وعندما يفتقد كلا الجدولين العددَ نفسه من أعمدته، تُقرن الأعمدة التي عُثر عليها بترتيب كتابتها، ولا تضم العلاقة سواها.
كل علاقة مستوردة هي Zero N، وتكون مُعرِّفة عندما يكون كل عمود من أعمدتها في الجدول الفرعي مفتاحًا أساسيًا أيضًا.

يصبح بندا ON DELETE وON UPDATE في كل مفتاح خارجي قيمتَي On Delete وOn Update للعلاقة: NO ACTION أو RESTRICT أو CASCADE أو SET NULL أو SET DEFAULT، دون مراعاة حالة الأحرف وبأي ترتيب. ويُستورد المفتاح الخارجي الذي يخلو منهما بالقيمة Not set. لمعرفة كيفية ضبطهما في المحرر، راجع تحرير العلاقات.
تُتجاوز عند القراءة قائمة الأعمدة التي تلي SET NULL أو SET DEFAULT في PostgreSQL، كما في ON DELETE SET NULL (a_id): فالإجراء ينطبق على المفتاح كله، ويظل ON UPDATE الوارد بعد القائمة مقروءًا. وتُتخطى MATCH FULL وMATCH PARTIAL وMATCH SIMPLE، ولا تُعامَل سمة العمود ON UPDATE CURRENT_TIMESTAMP في MySQL خطأً على أنها إجراء.
يُستورد تصدير مخطط SQL مجددًا بالإجراءات التي تكتبها قاعدة البيانات تلك، لذا يعود الإجراء الذي تستبعده، مثل SET DEFAULT في MySQL، أو أي ON UPDATE في Oracle، أو أي شيء عدا NO ACTION في Snowflake، بالقيمة Not set.

التعليقات​

تُستورد تعليقات الجداول والأعمدة من الصيغ الثلاث التي يقرؤها المحلل: خيار الجدول وسمة العمود COMMENT اللذان يستخدمهما MySQL وMariaDB وSnowflake وDatabricks، وعبارتا COMMENT ON TABLE وCOMMENT ON COLUMN اللتان يستخدمهما PostgreSQL وOracle، والخاصية الموسّعة MS_Description التي يضبطها SQL Server باستخدام EXEC sp_addextendedproperty.
ويُتجاهل التعليق الذي يسمّي جدولًا أو عمودًا لا يعرّفه الملف.

تُقرأ استدعاءات SQL Server بالوسائط المسمّاة، كما يكتب SQL Server Management Studio كل تعليق في سكربتاته (@name=N'MS_Description', @value=N'...', ..., @level1type=N'TABLE', @level1name=N'Users')، وبالوسائط الموضعية، كما يكتبها تصدير MSSQL في المحرر.
لا يعطي تعليقًا إلا MS_Description المطبق على جدول، أو على أحد أعمدته في المستوى 2. ولا تعطي خاصية أخرى أو طريقة عرض أو فهرس أو قيد أي تعليق، ولا التعليق الممرَّر في متغير أو المبني باستخدام +.

في التعليق، كما في أي نص مقتبس مثل قيمة DEFAULT أو اسم مقتبس، تمثل علامة الاقتباس المضاعفة علامة اقتباس واحدة، على النحو الذي يكتبها به mysqldump وpg_dump: يُقرأ 'it''s' على أنه it's.
وتهرّب الشرطة المائلة العكسية علامةَ الاقتباس التي تليها أيضًا، كما في 'it\'s' الذي يكتبه MySQL وMariaDB. ومع ذلك تُنهي علامة الاقتباس هذه النص إذا تلتها مسافة بيضاء أو , أو ; أو ) أو ] أو : أو | أو + أو نهاية الملف، لذا يحتفظ 'C:\' و'C:\'::text الذي يكتبه pg_dump و'C:\'+name في T-SQL بالشرطة المائلة العكسية فيها.
تحتفظ قيمة DEFAULT بعلامات اقتباسها، وتُكتب علامة الاقتباس الموجودة داخلها مضاعفةً أيًّا كانت طريقة تهريبها في الملف: 'it''s'.
عندما تكون قاعدة بيانات المستند هي Databricks وقت الاستيراد، يتبع النص الموضوع بين علامتي اقتباس مفردتين قواعد Spark بدلًا من ذلك: كل شرطة مائلة عكسية تهرّب الحرف الذي يليها، لذا يُقرأ 'C:\\dir' على أنه C:\dir، وتُفك تسلسلات التهريب مثل \n و\t و\u0041، ويُحتفظ بقيمة DEFAULT على أنها 'it\'s'.

يهرّب مخطط SQL المُصدَّر علامة الاقتباس الواقعة داخل تعليق الجدول أو العمود: COMMENT 'it''s' في MySQL وMariaDB وSnowflake، وCOMMENT ON TABLE وCOMMENT ON COLUMN ... IS 'it''s' في PostgreSQL وOracle، والمضاعفة نفسها، بما في ذلك أسماء الجداول والأعمدة، في استدعاءات sp_addextendedproperty في MSSQL. ويُكتب التعليق الذي لا يحتوي على علامة اقتباس كما هو.
أما Databricks فيهرّب علامة الاقتباس والشرطة المائلة العكسية بشرطة مائلة عكسية بدلًا من ذلك، كما في COMMENT 'it\'s'، لذا لا يُقرأ تصديره مجددًا بدقة إلا ما دام Databricks هو قاعدة البيانات المحددة.
يكتب MSSQL كل تعليق على النحو EXECUTE sys.sp_addextendedproperty 'MS_Description', '<comment>', 'schema', '<schema>', 'table', '<table>'، متبوعًا بالجزء 'column', '<column>' في حالة العمود. وعندما يكون Bracket على None، يعطي الجدول المسمّى sales.users المخطط sales والجدول users، ويكون الاسم الذي لا مخطط فيه ضمن dbo. ومع أي قيمة أخرى للخيار Bracket يكون الاسم كله هو الجدول، ضمن dbo.

لا تصمد التعليقات عند تصدير SQLite ثم إعادة استيراده: إذ يكتبها SQLite على شكل أسطر -- عادية، لا يقرؤها المحلل. أما استدعاءات sp_addextendedproperty في تصدير MSSQL فتُستورد مجددًا على أنها تعليقات الجداول والأعمدة نفسها.

GraphQL​

يمكنك استيراد مستند GraphQL SDL.
تصبح تعريفات أنواع الكائنات جداول، وتندمج كتلة extend type في النوع الذي توسّعه، وترث الأنواعُ التي تنفّذ الواجهات حقولَ تلك الواجهات.
يصبح الحقل الذي نوعه جدول آخر علاقةً بدلًا من عمود، وتُنشئ القائمة على كلا الجانبين جدول ربط.
يُقرن الحقل المفرد مثل buyer: User أولًا بالحقل الوحيد في النوع الآخر الذي ينتهي اسمه بالمقطع By متبوعًا باسم ذلك الحقل، مثل orderListByBuyer، دون مراعاة حالة الأحرف والشرطات السفلية؛ ويُقرن الحقل المرقّم مثل buyer2 بالطريقة نفسها دون رقمه. وهذه هي الطريقة التي تسمّي بها مخرجات GraphQL في منشئ التعليمات البرمجية الحقولَ عندما يتشارك جدولان أكثر من علاقة واحدة أو يشير جدول إلى نفسه، لذا تُستورد هذه المخرجات مجددًا بكل علاقاتها.
تُعامَل الأنواع الجذرية (Query وMutation وSubscription) وأنواع الاستبطان وأغلفة Relay والاتحاد وHasura، مثل PageInfo و*Connection و*Edge و*_aggregate، على أنها ضوضاء وتُتخطى.
تُراعى التوجيهات @id و@primaryKey و@unique و@autoincrement و@default و@map و@relation و@column و@table و@index و@db.*.
يجب أن ينتهي اسم الملف بالامتداد .graphql أو .gql أو .graphqls. أما ملف schema.prisma من Prisma فليس مستند GraphQL ولا يمكن استيراده هنا.

DBML​

يمكنك استيراد ملف DBML، وهو التنسيق الذي يستخدمه dbdiagram.io وdbdocs.
تُقرأ كتل Table وTablePartial وRef وEnum وTableGroup. أما كتل Project وكتل Note المستقلة فتُتخطى دون التأثير في الجداول المحيطة بها.
تُقبل كل صيغ كتابة المراجع: صيغة النقطتين Ref:، والمرجع المسمّى، وصيغة الكتلة Ref { }، وإعداد العمود المضمّن [ref: > table.column].
يُنشئ المرجع <> من نوع متعدد إلى متعدد جدول ربط يحمل اسمَي الطرفين.
يصبح الإعدادان delete وupdate في المرجع المستقل قيمتَي On Delete وOn Update للعلاقة، كما في Ref: users.id < posts.user_id [delete: cascade, update: set null]. والقيم هي cascade وrestrict وset null وset default وno action، دون مراعاة حالة الأحرف. وتُستورد أي قيمة أخرى، أو غياب الإعداد، بالقيمة Not set، وتُتجاهل الإعدادات الأخرى مثل color.
لا يحمل الإعداد المضمّن [ref: ...] أي إجراءات، ولا تُنقل إعدادات المرجع <> إلى جدول الربط. وعندما يُعلَن المفتاح الخارجي نفسه مضمّنًا ومرجعًا مستقلًا معًا، يُحتفظ بالمضمّن، دون إجراءات.
يصبح الإعداد headercolor للجدول، كما في Table users [headercolor: #3498DB]، لونَ الجدول عندما تكون القيمة رمزًا سداسيًا عشريًا #rgb أو #rrggbb مكتوبًا دون علامات اقتباس. وتُستبعد أي قيمة أخرى، ولا يُنقل headercolor في الكتلة TablePartial إلى الجداول التي تستخدمها.
يصبح كل TableGroup مجموعة جداول تضم الجداول التي يسردها، جدولًا في كل سطر، مسمّاةً كما يسمّيها Ref. ويصبح [color: ...] الخاص به لونَ المجموعة وفق القاعدة نفسها المتبعة مع headercolor، وتُستبعد ملاحظته وإعداداته الأخرى. والجدول الذي تسرده مجموعتان يبقى في الأولى. ولا تُنشأ المجموعة التي لا يتبقى فيها أي جدول، سواء لم تسرد أي جدول يعلنه الملف أو لم تسرد إلا جداول أخذتها مجموعة سابقة. ويُضبط مربع المجموعة ليحيط بجداولها أينما رُتّبت، وعندما تُرتَّب الجداول في صفوف، تبقى جداول المجموعة معًا.
يجب أن ينتهي اسم الملف بالامتداد .dbml.

AML​

يمكنك استيراد ملف AML (Azimutt Markup Language). وتُقبل الصيغة الحالية والصيغة القديمة v1 كلتاهما.
تصبح الكيانات جداول، وتُسطَّح السمات المتداخلة إلى اسم عمود منقّط مثل settings.slug.
تكون السمات NOT NULL ما لم تحمل العلامة nullable، وتُستبعد البنى التي لا يملك المحرر مكانًا لها، مثل check وtype وtags، بدلًا من رفضها. ويُستورد الكيان الموسوم بأنه طريقة عرض جدولًا عاديًا.
تصبح الخاصية color للكيان، كما في users {color: red}، لونَ جدوله. وتُقرأ أسماء الألوان في AML، وهي red وorange وamber وyellow وlime وgreen وemerald وteal وcyan وsky وblue وindigo وviolet وpurple وfuchsia وpink وrose وgray، دون مراعاة حالة الأحرف، مقتبسةً أو غير مقتبسة، وكلٌّ منها على أنه الدرجة 500 من لون Tailwind الذي يحمل الاسم نفسه، مثل #ef4444 للون red. ويُحتفظ بالقيمة السداسية العشرية المقتبسة مثل "#3498db" كما كُتبت؛ أما #3498db غير المقتبسة فلا يمكن قراءتها، لأن # يبدأ تعليقًا في AML. وتُستبعد أي قيمة أخرى، وكذلك color المطبق على سمة أو علاقة.
تحتفظ العبارة المستقلة rel، أو fk في الصيغة القديمة، بخاصيتيها onDelete وonUpdate بوصفهما قيمتَي On Delete وOn Update للعلاقة، كما في rel posts(user_id) -> users(id) {onDelete: cascade, onUpdate: "set null"}. والقيم هي cascade وrestrict وset null وset default وno action، مقتبسةً أو غير مقتبسة، دون مراعاة حالة الأحرف. وتُستبعد الخصائص الأخرى.
في العلاقة المضمّنة مثل user_id int -> users(id) {onDelete: cascade}، تنتمي الخصائص إلى السمة، لذا تُستبعد وتُستورد العلاقة بالقيمة Not set.
يجب أن ينتهي اسم الملف بالامتداد .aml.

GraphQL وDBML وAML تنسيقات قابلة للتحويل ذهابًا وإيابًا: إذ إن كلًّا منها هدف من أهداف منشئ التعليمات البرمجية أيضًا.
ينقل DBML وAML قيمتَي ON DELETE وON UPDATE لكل علاقة في الاتجاهين، راجع منشئ التعليمات البرمجية. أما GraphQL فلا ينقل أيًّا منهما، لذا يترك استيراد GraphQL كلتيهما على Not set.
وينقل DBML أيضًا ألوان الجداول، مع إسقاط أي شفافية، وكل مجموعة جداول تضم جدولًا، في الاتجاهين. وتعود المجموعة التي لا اسم لها باسم group_1 وgroup_2 وهكذا، ويعود اسم المجموعة المكرر مضافًا إليه _2 و_3 وهكذا. أما AML فلا ينقل لون الجدول إلا على أنه أقرب أسماء ألوانه، فيُكتب #FF8800 على أنه orange ويعود على أنه #f97316، ولا ينقل أي مجموعات. ولا ينقل GraphQL الألوان ولا المجموعات.

التصدير​

تحتوي القائمة الفرعية Export في قائمة السياق للوحة الرسم على ثلاثة عناصر:

  • json: يحفظ المخطط كما يحتويه ملفه، على شكل ملف .erd.json: الجداول بأعمدتها وفهارسها، والعلاقات والملاحظات ومجموعات الجداول، والإعدادات، مع كل إعداد مقفل بقيمته المقفلة.
  • Schema SQL: يفتح علامة تبويب مخطط SQL ولوحة خياراتها مفتوحة والتركيز على الزر Save file، لذا يحفظ الضغط على Enter نص SQL الذي تعرضه علامة التبويب على شكل ملف .sql. ولا يُحفظ شيء قبل ذلك.
  • Image: يفتح مربع الحوار Export image، الذي يحفظ المخطط على شكل ملف .png أو .svg، أو ينسخه إلى الحافظة بصورة PNG، راجع الصورة.

تعمل العناصر الثلاثة كلها في محرر للقراءة فقط.

يكتب مخطط SQL قيمتَي ON DELETE وON UPDATE لكل علاقة بعد REFERENCES الخاص بها، مع ON DELETE أولًا. ولا يكتب Not set شيئًا، ويُستبعد الإجراء الذي لا تقبله قاعدة البيانات المحددة. لمعرفة الإجراءات التي تقبلها كل قاعدة بيانات، راجع تحرير العلاقات.

يُسمّى كل ملف مُصدَّر <database name>-<timestamp> متبوعًا بامتداده، ويكون الطابع الزمني بالتوقيت المحلي ومنسقًا على النحو yyyy-MM-dd'T'HH_mm_ss — على سبيل المثال my-schema-2026-08-29T04_05_06.erd.json. وإذا كان اسم قاعدة البيانات فارغًا، يُستخدم unnamed بدلًا منه.
ويسمّي Save file في علامة تبويب مخطط SQL وفي منشئ التعليمات البرمجية الملفات بالطريقة نفسها. وتأخذ الصورة اسم قاعدة البيانات كما كان عند فتح مربع الحوار.

يتوفر Import وImport and Add وExport أيضًا من البحث السريع في علامة تبويب ERD، بالعناصر نفسها الموجودة في قائمة السياق للوحة الرسم.

في Obsidian لا يظهر أي مربع حوار للتنزيل أو الحفظ: إذ يُكتب الملف في الخزنة، في الموضع الذي يضع فيه Obsidian المرفقات الجديدة لذلك المخطط، ويذكر إشعارٌ مساره.
تُستبدل الأحرف التي لا يسمح بها Obsidian في اسم الملف، \ / : * ? " < > |، بالرمز -.
لا يعرض مستكشف الملفات في Obsidian ملف .erd.json أو .sql المُصدَّر إلا ما دام Settings → Files and links → Detect all file extensions مفعّلًا.

الصورة​

يفتح Export ▸ Image، من قائمة السياق للوحة الرسم أو من البحث السريع، مربع الحوار Export image: معاينة للصورة بجوار خياراتها. ويبقى المستكشف المفتوح مفتوحًا تحت المنطقة المعتّمة.

فتح Export &gt; Image، وتعطيل الوضع الداكن والخلفية، واختيار 3x، ونسخ الصورة إلى الحافظة

  • Background: مفعّل افتراضيًا. وعند تعطيله تبقى لوحة الرسم شفافة.
  • Dark mode: يبدأ مطابقًا لمظهر المحرر. وما دام مطابقًا للمظهر المعروض على الشاشة، تأخذ الصورة ألوان لوحة الرسم نفسها، بما فيها تغييرات منشئ النسق؛ أما المظهر الآخر فيستخدم النسق المعدّ مسبقًا ذا درجة الرمادي ولون التمييز نفسيهما.
  • Scale: 1x أو 2x أو 3x، مع تحديد 2x افتراضيًا. ولا يضبط إلا حجم ملف PNG والنسخة الموجودة في الحافظة، ويعرض السطر الذي تحته ذلك الحجم على النحو PNG <width> × <height> px.

يُحتفظ بالخيارات حتى يُغلق المحرر، ولا تُحفظ في المستند أبدًا. وتُرسم المعاينة بالطريقة التي تُرسم بها الصورة، ويُعاد رسمها عندما يتغير Background أو Dark mode.

تضم الصورة المخطط كما كان عند فتح مربع الحوار؛ أغلق مربع الحوار وأعد فتحه لتضمين التغييرات اللاحقة. وتضم المخطط كله مهما ابتعد العرض عنه بالتمرير، مقصوصةً على ما يرسمه المخطط مع هامش، وتُرسم دائمًا عند 100%، أيًّا كان مستوى التكبير الذي يعرضه المحرر، فيُرسم كل جدول كاملًا. وما تخفيه خيارات العرض — العلاقات أو تسميات ON DELETE وON UPDATE الخاصة بها أو مجموعات الجداول أو الملاحظات — لا يُرسم ولا تُخصص له مساحة، وتُرسم مجموعات الجداول خلف كل شيء آخر.

توجد ثلاثة أزرار تكتب الصورة، ويُبقي كلٌّ منها مربع الحوار مفتوحًا:

  • PNG: يحفظ ملف .png بحجم المخطط عند 100% مضروبًا في Scale. وتُكتب صورة PNG الأكبر من أن تستوعبها لوحة الرسم في المتصفح بدقة مخفضة بدلًا من أن تفشل العملية: إذ يحذّر مربع الحوار مسبقًا بالرسالة Reduced from <width> × <height> px, past what a browser canvas can hold، ويذكر ذلك لاحقًا إشعارٌ نصه Exported at a reduced resolution.
  • SVG: يحفظ ملف .svg بحجم المخطط عند 100%، أيًّا كانت قيمة Scale، ولا يُخفَّض أبدًا. ويبقى نصه نصًا، وتُذكر خطوطه بأسمائها بدلًا من تضمينها، لذا يرسم برنامج العرض الذي لا يتوفر لديه خط المحرر خطًا آخر. وتُستبعد الظلال.
  • Copy to clipboard: يضع صورة PNG في الحافظة بقيمة Scale المختارة، مع تخفيضها كما يُخفَّض ملف PNG المحفوظ عندما لا تستوعبها لوحة الرسم في المتصفح. ويؤكد ذلك بالرسالة Copied the image to the clipboard، أو بالرسالة Copied at a reduced resolution عندما تكون الصورة قد خُفّضت. وإذا فشل النسخ، لأن المتصفح أو المضيف يرفض استخدام الحافظة أو لأن الصورة تعذر رسمها، تقترح الرسالة Couldn't copy the image حفظ ملف PNG بدلًا من ذلك.

تُرسم الصورة في Web Worker يعمل في الخلفية حيثما يتيحه المضيف، فيبقى المحرر قابلًا للاستخدام في أثناء ذلك. ويظهر إشعار نصه Exporting PNG أو Exporting SVG أو Copying image عندما يستغرق الأمر أكثر من لحظة، ويُبلَّغ عن الفشل بالرسالة Couldn't export the PNG أو Couldn't export the SVG. ولا يؤدي إغلاق مربع الحوار بينما لا يزال ملف قيد الرسم إلى إيقاف حفظ ذلك الملف.

يكون التركيز على PNG عند فتح مربع الحوار، ولا ينقل Tab التركيز خارج مربع الحوار. ويُغلقه Escape أو الزر x أو النقر على المنطقة المعتّمة المحيطة به.
أثناء فتحه، لا تفعل اختصارات لوحة الرسم، بما فيها التراجع والإعادة، شيئًا، وكذلك النسخ واللصق. ويُغلقه Ctrl + K (Windows/Linux) أو ⌘ + K (Mac) ويفتح البحث السريع. ويُغلقه Ctrl + F (Windows/Linux) أو ⌘ + F (Mac) ويضع مؤشر الكتابة في حقل البحث في المستكشف، فيفتح المستكشف إن كان مغلقًا، ولا يغلقه أبدًا. وفي محرر أضيق من أن يعرض المستكشف، يظل يغلق مربع الحوار لكنه يعرض إشعارًا منبثقًا بدلًا من نقل مؤشر الكتابة.