للعلاقات عواقب
متاح أيضًا بـ28 لغة
English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

الوحدة 7 من 10 في فصل معمارية بيانات Salesforce، الفصل 3 من دورة Data Architect. كل وحدة قائمة بذاتها. السابق: الحقول معمارية أيضًا · التالي: الملكية ودورة الحياة
السؤال الذي تجيب عنه هذه الوحدة: ما الذي أختاره حقًا حين أربط كائنين في Salesforce؟
رسم العلاقة سهل. في الفصل 2 رسمنا خطوطًا وسمّيناها: شريك التجزئة يرسل بيانات شحن كثيرة، والتوصيلة تحمل بنودًا كثيرة، والطواقم والشاحنات تلتقي في تكليف الطاقم (Crew Assignment). تحدثنا عن الكاردينالية، والاختيارية، والتاريخ. والآن ننفّذ تلك الخطوط على Salesforce، ويبدأ الخط على المخطط بحمل وزن أكبر بكثير.
عندما أختار نوع علاقة على Salesforce، فأنا لا أقول فقط هذان السجلان مترابطان. قد أقرر أيضًا من يملك الابن، وهل يمكن أن يوجد دون الأب، ومن يستطيع رؤيته، وما الذي يحدث عند حذف الأب، وهل يمكن نقله إلى أب آخر، وهل أستطيع تلخيصه على الأب، وما الذي يحدث حين يكون هناك مئات الآلاف من الأبناء. العلاقة ليست مجرد خط. إنها تحمل سلوكًا.
ابدأ بالعلاقة التجارية
Section titled “ابدأ بالعلاقة التجارية ”قبل علاقة البحث أو علاقة رئيسي-تفصيلي، عُد إلى العمل. خذ التوصيلة (Delivery) وبنودها (Delivery Items)، الثلاجة، والتركيب، ونقل القديم. هل يمكن أن يوجد بند دون توصيلته؟ لا. إذا حُذفت التوصيلة، فهل ينبغي أن تذهب بنودها أيضًا؟ نعم. هل تحتاج البنود إلى مالك خاص بها أو أمان خاص بها؟ ليس فعلًا. هل ينبغي لأحد أن ينقل بندًا من توصيلة إلى أخرى؟ نأمل ألا يحدث ذلك عن طريق الخطأ.
والآن خذ التوصيلة والمسار (Route) الذي تقع عليه. التوصيلة موجودة قبل أن تُوجَّه إلى مسار، ويمكن نقلها إلى مسار آخر حين تتغير الخطة، وحذف مسار لا ينبغي أبدًا أن يحذف التوصيلات التي عليه. خطّان من واحد إلى متعدد يبدوان متماثلين على المخطط، بسلوك مختلف تمامًا. لاحظ أننا لم نقل بعد «علاقة بحث» أو «رئيسي-تفصيلي». صِف السلوك أولًا. والإعداد ينفّذه.
أنواع العلاقات
Section titled “أنواع العلاقات ”افتح شاشة New Field فتعرض عليك Salesforce حفنة من أنواع العلاقات (Object Relationships Overview (opens in a new tab)):
- علاقة البحث (Lookup): تربط كائنين. الخبز والملح في علاقات Salesforce.
- رئيسي-تفصيلي (Master-detail): رباط بين أب وابن يتحكم فيه الأب بالابن.
- متعدد إلى متعدد (Many-to-many): ليس نوع حقل قائمًا بذاته، بل نمط: كائن الربط في Salesforce (Salesforce Junction Object)، وهو كائن مخصص بعلاقتي رئيسي-تفصيلي.
- العلاقة الذاتية (Self-relationship): علاقة بحث من كائن إلى نفسه.
- الهرمية (Hierarchical): علاقة بحث خاصة لا توجد إلا على كائن User، مثل مدير المستخدم.
- علاقة البحث الخارجية (External lookup) وعلاقة البحث غير المباشرة (indirect lookup): العلاقات من الكائنات الخارجية وإليها، كائنات
__xمن الوحدة 4. علاقة البحث الخارجية تشير إلى كائن خارجي أب؛ وعلاقة البحث غير المباشرة تشير من كائن خارجي إلى كائن قياسي أو مخصص، بالمطابقة على External ID فريد.
معظم وقت تصميمك يذهب إلى الثلاثة الأولى. لنتناولها واحدة تلو الأخرى.
علاقة البحث: هذه السجلات مترابطة
Section titled “علاقة البحث: هذه السجلات مترابطة ”علاقة البحث تقول: هذا السجل مرتبط بذلك السجل. يحتفظ الابن بكيانه الخاص، ومالكه الخاص، وحياته الخاصة. تشير التوصيلة إلى مسارها. إذا أُلغي المسار، فلا تختفي التوصيلات؛ بل تعود لتُوجَّه من جديد.
الطريف أن حقل البحث يوضع على الابن، لكن الأب يحصل على شيء أيضًا، قائمة مرتبطة (related list) بأبنائه. لذا عندما تُنشئ واحدة، سمِّ الطرفين. Related List Label هو ما يراه الناس على الأب، وChild Relationship Name هو ما يستخدمه المطوّرون والتكاملات للانتقال من الأب إلى الأبناء. لا تقبل القيم الافتراضية.
يمكن أن تكون علاقة البحث إلزامية أو اختيارية. وعندما تكون اختيارية، تقرر أنت ما الذي يحدث إذا حُذف السجل الذي تشير إليه، وهناك ثلاثة خيارات (Considerations for Object Relationships (opens in a new tab)):
- Clear the value of this field (مسح قيمة هذا الحقل)، وهو الافتراضي. يبقى الابن، بعلاقة بحث فارغة.
- Don’t allow deletion (عدم السماح بحذف) سجل البحث. حاول حذف المسار، فتقول Salesforce لا: إنه جزء من علاقة.
- Delete this record also (حذف هذا السجل أيضًا)، أي حذف متتالٍ (cascade delete)، مثل علاقة رئيسي-تفصيلي. ولا يُعرض إلا لعلاقة بحث مخصصة على كائن مخصص، وهو معطّل افتراضيًا، ويجب أن تفعّله Salesforce لمؤسستك، لأن الحذف المتتالي يتجاوز الأمان والمشاركة: فيستطيع المستخدمون حذف سجلات لم يكونوا حتى قادرين على رؤيتها.
هذا قرار دورة حياة مختبئ في شاشة إعداد.
مرشحات البحث (Lookup filters) تضيّق ما يستطيع المستخدم اختياره. لنقل إن للتوصيلة علاقة بحث Installer إلى جهة الاتصال، وإن المركّبين نوع سجل واحد من جهات الاتصال بين أنواع كثيرة. مرشح البحث يُظهر المركّبين فقط، ويمكنه التصفية على السجل الحالي، وعلى السجل الذي يُبحث عنه، وعلى المستخدم: ملف تعريفه أو دوره أو أذوناته (Lookup Filters (opens in a new tab)). إنها طريقة رخيصة لإبقاء علاقة البحث صادقة.
رئيسي-تفصيلي: هذا الابن ينتمي إلى ذلك الأب
Section titled “رئيسي-تفصيلي: هذا الابن ينتمي إلى ذلك الأب ”علاقة رئيسي-تفصيلي تُدلي بتصريح أقوى بكثير. في الصف أسميها رباطًا محكمًا جدًا. لا يمكن أن يكون لديك سجل تفصيلي دون رئيسيه؛ فحقل الرئيسي إلزامي. ويفقد السجل التفصيلي حقل Owner الخاص به ويرث مالك أبيه. ولا يوجد جدول مشاركة منفصل للتفصيلي، لذا لا يمكنك مشاركة ابن وحده؛ فهو يرث مشاركة أبيه. لهذا لا يمكن أن يكون للكائن التفصيلي قواعد مشاركة، أو مشاركة يدوية، أو قوائم انتظار: فكلها تحتاج إلى حقل Owner (Object Relationships Overview (opens in a new tab)). وفي Setup يظهر إعداد مشاركته هكذا: Controlled by Parent (يتحكم فيه الأب). وعلى حقل رئيسي-تفصيلي نفسه تختار Sharing Setting (إعداد المشاركة): هل يحتاج المستخدم إلى وصول Read Only أو Read/Write إلى الرئيسي لإنشاء سجلاته التفصيلية أو تعديلها أو حذفها. وحذف الرئيسي يحذف سجلاته التفصيلية. ويحصل الرئيسي على حقول الملخص التجميعي (roll-up summary).
لذا إذا كان بند التوصيلة سجلًا تفصيليًا للتوصيلة، فأنا أقول: هذا البند ينتمي إلى هذه التوصيلة طوال حياته. هذا هو السؤال الذي أريد إجابته قبل أن يختار أحد Master-Detail Relationship في Setup.
سؤال الحذف
Section titled “سؤال الحذف ”إليك طريقتي المفضلة لمعرفة ما إذا كنا قد فكرنا في الأمر جيدًا: ما الذي ينبغي أن يحدث للأبناء إذا حذف أحدهم الأب؟ يشعر الجميع بعدم الارتياح. جيد. الآن نحن نمارس المعمارية.
لدى شريك التجزئة مئات الآلاف من التوصيلات التاريخية. يحذف أحدهم الشريك. هل ينبغي أن تختفي التوصيلات؟ بالتأكيد تقريبًا لا: فالمطالبات والفوترة والتاريخ كلها تعتمد عليها. ربما لا ينبغي السماح بحذف شريك أصلًا، وينبغي تعطيله بدلًا من ذلك. في علاقة رئيسي-تفصيلي، يمتد حذف الرئيسي متتاليًا إلى سجلاته التفصيلية وتفصيلياتها؛ واستعادة الرئيسي تعيدها (Considerations for Object Relationships (opens in a new tab)). لذا عندما يقول أحدهم «علاقة رئيسي-تفصيلي تعطينا الملخصات التجميعية»، فإجابتي: رائع. وعلى ماذا وافقت أيضًا للتو؟
الملكية تأتي معها
Section titled “الملكية تأتي معها ”مع علاقة البحث، يمكن أن يكون للابن مالكه الخاص. ومع رئيسي-تفصيلي، لا يمكن؛ فالوصول يتبع الرئيسي. وهذا صحيح تمامًا إذا كان السجل التفصيلي جزءًا من الأب حقًا. لكن إذا احتاج الابن إلى مالكه الخاص، أو مشاركته الخاصة، أو دورة حياته الخاصة، فالنموذج يخبرك أن رئيسي-تفصيلي هو الخيار الخاطئ. الوحدة التالية تتعمق أكثر في الملكية، ودورة Sharing and Visibility تذهب أبعد من ذلك. أما الآن: تصميم العلاقات وتصميم الأمان ليسا حوارين منفصلين. نموذج البيانات يشكّل نموذج الأمان قبل أن يكتب أحد قاعدة مشاركة.
أب إلزامي أم اختياري؟
Section titled “أب إلزامي أم اختياري؟ ”هل يمكن أن يوجد الابن قبل أن نعرف أباه؟ هذا أهم مما يبدو. إذا كانت التوصيلات تصل على بيان الشحنة في الليلة السابقة وتُبنى المسارات بعد ذلك، فإن جعل المسار إلزاميًا على التوصيلة يعني أن التوجيه يجب أن يحدث قبل أن يمكن إنشاء السجل أصلًا. يجب أن تدعم العلاقة المادية دورة الحياة الحقيقية. لذا لا أصمّم العلاقات من مخطط ثابت وحده. أريد أن أعرف: كيف تولد، وهل يمكن أن توجد وحدها، وهل يمكن أن تنتقل، وكيف تموت؟
هل يمكن للابن تغيير أبيه؟
Section titled “هل يمكن للابن تغيير أبيه؟ ”افتراضيًا، لا يمكن نقل ابن في علاقة رئيسي-تفصيلي إلى أب آخر. يمكنك السماح بذلك، بتحديد Allow reparenting (السماح بتغيير الأب) على العلاقة (Considerations for Object Relationships (opens in a new tab)). وغريزتي محافظة: إذا قال العمل إن الابن ينتمي إلى أب واحد مدى الحياة، فلا أجعل نقله سهلًا. نقل بند من توصيلة إلى أخرى ينبغي أن يكون حدثًا تجاريًا متعمّدًا، لا تعديل حقل. ومرة أخرى، الإعداد ليس المعمارية. قاعدة دورة الحياة هي المعمارية، والإعداد ينفّذها.
أمران آخران يوقعان الفرق لاحقًا. لا يمكنك إنشاء علاقة رئيسي-تفصيلي على كائن فيه بيانات بالفعل؛ بل تُنشئ علاقة بحث، وتملؤها على كل سجل، ثم تحوّلها. ولا يمكنك التحويل مرة أخرى إلى علاقة بحث إلا إذا لم تكن هناك حقول ملخص تجميعي على الرئيسي. وانتبه أيضًا إلى ما يفعله التحويل بالأمان: تحويل علاقة بحث إلى رئيسي-تفصيلي يضبط مشاركة الابن على Controlled by Parent، وتحويل رئيسي-تفصيلي مرة أخرى إلى علاقة بحث يضبط الإعداد الافتراضي على مستوى المؤسسة للابن على Public Read/Write (Considerations for Object Relationships (opens in a new tab)). سجلات كانت خاصة أمس تصبح مفتوحة اليوم، إلى أن يلاحظ أحد. اختر مبكرًا.
الملخصات التجميعية مفيدة، لكنها ليست مجانية
Section titled “الملخصات التجميعية مفيدة، لكنها ليست مجانية ”أحب الملخصات التجميعية. عُدّ البنود في توصيلة، واجمع مبالغ البنود في فاتورة، وجد أحدث تاريخ: مدمجة، بلا شيفرة. حقل رئيسي-تفصيلي يوضع على الابن، لكن الملخص التجميعي يوضع على الأب. ومع ذلك تأتي بشروط مكتوبة بخط صغير (Roll-Up Summary Field (opens in a new tab)):
- حساب قيم الملخص التجميعي بعد تغييرات معينة (حقل ملخص تجميعي جديد، أو تغيير في صيغة يعتمد عليها، أو إعادة حساب قسرية) قد يستغرق حتى 30 دقيقة، بحسب عدد السجلات المتأثرة. وقد رأيت أناسًا يتساءلون لماذا لم يتغير الرقم على الأب بعد.
- لا تستطيع تلخيص كل شيء. لا يمكن أن يكون Auto Number الحقل الذي تجمّعه. ولا يستطيع الملخص التجميعي تلخيص حقل صيغة إلا إذا كانت تلك الصيغة لا تمتد إلى كائن آخر ولا تستخدم دالة تتغير من تلقاء نفسها، مثل
NOW()أوTODAY(). صيغة «أيام التأخير» المبنية علىTODAY()تتغير كل ليلة دون أن يحفظ أحد سجلًا، لذا لا يوجد ما يُعيد الملخص التجميعي الحساب منه. هذا النوع من الأرقام يحتاج إلى تدفق مجدول، أو تقرير. - وللمرشح حدوده أيضًا: لا Text Area (Long)، ولا قائمة اختيار متعددة التحديد، ولا Description، ولا حقول النظام مثل Last Activity، ولا صيغ عابرة للكائنات، ولا حقول بحث.
- الملخصات التجميعية ليست على صفحات التعديل، لذا تستطيع قاعدة التحقق استخدام أحدها لكنها لا تستطيع عرض خطئها هناك.
ولا تعكس القرار. لا تقل: «نحتاج إلى ملخص تجميعي، إذن يجب أن تكون هذه رئيسي-تفصيلي». بل قل: «هذا الابن ينتمي حقًا إلى هذا الأب، والملكية ودورة الحياة تتوافقان، ومن الفوائد الملخصات التجميعية المدمجة». إذا لم تتوافق الدلالات، فحُلّ مسألة الحساب بطريقة أخرى. لا تشوّه نموذج البيانات من أجل الحصول على ميزة.
فما هي الطريقة الأخرى؟ تبني الملخص التجميعي بنفسك: حقل على الأب يحمل القيمة المحسوبة، وأتمتة تبقيه محدّثًا. لنقل إن شريك التجزئة علاقة بحث من التوصيلة، كما ينبغي، وإن العمل يريد Open Deliveries (التوصيلات المفتوحة) على الشريك. أضف حقلًا رقميًا، Open Deliveries، إلى الشريك. ثم تدفق يُطلقه السجل (record-triggered flow)، أو Apex trigger حين يتطلب الحجم أو المنطق شيفرة، يعيد حسابه كلما تغيرت توصيلة. وهو يعمل عبر علاقة بحث، ويستطيع التصفية على أي شيء، واستخدام التواريخ والصيغ التي لا يستطيعها الملخص التجميعي المدمج.
لكنه الآن مسؤوليتك أن تصيب فيه، وهنا تحديدًا تخطئ هذه الحلول. يجب أن تنطلق الأتمتة مع كل تغيير يهم: ابن جديد، وابن معدَّل، وابن محذوف، وابن مستعاد، وابن منقول إلى أب آخر، ما يعني إعادة حساب الأب القديم والجديد معًا. ويجب أن تتعامل مع تحميل بيانات من 200 سجل في المرة دون بلوغ الحدود. أعِد العدّ بدلًا من الجمع والطرح، حتى لا يترك حدث واحد فائت الرقم خاطئًا إلى الأبد. وخطّط لطريقة لإعادة حساب كل شيء، للتحميل الأول ولليوم الذي ينحرف فيه الرقم. وتذكّر أن كل حفظ لابن يحدّث الأب الآن، لذا فالأب ذو الآلاف من الأبناء يعيد مشكلة القفل التي سنراها بعد قليل. الملخص التجميعي المدمج يفعل كل ذلك لك؛ والمخصص قطعة برمجيات صغيرة تملكها أنت.
ثلاثة مستويات عمقًا: تكديس علاقات رئيسي-تفصيلي
Section titled “ثلاثة مستويات عمقًا: تكديس علاقات رئيسي-تفصيلي ”للمنصة شكل، ولعلاقة رئيسي-تفصيلي بُعدان منه. الأول هو العمق.
يمكنك تكديس علاقات رئيسي-تفصيلي حتى ثلاثة مستويات تفصيلية مخصصة عمقًا، وهذا هو القاع (Considerations for Object Relationships (opens in a new tab)). في الصف أرسمها كحساب له طلب (واحد)، والطلب ببنوده (اثنان)، والبنود بتفاصيلها (ثلاثة)، ثم أحاول إضافة رابع فلا تسمح لي Salesforce. وعلى Steve Trucking قد يبدو الأمر هكذا: التوصيلة (Delivery) هي الرئيسي؛ وبنود التوصيلة (Delivery Items) هي المستوى الأول؛ ومهام التركيب (Install Tasks) للبند هي الثاني؛ وخطوات المهمة (Task Steps) لكل مهمة هي الثالث. أما مستوى رابع، مثل ملاحظة الخطوة (Step Note)، فيجب أن يكون علاقة بحث.
بضع قواعد تأتي مع التكديس:
- لا يمكن أن تكون الكائنات القياسية على الطرف التفصيلي لكائن مخصص. يمكن أن يكون الكائن المخصص تفصيليًا للحساب؛ ولا يمكن أن يكون الحساب تفصيليًا لكائنك.
- لا يمكن أن يظهر الكائن إلا مرة واحدة في تكديس متعدد المستويات. لا تريدك Salesforce أن تلتف عائدًا إلى نفسك: لا يمكن للتفصيلي الفرعي أن يكون أيضًا رئيسيًا لرئيسيه.
- لا يستطيع الرئيسي تجميع المستوى الأسفل مباشرة. إذا أرادت التوصيلة عدد خطوات المهام، فإن مهمة التركيب تجمّع خطواتها، وبند التوصيلة يجمّع تلك الملخصات، والتوصيلة تجمّع البنود: مستوى واحدًا في كل مرة.
- الملكية والمشاركة تأتيان من القمة. كل مستوى يرث مالك الرئيسي ووصوله.
- حذف الرئيسي يحذف كل ما تحته، واستعادته تعيد كل شيء.
ثلاثة مستويات تكفي عادةً. إذا ظل تصميمك يريد مستوى رابعًا، فاسأل هل ينتمي كل مستوى حقًا إلى الذي فوقه مدى الحياة. وتذكّر أنك أنت من يختار أي رابط يكسر السلسلة. لا يلزم أن يكون المستوى الرابع هو علاقة البحث: ربما لا تنتمي مهمة التركيب حقًا إلى بند التوصيلة، فهي تُجدول وتُسند وحدها، فيصبح ذلك الرابط علاقة بحث، والآن تبدأ مهمة التركيب سلسلة جديدة تحتها خطوة المهمة وملاحظة الخطوة. اختر الرابط الذي يكون للابن فيه حياته الخاصة حقًا، واجعل ذلك الرابط علاقة البحث.
الآن لمهمة التركيب مالكها الخاص ومشاركتها الخاصة، ويمكن حذف توصيلة دون أن تأخذ معها مهام التركيب، ويمكن أن يكون تحت مهمة التركيب مستويان آخران. هذه هي المقايضة: السلسلة أقصر، وحياة مهمة التركيب ملك لها.
أبوان عرضًا: كائن الربط في Salesforce
Section titled “أبوان عرضًا: كائن الربط في Salesforce ”أولًا، كلمة عن الكلمات، لأن «كائن الربط (junction object)» يعني شيئين، وأنا أُدرّس الاثنين.
في الفصل 2 وجدنا كائن الربط المنطقي: ملتقى فكرتين أساسيتين يصبح شيئًا قائمًا بذاته، بسماته الخاصة. الكلب يعرف حيلًا كثيرة، والحيلة يعرفها كلاب كثيرة، وحيلة الكلب تقع بينهما وتحمل مستوى المهارة والتاريخ. هذا كائن ربط منطقي، في النموذج المنطقي، قبل وقت طويل من أن يقرر أحد علاقة بحث أو رئيسي-تفصيلي.
تستخدم Salesforce المصطلح بمعنى أضيق. عندما تقول Salesforce «junction object»، فهي تعني كائنًا مخصصًا بعلاقتي رئيسي-تفصيلي (Create a Many-to-Many Object Relationship (opens in a new tab)). سأسمي ذلك كائن الربط في Salesforce (Salesforce Junction Object). كل كائن ربط في Salesforce هو كائن ربط منطقي، لكن ليس كل كائن ربط منطقي يصبح كائن ربط في Salesforce: ابنِه بعلاقة رئيسي-تفصيلي وعلاقة بحث، أو بعلاقتي بحث، وسيظل كائن ربط منطقيًا، لكنه ليس من نوع Salesforce. (Salesforce نفسها ليست متسقة تمامًا: فمرجع الكائنات لديها يسمي بعض الكائنات القياسية المبنية على علاقات بحث «junction objects». وفي الاختبار، افترض التعريف الضيق.)
معلومة للاختبار. كائن الربط في Salesforce (Salesforce Junction Object) هو كائن مخصص بعلاقتي رئيسي-تفصيلي، وهذا ما تعنيه Salesforce حين تقول «junction object». أما كائن الربط المنطقي فهو فكرة النمذجة الأوسع: أي كائن يربط بين كائنين آخرين في علاقة متعدد إلى متعدد ويحمل سماته الخاصة، أيًا كانت طريقة بنائه.
البُعد الثاني هو العرض. هل يمكن أن يكون للابن أبوان في علاقة رئيسي-تفصيلي؟ نعم. ثلاثة؟ لا. كل كائن مخصص يمكن أن تكون له علاقتا رئيسي-تفصيلي كحد أقصى (Considerations for Object Relationships (opens in a new tab)). أبوان في علاقة رئيسي-تفصيلي هما طريقة بناء كائن الربط في Salesforce لعلاقة متعدد إلى متعدد. يلتقي الطاقم (Crew) والشاحنة (Truck) في تكليف الطاقم (Crew Assignment)، وكما وجدنا في الفصل 2، فهو ليس مجرد تمديدات: له تاريخ، ومسار، وربما حالة. الربط هو المكان الذي تصبح فيه العلاقة مفهوم عمل. ونصائح Salesforce لبناء واحد: أعطه اسمًا يقول ما هو، واجعل اسم سجله رقمًا تلقائيًا، وأعد تسمية القائمة المرتبطة لكل رئيسي باسم الرئيسي الآخر، بحيث تُظهر صفحة الطاقم «Trucks» وصفحة الشاحنة «Crews» (Create a Many-to-Many Object Relationship (opens in a new tab)).
وإليك الدقة. أحد الأبوين هو الأساسي (primary)، وهو الذي أنشأت حقل رئيسي-تفصيلي الخاص به أولًا. ولا توجد إشارة مرئية إلى أيهما هو، لذا فهو سؤال اختبار كلاسيكي، ومفاجأة كلاسيكية.
ما الذي يقرره الأساسي؟ ثلاثة أشياء (Create a Many-to-Many Object Relationship (opens in a new tab)):
- المظهر. صفحات كائن الربط تستخدم لون الرئيسي الأساسي وأيقونته.
- المالك. سجلات الربط ترث مالك سجل الرئيسي الأساسي. لا تراه أبدًا، لأن السجل التفصيلي ليس له حقل Owner؛ ولا يهم إلا إذا أزلت لاحقًا علاقتي رئيسي-تفصيلي كلتيهما.
- القسم (Division)، إذا كانت مؤسستك تستخدم الأقسام، بالطريقة نفسها.
والآخر هو الثانوي (secondary). ماذا يعني ذلك؟
- إنه التالي في الدور ليصبح أساسيًا. احذف حقل رئيسي-تفصيلي الأساسي أو حوّله إلى علاقة بحث، فيصبح الثانوي هو الأساسي.
- إنه يحدد نطاق التقارير. تعطيك Salesforce نوعين من التقارير: «Primary master with junction object and secondary master» و«Secondary master with junction object and primary master». والرئيسي المذكور أولًا يقرر السجلات التي يستطيع التقرير عرضها.
- إنه يُحتسب بالقدر نفسه في الوصول. إليك كيف أصوغها: الملكية من الأساسي، والوصول من كليهما، والأكثر تقييدًا يفوز. كائن الربط، مثل أي سجل تفصيلي، ليس له جدول مشاركة خاص به. تتحقق Salesforce من وصول المستخدم إلى كلا السجلين الرئيسيين، عبر Sharing Setting على كل حقل رئيسي-تفصيلي. إذا كان كلاهما مضبوطًا على Read/Write، فيحتاج المستخدم إلى Read/Write على الطاقم وعلى الشاحنة لتعديل تكليف الطاقم (Considerations for Object Relationships (opens in a new tab)).
- إنه يحذف بالقدر نفسه. احذف أيًا من الرئيسيين، الطاقم أو الشاحنة، فتذهب سجلات الربط الخاصة به إلى سلة المحذوفات (Recycle Bin). احذف كليهما فتذهب إلى غير رجعة.
بضع قواعد أخرى: يمكن أن يكون لكلا الرئيسيين ملخصات تجميعية من كائن الربط، ويمكن لصيغ كائن الربط وقواعد التحقق فيه أن تصل إلى حقول على كليهما. لكن كائن الربط لا يمكن أن يكون رئيسيًا لأي شيء آخر، لذا لا يمكن أن يقع في وسط تكديس، ولا يمكن أن يكون الرئيسيان الكائن نفسه؛ فعلاقة متعدد إلى متعدد من كائن إلى نفسه تحتاج إلى تصميم مختلف. وإذا كان لأب أكثر من 200 سجل ربط وكان كائن الربط يجمّع إلى الأب الآخر، فلن تسمح لك Salesforce بحذف ذلك الأب حتى تزيل منها ما يكفي.
إذن: أي الأبوين ينبغي أن يكون الأساسي؟ أنشئ أولًا الذي يملك المعنى. في تكليف الطاقم، الطاقم هو من يؤدي العمل، لذا سأُنشئ Crew أولًا. ثم دوّن ذلك، لأن لا شيء على الشاشة سيخبر الشخص التالي.
بعد قول كل ذلك، لا ينتهي بي الأمر بكائنات ربط كثيرة في Salesforce. عادةً يكون للكائن أب واحد في علاقة رئيسي-تفصيلي، ومن النوع نفسه من البيانات: بيانات عملاء تحت بيانات عملاء، ومعاملات تحت معاملات (تذكّر أنواع البيانات في الفصل 2: العملاء، والمعاملات، والمرجعية). وحين يكون أبوه الآخر من نوع مختلف، عادةً كائن مرجعي، تكون تلك العلاقة علاقة بحث. بند التوصيلة ينتمي إلى توصيلته: رئيسي-تفصيلي، وكلاهما معاملات. ويشير إلى المنتج الذي يحمله بعلاقة بحث، لأن المنتج بيانات مرجعية لها حياتها الخاصة، ولا أحد يريد أن يأخذ حذف منتج معه سنوات من تاريخ التوصيلات. ما زال بند التوصيلة كائن ربط منطقيًا بين توصيلة والمنتجات التي عليها؛ لكنه ليس كائن ربط في Salesforce.
العلاقات الذاتية: حين يعود الخط
Section titled “العلاقات الذاتية: حين يعود الخط ”يمكن لكائن أن يرتبط بنفسه: حساب أب، أو مدير، أو مركز توزيع يتبع مركزًا إقليميًا. تبني Salesforce اثنتين منها ستقابلهما في كل مؤسسة تقريبًا: من الحساب إلى الحساب، حقل Parent Account الذي يبني التسلسل الهرمي للحسابات، ومن الحالة إلى الحالة، أي Parent Case من الوحدة 2 الذي يجمع الحالات المترابطة. يجب أن تكون العلاقة الذاتية علاقة بحث، ولا يمكن لسجل أن يشير إلى نفسه، وإن كان يمكن لسجلين أن يشير كل منهما إلى الآخر (Considerations for Object Relationships (opens in a new tab)). وعلى كائن User هي نوع خاص بذاته، العلاقة الهرمية، وتُستخدم لأشياء مثل مدير المستخدم. الآليات سهلة؛ أما التسمية فمهمة. علاقة بحث من مركز التوزيع إلى مركز التوزيع اسمها Distribution_Center__c لا تساعد أحدًا. أب؟ احتياطي؟ فائض؟ سمِّ العلاقة باسم الدور، لا باسم الكائن الذي تشير إليه.
الهرمية: العلاقة الخاصة بكائن User
Section titled “الهرمية: العلاقة الخاصة بكائن User ”هذه صغيرة، وهي بالضبط من نوع الحقائق قليلة الشهرة والفريدة من نوعها التي أتوقع أن يستند إليها اختبار. الهرمية (Hierarchical) علاقة بحث خاصة لا توجد إلا على كائن User. تربط مستخدمًا بمستخدم آخر، ولا تسمح Salesforce للسلسلة بأن تلتف عائدة: لا يستطيع المستخدم أن يشير إلى نفسه، مباشرة أو بشكل غير مباشر (Object Relationships Overview (opens in a new tab)). إذا كان مدير Maria هو Dev، فلا يمكن أن يكون مدير Dev هو Maria، ولا أي شخص يتبع Maria في التسلسل.
هذا هو الفرق عن العلاقات الذاتية أعلاه. على الحساب أو الكائن المخصص، يمكن لسجلين أن يشير كل منهما إلى الآخر. أما على User، فيجب أن يبقى التسلسل الهرمي تسلسلًا هرميًا. وهي الطريقة الوحيدة لربط User بـ User: فعلاقة البحث العادية من User إلى نفسه غير متاحة.
لديك واحدة بالفعل. حقل Manager القياسي على User علاقة هرمية، وتستطيع الموافقات استخدامه: أرسل هذا الطلب إلى مدير مقدّمه. ويمكنك إنشاء علاقاتك الخاصة أيضًا، مثل Escalation Contact أو Backup Approver، ويمكن أن تمر الموافقة عبرها بالطريقة نفسها (ApprovalProcess, Metadata API (opens in a new tab)). لا تخلط بينها وبين التسلسل الهرمي للأدوار، الذي يقود الوصول إلى السجلات. الحقل الهرمي مجرد علاقة بين مستخدمين؛ ولا يشارك سجلًا واحدًا.
معلومة للاختبار. العلاقة الهرمية لا توجد إلا على كائن User، مثل حقل Manager القياسي، ولا يستطيع المستخدم أن يشير إلى نفسه، مباشرة أو بشكل غير مباشر. وهي ليست التسلسل الهرمي للأدوار.
للعلاقات حدود أيضًا
Section titled “للعلاقات حدود أيضًا ”يمكن أن يكون لكل كائن علاقتا رئيسي-تفصيلي كحد أقصى. حقول البحث وحقول رئيسي-تفصيلي معًا تُحتسب كحقول علاقات: 40 لكل كائن افتراضيًا، و50 كحد أقصى عند الطلب. وحقول الملخص التجميعي: 25 لكل كائن افتراضيًا، و40 كحد أقصى (Increase the Maximum Relationships Allowed per Object (opens in a new tab)؛ Increase the Maximum Limit of Roll-Up Summary Fields (opens in a new tab)). وتضيف Salesforce أن رفع أي من الحدين قد يؤثر في الأداء.
لا تحتاج إلى التصميم وفق تلك الأرقام؛ بل تحتاج إلى أن تلاحظ حين تقترب منها. كائن تتدلى منه علاقة بعد علاقة يخبرك بشيء. ربما هو مركزي حقًا إلى هذا الحد. أو ربما النموذج خاطئ. (وقاعدة هامش الأمان في الفصل 18 تنطبق: ابقَ دون الحد بفارق كبير، مقيسًا على السنة الثالثة.)
سؤال الـ 10,000 ابن
Section titled “سؤال الـ 10,000 ابن ”ثم هناك الأب ذو الأبناء الكثيرين جدًا. إرشادات Salesforce نفسها هي ألا تتجاوز نحو 10,000 سجل ابن لأب واحد في علاقة رئيسي-تفصيلي (Considerations for Object Relationships (opens in a new tab))، ودليلها للوصول إلى السجلات على نطاق واسع يقول الشيء نفسه عن علاقات الأب والابن عمومًا (Parent-Child Data Skew (opens in a new tab)). السجل رقم 10,001 لا يعطّل المؤسسة. لكن بعد تلك النقطة، قد يقفل حفظ ابن الأب، وتتموج تغييرات المشاركة على الأب عبر كل ابن.
لذا عندما أرى أبًا واحدًا، وأعدادًا هائلة من الأبناء، أسأل: لماذا هم جميعًا تحت الأب نفسه، ومن يملكهم، وكيف يُستعلم عنهم، وما الأتمتة التي تلمس الأب؟ كل توصيلة تحت حساب واحد اسمه «Steve Trucking» ستتجاوز 10,000 في أيام قليلة. علاقة بريئة من واحد إلى متعدد تصبح مشكلة data skew (انحراف البيانات). الوحدة التالية تعطي لمحة عن الانحراف، والجزء 2 يتعمق فيه.
لا تصمّم الخط وفق الميزة
Section titled “لا تصمّم الخط وفق الميزة ”هذه هي العادة التي أريدها من هذه الوحدة. لا تبدأ من «أحتاج إلى ملخص تجميعي»، أو «أحتاجه إلزاميًا»، أو «أريد مشاركة موروثة». هذه مؤشرات تنفيذ. ابدأ من العمل: هل للابن حياته الخاصة، ومن يملكه، وهل يمكن أن يوجد وحده، وهل يمكن أن ينتقل، وما الذي يحدث حين يذهب الأب، وهل تحمل العلاقة بيانات، وإلى أي حجم يمكن أن يصل كل طرف؟ ثم اختر العلاقة التي تنفّذ الإجابات.
ما بعد الاختبار: ما الذي يغيّره الذكاء الاصطناعي. يستطيع الذكاء الاصطناعي اقتراح العلاقات في ثوانٍ. لكنه لا يستطيع أن يخبرك هل سيحذف العمل الأب يومًا. والرسم الأسرع للمخططات لا يجعل التراجع عن علاقة خاطئة أرخص بمجرد أن تعتمد عليها ملايين السجلات وعشرات الأتمتات.
ما الذي يقرره المعماري هنا
Section titled “ما الذي يقرره المعماري هنا ”- هل للابن دورة حياته الخاصة أم ينتمي حقًا إلى الأب، وهل ينبغي أن تكون الملكية والوصول خاصين به أم موروثين.
- هل يمكن أن يوجد الابن دون أب، أو ينتقل بين الآباء، أو ينجو من حذف الأب.
- ما الذي تفعله كل علاقة بحث حين يُحذف أبوها: المسح، أو المنع، أو الحذف المتتالي.
- هل علاقة متعدد إلى متعدد مجرد تمديدات أم مفهوم عمل، وهل يصبح كائن الربط المنطقي كائن ربط في Salesforce، وأي الأبوين هو الأساسي، وما الذي يعنيه الأبوان كلاهما للوصول.
- هل يتوافق النموذج مع شكل المنصة: ثلاثة مستويات تفصيلية مخصصة عمقًا، وأبوان في علاقة رئيسي-تفصيلي عرضًا، وحدود العلاقات والملخصات التجميعية.
- هل العدد المتوقع للأبناء وتوزيعهم يُحدث خطر انحراف ينبغي أن يغيّر التصميم.
العلاقة مجموعة من الوعود حول كيفية تصرف قطعتين من البيانات معًا. اقطعها عن قصد.
للاستزادة
Section titled “للاستزادة ”- Salesforce Help، Considerations for Object Relationships (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-13).
- Salesforce Help، Object Relationships Overview (opens in a new tab) وCreate a Many-to-Many Object Relationship (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-13).
- Salesforce Help، Roll-Up Summary Field (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-13).
- Salesforce Developers، Metadata API، ApprovalProcess (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-13).
- Salesforce Help، Lookup Filters (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-13).
- Salesforce Help، Increase the Maximum Relationships Allowed per Object (opens in a new tab) وIncrease the Maximum Limit of Roll-Up Summary Fields (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-02).
- Salesforce Developers، Designing Record Access for Enterprise Scale، Parent-Child Data Skew (opens in a new tab)، (بالإنجليزية، تم التحقق في 2026-10-02).
