You are on page 1of 15

‫‪1800‬‬

‫نظري‬

‫‪00‬‬ ‫‪Types of indexes‬‬


‫‪6‬‬

‫‪15‬‬ ‫د‪ .‬روان قرعوني‬

‫‪ ‬في هذه المحاضرة سنكمل حديثنا عن الفهارس حيث أننا سنتعرف على الفهرس‬
‫الكثيف ‪ Dense index‬والفهرس االجوف ‪ sparse index‬والفهارس متعددة‬
‫المستويات ‪ multi-level‬والفهارس من نوع ‪ Bitmap‬وفهارس التقطيع ‪hash index‬‬
‫كما أننا سنتحدث عن ‪ B-tree‬و‪B+ tree‬‬

‫‪ ‬الهدف من هذه المحاضرة هو ان نفهم كيف يفكر ‪ DBMS‬وماهي الطريقة التي‬


‫يتم فيها بناء الفهارس لتوفير الوقت‪.‬‬

‫الفهرس الكثيف ‪Dense index‬‬


‫سنأخذ مثال بسيط للتوضيح ننطلق منه بفكر الفهارس‪:‬‬
‫مثال‪:‬‬
‫لنفترض أنه لديك جدول يعبر عن الموظفين يحوي ‪ eid‬حجمه ] ‪ [ 4 byte‬و ‪ cid‬حجمه ]‪ [4 byte‬و ‪ name‬حجمه‬
‫] ‪ [60 byte‬و ‪ address‬حجمه ] ‪ [ 60 byte‬وهو مؤلف من ‪ 100‬موظف )‪ (record‬ولنفرض أن حجم ال ‪ Block‬هو‬
‫‪512 byte‬‬
‫‪-‬ماهو عدد التسجيالت في ال ‪Block‬؟‬

‫𝐤𝐜𝐨𝐥𝐁 𝐞𝐡𝐭 𝐟𝐨 𝐞𝐳𝐢𝐬 𝐞𝐡𝐭‬


‫= 𝐤𝐜𝐨𝐥𝐁 𝐧𝐢 𝐬𝐝𝐫𝐨𝐜𝐞𝐫 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬
‫𝐝𝐫𝐨𝐜𝐞𝐫 𝐟𝐨 𝐞𝐳𝐢𝐬 𝐞𝐡𝐭‬

‫‪Record size= 4 + 4 + 60 + 60 = 128 byte‬‬


‫>= ‪Block size = 512 byte‬‬
‫𝟐𝟏𝟓‬
‫= 𝐤𝐜𝐨𝐥𝐁 𝐧𝐢 𝐬𝐝𝐫𝐨𝐜𝐞𝐫 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬ ‫𝐬𝐝𝐫𝐨𝐜𝐞𝐫 𝟒 =‬
‫𝟖𝟐𝟏‬

‫أي أن الـ ‪ Block‬الواحد يحوي على أربعة موظفين‪.‬‬

‫‪1‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪ -‬ماهو عدد الـ ‪ Block‬؟!‬


‫𝐬𝐝𝐫𝐨𝐜𝐞𝐫 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬
‫= 𝐤𝐜𝐨𝐥𝐁 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬
‫𝐤𝐜𝐨𝐥𝐁 𝐧𝐢 𝐬𝐝𝐫𝐨𝐜𝐞𝐫 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬

‫𝟎𝟎𝟏‬
‫= 𝐤𝐜𝐨𝐥𝐁 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬ ‫𝟓𝟐 =‬
‫𝟒‬

‫أي ان الجدول هو عبارة عن ‪Block 25‬‬


‫‪4‬‬ ‫‪4‬‬ ‫‪60‬‬ ‫‪60‬‬
‫‪eid‬‬ ‫‪cid‬‬ ‫‪name‬‬ ‫‪address‬‬
‫‪1‬‬ ‫‪7‬‬ ‫‪Ahmad‬‬ ‫‪............‬‬ ‫‪record‬‬
‫‪2‬‬ ‫‪3‬‬ ‫‪128Byte‬‬
‫‪Block 1‬‬
‫‪3‬‬ ‫‪2‬‬
‫‪4‬‬ ‫‪5‬‬
‫‪5‬‬ ‫‪3‬‬
‫‪6‬‬ ‫‪2‬‬
‫‪Block 2‬‬
‫‪7‬‬ ‫‪7‬‬
‫‪8‬‬ ‫‪2‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪97‬‬
‫‪98‬‬
‫‪Block 25‬‬ ‫‪99‬‬
‫‪100‬‬

‫نريد البحث عن موظف ما (دون فهارس) ‪ ,‬فأسوأ األحوال نحتاج الى ‪ 25Block‬من أجل ايجاد موظف ما‪.‬‬ ‫▪‬
‫لنفترض انه قمت ببناء فهرس على ‪ id‬مثال‪ ,‬وحقل الفهرس مؤلف من ‪ eid‬حجمه ] ‪ [4 byte‬و ‪ pointer‬حجمه ‪[ 12‬‬
‫] ‪byte‬‬
‫𝟐𝟏𝟓‬
‫= 𝐤𝐜𝐨𝐥𝐛 𝐧𝐢 𝐲𝐫𝐭𝐧𝐞 𝐱𝐞𝐝𝐧𝐢 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬ ‫𝒚𝒓𝒕𝒏𝒆 𝟐𝟑 =‬
‫𝟔𝟏‬
‫𝟎𝟎𝟏‬
‫= 𝐤𝐜𝐨𝐥𝐛 𝐟𝐨 𝐫𝐞𝐛𝐦𝐮𝐍‬ ‫𝒌𝒄𝒐𝒍𝒃 𝟒 =‬
‫𝟐𝟑‬
‫أي ان جدول الفهرس يحوي على ‪ 4 block‬وكل ‪ block‬يحوي على ‪.32 entry‬‬

‫‪2‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫بأسوء األحوال‪ :‬نحتاج لـ ‪ 5 block‬ألن الفهرس عبارة عن ‪ 4 block‬أي أنني سأحتاج للبحث ضمن هذه الـ ‪ 4‬باإلضافة‬
‫إلى الـ ‪ Block‬ضمن الجدول األساسي‪.‬‬

‫مالحظة‪ :‬عند اجراء تعديل على الجدول األساسي نقوم بالتعديل أيضا على الفهرس الذي قمنا‬
‫ببنائه‬

‫‪eid‬‬ ‫‪cid‬‬ ‫‪name‬‬ ‫‪address‬‬ ‫‪eid‬‬ ‫‪pointer‬‬


‫‪1‬‬ ‫‪1‬‬
‫‪1‬‬ ‫‪7‬‬
‫‪2‬‬ ‫‪1‬‬
‫‪2‬‬ ‫‪3‬‬ ‫‪3‬‬ ‫‪1‬‬
‫‪4‬‬ ‫‪1‬‬ ‫‪Block 1‬‬
‫‪Block 1‬‬ ‫‪3‬‬ ‫‪2‬‬
‫‪5‬‬ ‫‪2‬‬
‫‪4‬‬ ‫‪5‬‬ ‫‪.‬‬
‫‪.‬‬
‫‪5‬‬ ‫‪3‬‬
‫‪.‬‬
‫‪6‬‬ ‫‪2‬‬ ‫‪32‬‬
‫‪Block 2‬‬ ‫‪33‬‬
‫‪7‬‬ ‫‪7‬‬
‫‪.‬‬
‫‪8‬‬ ‫‪2‬‬ ‫‪.‬‬ ‫‪Block 2‬‬
‫‪.‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪64‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪65‬‬
‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬ ‫‪.‬‬
‫‪97‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪Block 3‬‬
‫‪Block 25‬‬ ‫‪98‬‬ ‫‪.‬‬
‫‪96‬‬
‫‪99‬‬ ‫‪97‬‬

‫‪100‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪Block 4‬‬
‫‪.‬‬
‫‪100‬‬

‫الحظ أن كل رقم له مقابل بالفهرس أي أن كل ‪ entry‬له ‪ Key‬وهذا سبب تسمية الفهرس بالفهرس الكثيف‪.‬‬

‫‪3‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫الفهرس األجوف ‪Sparse index‬‬


‫بالعودة إلى مثالنا السابق فرضا زاد عدد الـ ‪ records‬إلى ‪ 1000‬وبالتالي سيكون عدد ‪ block‬في الفهرس هو‬
‫𝟎𝟎𝟏‬
‫‪512/16=32‬‬ ‫𝟐𝟑 ≃ 𝟓𝟐 ‪= 𝟑𝟏,‬‬
‫𝟐𝟑‬
‫وهنا عدنا لفكرة أننا سنضطر لعمليات قراءة كثيرة‪ ,‬وفي هذه الحالة عندما يرى ‪ DBMS‬أن القراءة من الفهرس أصبحت‬
‫مكلفة يقوم ببناء فهرس على الفهرس‬

‫مالحظة‪:‬‬
‫‪ Sparse index -‬من الممكن أن يبنى على الجدول مباشرةً او يبنى على فهرس‬
‫‪ -‬الكلفة األساسية هي كلفة القراءة من الهارد (عدد الـ ‪ block‬الذي نجلبه من الهارد )‬
‫‪ -‬ما نتعلمه في هذه المحاضرة ليس الذي نقوم ببناءه بإيدينا ( ‪ create index‬بانواعه ‪DBMS , )...‬‬
‫يحدد بنية الفهرس بناءً على الـ ‪ Data‬الموجودة لديه وعدد عمليات اإلدخال حيث انه يملك‬
‫خوارزميات خاصةً يحدد من خاللها بنية الفهرس بحيث يسرع العمل بالفهرس الذي تبنيه مثال قمت‬
‫ببناء فهرس على ‪ id‬في هذه الحالة هو يختار البنية المناسبة ليسرع العمل‪.‬‬
‫أي عندما يرى مثأل أن كلفة القراءة من ‪ Dense index‬أصبحت مكلفةً مثلها مثل القراءة من‬
‫الجدول من الممكن أن يقوم ببناء ‪ sparse index‬ولكن لماذا اليقوم ببناء ‪ sparse index‬مباشرةً ؟‬
‫ألن ذلك سوف يكلف حجوم تخرين إضافية(كل فهرس له حجم تخرين) وبالتالي تكلفة إضافية‪.‬‬
‫‪ -‬الفرق بين الفهرس األجوف وبين الفهرس الكثيف هو أن الفهرس الكثيف ال ‪ Keys‬الخاصة به‬
‫مرتبة‪.‬‬

‫‪4‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪4‬‬ ‫‪12‬‬ ‫‪4‬‬ ‫‪12‬‬


‫‪eid‬‬ ‫‪pointer‬‬ ‫‪eid‬‬ ‫‪pointer‬‬
‫‪1‬‬
‫‪1‬‬ ‫‪1‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪Block 1‬‬
‫‪33‬‬ ‫‪2‬‬ ‫‪.‬‬
‫‪32‬‬
‫‪65‬‬ ‫‪3‬‬
‫‪33‬‬
‫‪Block 1‬‬ ‫‪.‬‬
‫‪97‬‬ ‫‪4‬‬
‫‪.‬‬ ‫‪Block 2‬‬
‫‪.‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪64‬‬
‫‪.‬‬ ‫‪65‬‬
‫‪993‬‬ ‫‪32‬‬ ‫‪.‬‬
‫‪.‬‬ ‫‪Block 3‬‬
‫‪.‬‬
‫فهرس ‪2‬‬
‫‪96‬‬
‫‪.‬‬
‫‪.‬‬
‫‪.‬‬
‫‪993‬‬
‫‪.‬‬
‫‪.‬‬ ‫‪Block 32‬‬
‫‪.‬‬
‫‪1000‬‬

‫فهرس ‪1‬‬

‫الحظ أن كل ‪ entry‬من الفهرس التاني يؤشر على مجموعة ‪ entry‬من الفهرس األول( كل ‪ pointer‬من الفهرس‬
‫الثاني يؤشر على ‪ Block‬من الفهرس األول )‬
‫‪-‬بالفهرس ‪ 2‬يوجد لدينا ‪ entry 32‬ألن لدي ‪ block 32‬بالفهرس ‪( 1‬كل ‪ entry‬يؤشر على ‪ )Block‬وبالتالي عدد‬
‫𝟐𝟑‬
‫‪ block‬بالفهرس ‪ 2‬هي 𝟏 =‬
‫𝟐𝟑‬

‫وبالتالي كلفة البحث عن موظف ما هي بأسوء األحوال ‪( 3 block‬يجيب الـ ‪ block‬من الفهرس ‪ 2‬ومنه نحصل على الـ‬
‫‪ block‬من الفهرس ‪ 1‬وبعدها نحصل على الـ ‪ block‬من الجدول األساسي)‪.‬‬

‫‪5‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫الفهرس متعدد المستويات ‪Multilevel index‬‬


‫في ح ال لم نستطيع نقل الفهرس الرئيسي بشكل كامل إلى الذاكرة الرئيسية تصبح عملية الوصول إلى المعلومة تحتاج‬
‫إلى عمليات وصول على مستويين (عملية مكلفة)‬
‫ولتقليص عدد الوصول الكلي إلى القرص الذي نحتاجه للوصول إلى التسجيلة المعنية في الفهرس يتم تشكيل فهرس‬
‫أجوف للفهرس الرئيسي المخزن كملف تسلسلي على القرص‪ ,‬ويصبح لدينا نوعين من الفهارس‪:‬‬
‫‪ .1‬فهرس خارجي ‪ : outer-index‬وهو عبارة عن فهرس أجوف للفهرس الرئيسي‬
‫‪ .2‬فهرس داخلي ‪ : inner-index‬ملف الفهرس الرئيسي‬
‫وفي حال بقي الفهرس الخارجي كبيراً لنقله في الذاكرة الرئيسية نقوم بتوليد مستوى ثاني من الفهرس وهكذا‪ ,‬ومنه‬
‫أصبح لدينا مستويات متعددة من الفهارس تشبه البنية الشجرية‬

‫‪index block 0‬‬ ‫‪data block 0‬‬

‫‪data block 1‬‬

‫‪outer index‬‬ ‫‪index block 1‬‬

‫‪inner index‬‬

‫ومن محاسن استخدام هذا النوع من الفهارس هي أن عملية إعادة تنظيم الفهرس تجري بشكل الي عند القيام بعمليات‬
‫اإلضافة والحذف وتتطلب هذه العملية تغييرات بسيطة ومحلية وال داعي إلعادة تنظيم الملف‪.‬‬
‫بما أن البنية في هذه الفهارس هي بنية شجرية سوف نتحدث عن ‪ B-tree‬و ‪ B+ - Tree‬ولنفهمها بشكل أفضل سنبدأ‬
‫بالحديث عن ‪M-May search tree‬‬

‫‪6‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪M-May search tree‬‬


‫‪ M‬تسمي درجة الشجرة‪ ,‬كل عقدة تحوي قيم )‪ KEY (M-1‬وأشجار فرعية ‪ (children) M‬ولكن ليس بالضرورة (كل‬
‫‪ M-1‬قيمة ‪ ,‬كما أن عدد األشجار الفرعية )‪ (children‬يتراوح‬ ‫عقدة بالشجرة الفرعية من الممكن ان تحوي من ‪1‬‬
‫من ‪( 0‬لألوراق ) إلى (‪ + 1‬عدد القيم في العقدة ))‬
‫أي ليس هناك قواعد تجبرك على عمل عقدة جديدة بإمكانك تكبير أو تصغير العمق الذي تريده على عكس ‪Btree‬و ‪B+‬‬
‫‪ - Tree‬سيكون هناك تقييد‬
‫‪ -‬المفاتيح في العقدة الواحدة مرتبة ‪.‬‬
‫‪ -‬اذا كان للعقدة ‪ K‬مفتاح فإما أن يكون لها ‪ K+1‬ابن أو ليس لها أبناء (ورقة)‪.‬‬
‫مثال ‪:2-way tree‬‬
‫‪Key1‬‬ ‫▪‬
‫‪children2‬‬ ‫▪‬
‫مالحظة‪ :‬ال ننسى فكرة الترتيب في هذا النوع من األشجار‬

‫‪3‬‬

‫‪6‬‬ ‫‪20‬‬

‫‪0‬‬
‫‪0‬‬
‫‪4‬‬ ‫‪9‬‬ ‫‪15‬‬ ‫‪30‬‬

‫مثال ‪:3-way tree‬‬

‫‪Key2‬‬ ‫▪‬
‫‪Children3‬‬ ‫▪‬

‫‪7‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪.1‬‬
‫‪10 20‬‬

‫‪5‬‬ ‫‪7‬‬ ‫‪11‬‬ ‫‪15‬‬ ‫‪22 25‬‬

‫‪10 44‬‬ ‫‪.2‬‬

‫‪3 7‬‬ ‫‪22‬‬ ‫‪55 70‬‬

‫‪50‬‬ ‫‪66 68‬‬

‫نالحظ أنه ليس هناك تقييد‪ ,‬بعض العقد تحوي على مفتاح واحد فقط وبعضها لها ‪ 2‬ابن ‪....,‬‬
‫كما رأينا سابقا للفهرس ‪ key‬و‪ pointer‬على الجدول فإذا أردنا عكس هذا المفهوم على الشجرة كيف سيصبح شكل‬
‫الورقة؟!‬

‫‪10 20‬‬

‫‪5 7‬‬ ‫‪11 15‬‬ ‫‪22 25‬‬

‫سيكون شكل الورقة‪:‬‬


‫‪CP1‬‬ ‫‪K1‬‬ ‫‪K1p‬‬ ‫‪CP2‬‬ ‫‪K2‬‬ ‫‪K2p‬‬ ‫‪CP3‬‬

‫حيث أن ‪ k1‬و‪ k2‬هي المفاتيح ( في مثالنا بالنسبة للعقدة الجذر ‪ ) K2=20 , k1=10‬و ‪ cp3,cp2,cp1‬هي مؤشرات لألبناء‬
‫و ‪ cp3‬هو مؤشر على‬ ‫‪11 15‬‬ ‫و ‪ cp2‬هو مؤشر على العقدة‬ ‫‪5 7‬‬ ‫)في مثالنا ‪ cp1‬هو مؤشر على العقدة‬
‫(‬ ‫‪22 25‬‬ ‫العقدة‬

‫‪8‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫و ‪ k1p‬و ‪ k2p‬هي مؤشرات على الجدول مباشرةً‪.‬‬


‫للتوضيح‪:‬‬
‫‪ 10‬تمثل ‪ id‬لموظف ما )‪ (key‬ولكن كيف سنصل لهذا الموظف؟!‬
‫يجب ان يكون مع كل ‪ key‬ب ‪ pointer‬وهو ‪ Kp‬يؤشر على ‪ record‬خاص بالجدول يمثل الموظف الذي ‪ id‬هو ‪.10‬‬

‫‪B-tree‬‬
‫هي ‪ M-Way search tree‬ولكن مع بعض القيود وهي‪:‬‬
‫‪ .1‬األوراق ‪ leaf Node‬يجيب ان تكون في مستوى واحد‬
‫‪ .2‬كل عقدة ‪ Node‬تحوي على األقل ‪ M/2 – 1‬مفتاح وعلى األكثر ‪ M-1‬باستثناء الجذر ليس له حد أدنى من‬
‫‪ M-1‬مفتاح‪.‬‬ ‫الممكن أن يحوي من ‪1‬‬
‫‪ .3‬نبدأ بخلق األبناء من األدنى الى األعلى‬

‫واالن دعونا نأخذ مثال لنفهم كيف ‪ DBMS‬يقوم ببناء ‪ B-tree‬لفهرس معين عن طريق ادخاالت‪:‬‬
‫(يبدأ الجدول بفهرس مبتدئ وبعدها يكبر الجدول وتتغير بنية الفهرس)‬
‫أول ما انشأ الجدول بعمل ‪ create index‬وبعدها يكبر الفهرس او يصغر حسب اإلدخاالت أو الحذف‬
‫يكبر الفهرس‬ ‫إضافة ‪record‬‬
‫يصغر الجدول ويصغر الفهرس‬ ‫حذف ‪record‬‬
‫مايهمنا هو فهم البنية العامة للـ ‪ B- tree‬والتهمنا اإلضافة والحذف‬

‫فرضا أدخلنا إلى الجدول ‪10‬و ‪ 20‬و ‪(3 record) 30‬‬ ‫▪‬
‫نذكر بأن حالة ‪: 4-Way‬‬ ‫لتبنى أول ورقة من الفهرس (سنأخذ حالة ‪: ) 4-way‬‬

‫‪3Keys , 4children‬‬ ‫‪10‬‬ ‫‪20‬‬ ‫‪30‬‬

‫‪-‬في حال ادخلنا ‪ 40‬في هذه الحالة اليمكن إضافتها للورقة ألن اقصى حد هو ‪ 3‬عندما نرفع اخر عنصر‬

‫‪30‬‬

‫‪10‬‬ ‫‪20‬‬ ‫‪40‬‬

‫‪9‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪-‬في حال ادخلنا ‪ 60‬و ‪ 70‬يصبح الشكل ‪:‬‬

‫‪30‬‬

‫‪10‬‬ ‫‪20‬‬ ‫‪40 60 70‬‬

‫‪ -‬في حال ادخلنا ‪ 80‬عندها ترتفع ‪ 70‬وتأشر على ‪ 80‬يصبح الشكل‪:‬‬

‫‪30‬‬ ‫‪70‬‬

‫‪10‬‬ ‫‪20‬‬ ‫‪40‬‬ ‫‪60‬‬ ‫‪80‬‬

‫‪-‬في حال ادخلنا ‪ 25‬يصبح الشكل‪:‬‬


‫‪30‬‬ ‫‪70‬‬

‫‪10 20 25‬‬ ‫‪40‬‬ ‫‪60‬‬ ‫‪80‬‬

‫ولكن كونه غير مسموح فقط لـ ‪3‬‬ ‫‪5‬‬ ‫‪10‬‬ ‫‪20‬‬ ‫‪25‬‬ ‫‪-‬في حال ادخلنا ‪( 5‬سوف تأتي قبل ‪ 10‬أي تصبح‬
‫عندها ترتفع ‪ 20‬والسهم األول يؤشر على ماقبلها والسهم الثاني يؤشر على مابعدها (‪ )25‬ويصبح الشكل‪:‬‬

‫‪20 30 70‬‬

‫‪5‬‬ ‫‪10‬‬ ‫‪25‬‬ ‫‪40‬‬ ‫‪60‬‬ ‫‪80‬‬

‫‪10‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪-‬في حال ادخلنا ‪ 15‬يصبح الشكل‪:‬‬

‫‪20 30 70‬‬

‫‪5 10‬‬ ‫‪15‬‬ ‫‪25‬‬ ‫‪40‬‬ ‫‪60‬‬ ‫‪80‬‬

‫ولكن كونه غير مسموح يجب ان‬ ‫‪5‬‬ ‫‪10‬‬ ‫‪15‬‬ ‫‪18‬‬ ‫‪-‬في حال ادخلنا ‪( 18‬سوف تأتي بعد ‪ 15‬أي تصبح‬
‫وهذا غير مسموح لذلك نذهب لألعلى بمستوى جديد‬ ‫‪15‬‬ ‫‪20‬‬ ‫‪30‬‬ ‫‪70‬‬ ‫ترتفع ‪ 15‬ولكن اصبح لدينا‬
‫ماقبلها‬ ‫‪15‬‬ ‫‪20‬‬ ‫بحيث ترتفع ‪ 30‬و السهم األول يؤشر على‬
‫‪70‬‬ ‫والسهم الثاني يؤشر على مابعدها‬

‫وهكذا يصبح شكل الشجرة‪:‬‬


‫‪30‬‬

‫‪15‬‬ ‫‪20‬‬ ‫‪70‬‬

‫‪5 10‬‬ ‫‪18‬‬ ‫‪25‬‬ ‫‪40‬‬ ‫‪60‬‬ ‫‪80‬‬

‫الحظ يوجد مؤشر لكل عقدة على ‪ record‬الخاص بها‬

‫نكرر‪ :‬المبدأ الذي يهمنا هو أن الفهرس تشكل باألول وبعدها يكبر وتكبر ‪ B-tree‬وذلك عندما تزداد ال ‪Data‬‬

‫إلى االن أخذنا آليتين للفهارس وهي فهارس ‪ 1 level‬و فهارس ‪ Multilevel‬ولكن متى نلجأ لهما‬
‫؟!‬
‫كالهما مفيد ولكن لكل واحد حالة معينة‪ ,‬فمثال إذا كان حجم الجدول قليل يكون فهرس ‪ 1 level‬مقبول ولكن عندما‬
‫تزداد ‪ records‬يصبح إعادة تنظيم للملف أكثر )كل عملية إضافة ‪ /‬حذف ‪ /‬تعديل تؤدي إلى إعادة بناء الفهرس من األول‬
‫ليزداد فعاليته(‬

‫‪11‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫بينما بال ‪ Multilevel‬على الرغم من أن حجم التخزين أكبر ولكن عند اإلضافة ‪ /‬الحذف تحدث بأماكن محددة وبالتالي‬
‫اليتم إعادة البناء للفهرس ألنه أساساً يبنى صغير ثم يكبر وبالتالي ‪:‬‬
‫من مساوئ فهارس ‪1 level‬‬
‫‪ -‬يتناقص األداء كلما كبر الملف حيث يؤدي ذلك إلى ربط عدد من الكتل اإلضافية ‪overflow block‬‬
‫‪ -‬إعادة تنظيم للملف بأكمله بشكل دوري‪.‬‬

‫ومن مساوئ الفهارس متعدد المستويات‬


‫‪ -‬حجم تخزين إضافي‬

‫‪B+-tree‬‬
‫هي نفسها ‪ B-tree‬ولكن المؤشرات ليست بكل عقدة وإنما باألوراق فقط (الـ ‪ key‬سوف يتكرر حتى يصل إلى األوراق)‬
‫بنفس مثالنا السابق نعدل عليه لصبح ‪B+-tree‬‬
‫‪30‬‬

‫‪15 20‬‬
‫‪30 70‬‬

‫‪5 10‬‬ ‫‪15 18‬‬ ‫‪20 25‬‬ ‫‪30‬‬ ‫‪40 60‬‬ ‫‪70 80‬‬

‫من إيجابيات ‪ : B-tree‬في بعض األحيان نصل إلى المفتاح الذي نبحث عنه قبل الوصول إلى األوراق‬
‫ولكن التعتبر إيجابية قوية ألن هذه العناصر عددها قليل جداً مقارنة باألوراق‪.‬‬
‫ومن مساوئ ‪ B-tree‬التي حلتها ‪ B+-tree‬هو أن العقد غير األوراق تحتاح إلى مكان تخزين أكبر وبالتالي عدد العناصر في‬
‫العقدة أقل وبالتالي عمق الشجرة ‪ B-tree‬اكبر منه بـ ‪B+-tree‬‬

‫البنية العامة للعقد في ‪ B+-tree‬هي‪:‬‬

‫‪P1‬‬ ‫‪K1‬‬ ‫………………… ‪P2‬‬ ‫‪Pn-1‬‬ ‫‪Kn-1‬‬ ‫‪Pn‬‬

‫والبنية العاملة للعقد في ‪ B-tree‬هي‪:‬‬


‫‪CP1‬‬ ‫‪K1 K1p CP2 K2 K2p ………………… CPm-1 Km-1 KPm-1 CPm‬‬

‫‪12‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪ -‬الحظ أن ‪ B-tree‬الحجم أكبر النها تحوي على مؤشرات مباشرةً لل ‪(kp) record‬‬
‫‪ -‬سرعة قراءة ‪ B+-tree‬أكبر الن الحجوم فيها ليست كبيرة‬

‫فهرس التقطيع ‪Hash index‬‬


‫وهو قليل االستخدام ‪ ,‬حيث يعتمد مبدأ التقسيم ل ‪( Bucket‬رزم)‪.‬‬
‫المقصود بالرزمة ( ‪:) Bucket‬‬
‫هي وحدة تخزين تحوي على تسجيلة أو اكثر عادةً تساوي ‪ block‬وممكن أكثر‪.‬‬
‫‪ -‬في الفهارس السابقة كنا نضع الـ ‪ record‬بشكل تسلسلي ضمن الـ ‪ block‬مثال كان الـ ‪ block‬هو عبارة عن‬
‫‪ 4 records‬فالموظف الذي ‪ id=1‬و ‪ id=2‬و ‪ id=3‬و ‪ id=4‬نضعها بالـ ‪ block‬الذي رقمه ‪ 1‬وهكذا اما هنا الوضع مختلف‬
‫حيث أننا نطبق تابع تقطيع ‪ Hash Function‬لنضع التسجيلة في الرزمة الخاصة بها ‪.‬‬
‫تابع التقطيع‪ :‬يطبق على ‪ key search‬لمعرفة ال ‪ Bucket‬الحاوية على التسجيلة ‪ ,‬حيث يتم تقسيم التسجيالت‬
‫على عدة رزم وليكن عددها ‪ m‬و كل رزمة لها رقم خاص بين ‪ 0‬و ‪ m-1‬ونعرف رقم الرزمة لتسجيلة معينة باستخدام‬
‫تابع التقطيع‪.‬‬
‫مثال‪ :‬تخزين عالقة ‪ account‬في ملف تقطيع مقسم إلى ‪ 10‬رزم باستخدام مفتاح البحث ‪ branch-name‬وتابع التقطيع‬
‫‪:h‬‬
‫𝟎𝟏 𝒅𝒐𝒎 )]𝐢[𝐞𝐦𝐚𝐧 ∑( = )𝐞𝐦𝐚𝐧(𝐡‬
‫وبالتالي‬
‫‪h (Round Hill ) =3, h (Brighton ) =3‬‬
‫‪h (partridge) =5‬‬
‫مثال نريد البحث عن الفرع الذي اسمه ‪Brighton‬‬
‫)”‪(…. Where branch-name=” Brighton‬‬
‫في هذه الحالة نطبق تابع التقطيع على الـ ‪ name‬ومنه نعرف بأي ‪ Bucket‬موجود ونذهب اليه ومن الـ ‪ key‬نذهب إلى‬
‫ال ‪( table‬يوجد مؤشر)‬
‫الحظ أن عملية البحث ضمن ‪ Hash index‬فعالة في حالة ‪ search key‬يساوي قيمة محددة أي عندما يكون‬ ‫ولكن‬
‫‪ , )where id‬هنا سيكون مشكلة ألنه سيضطر لتطبيق تابع التقطيع على كل القيم ‪10‬و‪11‬و‪...12‬‬ ‫لديك ‪ ( range‬فرضا‬
‫لكي يعلم كل واحدة منها بأي ‪ bucket‬موجودة ‪.‬لذلك يعتبر قليل االستخدام ألنه محدود نوعاً ما‬
‫باإلضافة إلى ذلك من الممكن أن يكون هناك ضغط على ‪ Bucket‬معينة >أغلب األسماء ‪ < Ahmed‬وبالتالي سنضطر‬
‫لتغيير تابع التقطيع‪ ,‬ولكن ‪ Hash index‬يستخدم في حاالت معينة ‪:‬التوزيع نظامي ‪ /‬االستعالم محدد )اليوجد‪) range‬‬

‫‪13‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪Bitmap index‬‬
‫يطبق على الواصفات التي لها مجال محدد من القيم‪.‬‬
‫مثال‪ :‬جنس اإلنسان )‪ / (F,M‬الحالة العائلية ‪....... /‬‬
‫القيم المخزنة في فهرس ‪ Bitmap‬هي عبارة عن ‪ array of bits‬طولها بعدد التسجالت في الجدول ‪ ,‬من أجل القيمة ‪V‬‬
‫للواصفة تكون قيمة ‪ Bitmap‬مؤلفة من مجموعة من البتات بحيث يكون البت الخاص بالتسجيلة رقم ‪ 1‬يساوي ‪ 1‬إذا‬
‫كانت قيمة الواصفة في هذه التسجيلة تساوي ‪ V‬وإال تساوي ‪ . 0‬سنأخذ مثال للتوضيح‬
‫ليكن لديك الجدول التالي قم ببناء فهرس من النوع ‪ Bitmap‬على الحقل ‪ gender‬وفهرس اخر على الحقل ‪: level‬‬

‫‪id‬‬ ‫‪gender‬‬ ‫‪level‬‬ ‫‪Record number‬‬


‫‪1‬‬ ‫‪m‬‬ ‫‪L1‬‬ ‫‪0‬‬
‫‪2‬‬ ‫‪m‬‬ ‫‪L2‬‬ ‫‪1‬‬
‫‪3‬‬ ‫‪f‬‬ ‫‪L3‬‬ ‫‪2‬‬
‫‪4‬‬ ‫‪m‬‬ ‫‪L4‬‬ ‫‪3‬‬
‫‪5‬‬ ‫‪f‬‬ ‫‪L5‬‬ ‫‪4‬‬
‫‪6‬‬ ‫‪f‬‬ ‫‪L6‬‬ ‫‪5‬‬

‫‪:Bitmap for gender‬‬


‫‪:M‬‬
‫‪1‬‬ ‫‪1‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪0‬‬ ‫‪0‬‬
‫الحظ طولها هو ‪ 6‬بعدد ال ‪ records‬ولتعبئتها ننظر الى الجدول فنرى أنها متواجدة في التسجيلة رقم ‪0,1,3‬‬
‫فنضع ‪ 1‬في مكانها والباقي أصفار‪.‬‬

‫‪:F‬‬
‫‪0‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪1‬‬

‫‪:Bitmap for level‬‬


‫بنفس الطريقة قمنا بتعبئتها‬
‫‪: L1‬‬
‫‪1‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪1‬‬ ‫‪0‬‬ ‫‪0‬‬

‫‪14‬‬
‫‪/ITE.RBCs‬‬
‫قواعد معطيات ‪ | 2‬د‪ .‬روان قرعوني‬

‫‪: L2‬‬
‫‪0‬‬ ‫‪1‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬

‫‪: L3‬‬
‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪0‬‬

‫‪: L4‬‬
‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪1‬‬

‫‪: L5‬‬
‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬ ‫‪0‬‬

‫مالحظة ‪ :‬فهارس ‪ Bitmap‬مفيدة عندما يكون لدي عمليات ‪ not ,and ,or‬كثيرة‬
‫مثال‪:‬‬
‫عندما نريد تنفيذ استعالم معين على الجدول في المثال السابق‪:‬‬
‫‪ -‬نريد الموظف الذي جنسه ‪ F‬ومستواه الوظيفي هو ‪ , l1‬نطبق عملية ‪ and‬بين ‪ Bitmap‬للنوع ‪ F‬و ‪Bitmap‬‬
‫للمستوى ‪: l1‬‬
‫(‪)001011( and )101100‬‬
‫‪001000‬‬

‫سيخب ظنك إن مل تنجح‪...‬لكنك‬


‫هالك إن مل حتاول‬

‫‪15‬‬
‫‪/ITE.RBCs‬‬

You might also like