This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Saturday, 06 December 2025
البيانات الهرمية هي في كل مكان في تطوير البرمجيات: التعليقات الخيطة، الرسوم البيانية التنظيمية، أنظمة الملفات، فئات المنتجات، ومناقشات المنتدى. السؤال الأبدي عن "كيف أخزن شجرة في قاعدة بيانات علاقة؟" قد طارد المطورين منذ الأيام الأولى من SQL، وبصراحة، لا يزال لا يوجد جواب واحد يجعل الجميع سعداء. حول هذا الموضوع في عام 2004ولا تزال التحديات الأساسية كما هي اليوم.
وهنا تكمن المشكلة الأساسية: قواعد بيانات البيانات ذات العلاقة تفكر في مجموعات، لا في الأشجاركما شرح جو سيلكو في كتابه الممتاز جاري البحث في المجموعاتيعمل SQL على جداول كاملة وليس صفاً فردياً.
عند كتابةك لـ SSQQL ، محرك قاعدة البيانات يعمل على **إنها عبقرية في العمليات مثل "تجد جميع الطلبات على 100" أو "تنضم العملاء إلى مشترياتهم" - هذه هي عمليات المجموعة التي تتناسب بشكل طبيعي مع كيفية عمل الجداول. النتيجة هي دائماً مجموعة مسطحة من الصفوف.
غير أن التسلسل الهرمي هو في جوهره *(م)*لكي تجد كل ذرية العقدة، تحتاج إلى:
هذا تكراري traververal لا يرسم بشكل طبيعي لوضع العمليات. لا يمكنك التعبير عن "أعطني كل الأحفاد في أي عمق" في بيان واحد بسيط SQL بدون أي منهما:
كل نهج في هذه السلسلة يمثل مقايضة مختلفة بين تعقيد الكتابة، تعقيد القراءة، والتخزين، والعليا. ليس هناك غداء مجاني - أنت دائماً تقايض تكلفة واحدة مقابل أخرى. للمرجع النهائي لهذا الموضوع، انظر جو سيلكو. الأسطور و التدرجات في SQL لـالتي تغطي جميع هذه النُهُج بتعمق.
لجعل المقارنات ملموسة، سنستخدم التعليقات الخيطية كنموذج تسلسلي - شيء تستخدمه هذه المدونات نفسها. قد يبدو هذا الخيط التعليقي كما يلي:
flowchart TD
subgraph Post["Post: How to Deploy Docker Containers"]
C1["Comment 1: Great article!<br/>depth 0"]
C2["Comment 2: Thanks!<br/>depth 1"]
C3["Comment 3: Very helpful indeed<br/>depth 1"]
C4["Comment 4: Agreed!<br/>depth 2"]
C5["Comment 5: What about Kubernetes?<br/>depth 0"]
C6["Comment 6: That's covered in part 2<br/>depth 1"]
end
C1 --> C2
C1 --> C3
C3 --> C4
C5 --> C6
style Post stroke:#10b981,stroke-width:2px
style C1 stroke:#6366f1,stroke-width:2px
style C2 stroke:#8b5cf6,stroke-width:2px
style C3 stroke:#8b5cf6,stroke-width:2px
style C4 stroke:#a855f7,stroke-width:2px
style C5 stroke:#6366f1,stroke-width:2px
style C6 stroke:#8b5cf6,stroke-width:2px
ونحن بحاجة إلى دعم هذه العمليات:
ويغطي كل نهج بالتفصيل في المادة الخاصة به، وإليكم ملخص يساعدكم على الاختيار:
أبسط وأكثر نهج بديهي. كل صف يخزن إشارة إلى العقدة الأصلية. هو ما يصل إليه معظم المطورين لأول مرة لأنه يرسم بشكل طبيعي لكيفية تفكيرنا في التسلسل الهرمي.
كيف يعمل: كل تعليق لـه عـلـاقـة ParentCommentId لتعليقات الجذور NULL، والردود تشير إلى والديها.
أفضل من أجل: التسلسل الهرمي الضحل (أقل من 5-6 مستويات)، حركات شجرية متكررة، عندما تريد خصائص تصفح EF CORE للعمل بشكل طبيعي.
المقاصات: يتطلب الحصول على الأجداد أو أحفادهم عمليات تفاضلية متكررة أو استفسارات متعددة. بسيطة للكتابة، يمكن أن تكون بطيئة في قراءة الأشجار العميقة.
يقوم بتخزين و تخزين كل علاقة بين سلف و من سلالة في جدول منفصل. بدلاً من معرفة العلاقات في وقت الاستعلام، نقوم بتخزينها بشكل صريح مع عمقها.
كيف يعمل: ألف - مستقلة CommentClosure ويمكن أن يتضمن التعليق 4 تحت التعليق 1 عبر التعليق 3 مدخلات: (1,4,2,3,4,1,4,1,4,4,4,0).
أفضل من أجل: تطبيقات قراء الثقيلة، عندما تحتاج إلى الإستفسار في الأعماق التعسفية، عندما نادراً ما تحرك الأشجار الفرعية.
المقاصات: أما المداخل الأكثر تعقيداً (يضاف إليها أيضاً قيود الإغلاق)، فالتخزين ينمو بتعمق، وتتطلّب شقق فرعية متحركة إغلاقات جديدة.
يقوم بتخزين كامل السلالة كسلسلة نصية محددة. اعتبرها تخزيناً للعنوان البريدي الكامل بدلاً من مجرد اسم الشارع.
كيف يعمل: لكل تعليق على Path مثل عمود "1/3/7" بمعنى "الروت هو 1، الوالد هو 3، هذا هو 7". يمكن تقسيم الأسلاف من الخيط؛ يمكن العثور على الأحفاد مع استفسارات مماثلة.
أفضل من أجل: جيل فتات الخبز، عندما يُسأل الأجداد أكثر من مجرد ذرية، عندما تريد مسارات قابلة للقراءة من البشر من أجل التصحيح.
المقاصات: مثل الإستفسارات يمكن أن تكون بطيئة بدون الفهارس الصحيحة، المسار الأوتار لها حدود طولية، تحريك الأشجار الفرعية يتطلب تحديث جميع مسارات السلال.
يعيّن كل نُقطة يسار و يمين أرقام من a عمق الأوّل. كلّ ذرّات له قيم. - - - - - - حدود الأباء
كيف يعمل: كان لكل تعليق على ما يلي: Left وقد عقد مؤتمراً بشأن Right تحتوي العقدة التي تحمل L=4، R=7 على جميع العقد التي يوجد فيها 4 < يساراً و يميناً > 7.
أفضل من أجل: كفئة الأشجار. ممتاز لـ "احصل على كامل شجرة تحتية في ترتيب العرض" إستفسارات.
المقاصات: الإضافات تحتاج إلى تحديث العديد من الصفوف (حوّل كل القيم إلى غرفة)، الشجر الفرعي المتحرك معقد. غير مناسب للكتابات المتكررة.
postgreSQL يعمل
كيف يعمل: ثالثاً - ltree مع مسارات مثل "1-3-7". الفهارس التي تتيح كفاءة الاسلاف/استفسارات من الخلف باستخدام مشغلين مثل: @> وقد عقد مؤتمراً بشأن <@.
أفضل من أجل: موقعSQL فقط نشرات حيث الأداء مهم، عندما تحتاج إلى نمط مطابقة الإستفسارات، عندما تريد أفضل المسارات المادية.
المقاصات: PostgreSQL فقط، يضيف الاعتماد على توسيع قاعدة البيانات. ملاحظة: نبغgsql يجري دعم دعم linQ عـن شـرـر شـر LTree على الرغم من أن الـ CTEs لا تزال تتطلب الخام SQL.
يُدرج ما يلي: (أ) (أ) (أ) (أ) (أ) (أ) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (أ) (ب) (ب) (ب) (ب) (ب) (ب) (أ) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (أ) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (أ) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب) (ب)
|----------|--------|---------------|-----------------|--------------|---------|-----------------|
| **** O (1) O(n) مع CTE o o O (d) مع CTE o O (1)
| المُنْفَفَفَفَف o O(n x d) o O (1) O (1) o O (s x d) o O (n x d) o جيد
| مُثثثثثثثث سين )١( سين )١(* o O (1) o O (Os) o O (d) لكل عقد من العقد o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o o
| مُنت مُز تنفيذ o O(n) o O (1) O (1) o O (n) o الحد الأدنى o جيد o جيد o
| لا تُغرِّر O (1) O (1) أو O (1) أو O (1) أو O (Os) o O (d) في العقد الواحد من العقد LTree )( / / / /
ن = مجموع العقدات، د = العمق، س = الحجم الفرعي *مع الرقم القياسي الصحيح
flowchart TD
Start([Start]) --> Q1{Shallow tree?<br/>< 5 levels}
Q1 -->|Yes| Q2{Need EF Core<br/>navigation properties?}
Q2 -->|Yes| AL[Adjacency List]
Q2 -->|No| Q3{Performance<br/>critical?}
Q3 -->|No| AL
Q3 -->|Yes| MP[Materialised Path]
Q1 -->|No| Q4{Read-heavy?}
Q4 -->|Yes| Q5{Writes rare?}
Q5 -->|Yes| NS[Nested Sets]
Q5 -->|No| CT[Closure Table]
Q4 -->|No| Q6{PostgreSQL only?}
Q6 -->|Yes| LT[ltree]
Q6 -->|No| Q7{Need breadcrumbs?}
Q7 -->|Yes| MP
Q7 -->|No| CT
style Start stroke:#10b981,stroke-width:2px
style AL stroke:#6366f1,stroke-width:2px
style MP stroke:#8b5cf6,stroke-width:2px
style NS stroke:#ec4899,stroke-width:2px
style CT stroke:#f59e0b,stroke-width:2px
style LT stroke:#14b8a6,stroke-width:2px
هذه المدوّنة تستخدم المُنْفَفَفَفَف الأساس المنطقي:
انظر S انظر الجزء الثاني: جدول النتائج (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة) و (بآلاف دولارات الولايات المتحدة)
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.