لغة البرمجة المستخدمة للتوضيح وفى إعداد المثال التالى (Microsoft Visual Basic 6.0) ـ DatabaseCaching.zip
الهدف: توضيح استخدام (Linked List)، واستغلال ذلك فى عمل (Cache) والاستفادة منه.
هذا الموضوع (ج1) يوضح طريقة عمل:
- سلسلة البيانات (Linked List Chain)
- مثال على استخدام (Linked List) كـ (Cache) لقاعدة بيانات
- سلسلة البيانات (Linked List Chain)
البيانات المتسلسلة (Linked List): هى واحدة من أساسيات البيانات المهيكلة (Data Structures)، وهى تتكون من وحدات أو نقاط (Nodes) متماثلة من ناحية الهيكل ومتتالية، كل وحدة أو نقطة عبارة عن مجموعة من البيانات (Type of date, Class or Structure)، وتحتوى على مؤشر (Link) يشير إلى النقطة التالية (وتسمى Singly-Linked list)، وأحياناً تحتوى على مؤشر (Link) أخر يشير إلى النقطة السابقة (وتسمى Doubly-Linked list)، والمثال المستخدم هنا يستخدم النوع الأول (Singly-Linked list).
مثال على استخدام (Doubly-Linked list): فى تحميل بيانات من قاعدة البيانات (بعيدة) إلى الذاكرة (Cache)

ولها عدة مميزات عند استخدامها فى البرمجة، فهى تسمح بسهولة بإضافة أو حذف عناصر بيانات (Nodes) فى أى مكان داخل السلسلة، دون الاحتياج إلى تحريك باقى العناصر كما فى المصفوفات (Array) ، كذلك القابلية للامتداد وإضافة عناصر جديدة:
وعملية الإضافة فى أى موضع تسهل وتسرع فى ترتيب البيانات.
فمثلاً ولو هناك سلسلة تحتوى أسماء الطلاب (أحمد –> باسم –> تامر –> ثابت –> جمال –> خالد –> دلال –> ذينب –> رامى –> زين –> سامى –> شادى) ، وبعد ذلك أردنا إضافة (حامد) على السلسلة، فيتم إضافة عنصر جديد وهو (حامد) ونغير مؤشر عنصر (جمال)، فبدلاً من أن يشير لـ(خالد) نجعله يشير للعنصر الجديد (حامد)، وبدوره العنصر الجديد (حامد) ، يتم تعديل مؤشره ليشير إلى (خالد)، وبالتالى يكون تم إدراج العنصر الجديد فى مكانه الصحيح والحفاظ على الترتيب.
أى تصبح (أحمد –> باسم –> تامر –> ثابت –> جمال –> حامد -> خالد –> دلال –> ذينب –> رامى –> زين –> سامى –> شادى)
- مثال على استخدام (Linked List) كـ (Cache) لقاعدة بيانات
مثال باستخدام (Microsoft Visual Basic 6.0)، لاستخدام الـ(Linked list as a database cache) ويحتوى على التالية:- Employee Class: وهى تعتبر الـ(Node) ، حيث تحتوى على البيانات وعلى (Link) وهو المتغير (nextObject)، ونلاحظ هنا انه من نفس نوع (nextObject As Employee).
- المتغير pFirstEmpObject: وهو دائماً يشير إلى أول عنصر فى السلسلة، وعندما تكون السلسلة لا تحتوى على عناصر فقيمة هذا المتغير تساوى (NoThing)
- المتغير pLastEmpObject: وهو يشير إلى أخر عنصر تم إدخاله فى السلسلة، وعندما تكون السلسلة لا تحتوى على عناصر فقيمة هذا المتغير تساوى (NoThing) أيضاً
- AddNewEmployee: إضافة عنصر إلى السلسلة فى حالة عدم وجوده، وإرجاع مؤشر لهذا العنصر.
- GetEmployeeFromCache: البحث عن عنصر داخل السلسلة وإرجاع مؤشر له فى حالة وجودة، أو إرجاع (NoThing) فى حالة عدم وجودة.
- GetEmployee: البحث عن العنصر فى السلسلة باستخدام الدالة (GetEmployeeFromCache)، وفى حالة عدم وجوده يتم تحميله من قاعدة البيانات.
- LoadWholeTable: تحميل جميع العناصر الموجوده فى قاعدة البيانات إلى السلسلة باستخدام الدالة (AddNewEmployee) تضيف العنصر للسلسلة فى حالة عدم وجوده.
- FreeCache: تفريغ السلسلة من جميع العناصر.
- GetFirst: ترجع مؤشر لأول عنصر فى السلسلةن ويساوى (NoThing) إذا كانت فارغة.
- GetLast: ترجع مؤشر لأخر عنصر فى السلسلةن ويساوى (NoThing) إذا كانت فارغة.
- GetCacheCounter: عدد العناصر الموجودة فى السلسلة.
وظيفة الدوال:
- AddNewEmployee: إضافة عنصر إلى السلسلة، وظيفة الدالة :
- تستدعى الدالة (GetEmployeeFromCache) "سيتم شرحها لاحقاً"، برقم (ID) الخاص بالعنصر الذى سيتم إضافتة.
- فى حالة العنصر غير موجود فيتم إنشاء عنصر جديد، وملئه بالبيانات ثم إضافته للسلسلة:
- إنشاء عنصر جديد باستخدام New: Set pCurrentObject = New Employee
- ثم يتم ملء هذا العنصر الجديد (pCurrentObject) بالبيانات
- ثم يتم إضافته للسلسلة، وهنا توجد حالتين:
- أن يكون أول عنصر يتم اضافتة، وبالتالى يتم تخصيصه للمؤشر pFirstEmpObject
- أن لا يكون أول عنصر، وبالتالى يتم تخصيصه إلى المؤشر (nextObject) الموجود فى أخر عنصر تم إضافته ، وحيث أن المتغير (pLastEmpObject) يحتوى على أخر عصر تم إضافته، لذا ستم تخصيصه للمتغير (pLastEmpObject.nextObject)، وبالتالى أصبح أخر عنصر يشير إلى العنصر الجديد.
- تحديث المتغير (pLastEmpObject) كى يشير دائماً لأخر عنصر تمت إضافته.
- وهكذا باستمرار، عند إضافة عنصر جديد، فالمؤشر الموجود فى أخر عنصر قبل العنصر الجديد يشير إلى العنصر الجديد، والعنصر الجديد يصبح أخر عنصر فى السلسلة ويسير إلى (NoThing).

- GetEmployeeFromCache: البحث عن عنصر فى السلسلة، وظيفة الدالة:
- أولاً تخصص للمتغير (pCurrentObject) أول عنصر فى السلسلة.
- فى حالة أن المتغير يشير على عنصر (أى لا يساوى NoThing) يتم مقارنة البيانات (pCurrentObject.id) الموجودة فيه الرقم المُرسل إلى الدالة (EmpID)، فإذا كانا متطابقين فيتم إنهاء الدالة ورجوع مؤشر لهذا العنصر.
- فى حالة عدم التطابق تخصص للمتغير (pCurrentObject) العنصر التالى فى السلسلة (pCurrentObject.nextObject)، ويتم تكرار الخطوة (B).
- إذا إنتهت العناصر (أخر عنصر يساوى NoThing) دون وجود العنصر المساوى لـ(EmpID)، يتم إرجاع (NoThing).

- أولاً تخصص للمتغير (pCurrentObject) أول عنصر فى السلسلة.
استغلال الـ(Cache) لرفع أداء التطبيق:
بوجهاً عام استخدام الـ(Cache) مع قواعد البيانات له فوائد كثيرة والملحوظة التأثير فى التطبيقات، وبالخصوص عندما تكون قاعدة البيانات موجودة على جهاز أخر، ويتم الوصول إليها من خلال الشبكة أو الإنترنت، فإذا كانت الشبكة مزدحمة أحياناً، فيكون خيار الـ(Cache) ، حل مقبول لرفع الكفاءة، وغالباً لا يتم استخدام الـ(Cache) لجميع الجداول، ولكن تستخدم مع البيانات الثابتة (لا تتغير باستمرار) غالباً، ونحتاج لوصول غلها بكثرة، مثل مثلاً: أسماء المناهج الدراسية فى برنامج للجامعة، أو الدليل المحاسبى فى برامج الحسابات، وهكذا ... الخ
ويوضع البرنامج المرفق طريقتين للاستفادة من الـ(Cache):
- تحميل البيانات دفعة واحدة فى الـ(Cache) والمتمثلة فى الزرار (Load Whole Table)
- تحميل البيان عند الطلب، والمتمثلة فى الزرار (Load Current Employee)
- وفى كلا الحالتين يتم تحميل البيانات أول مرة من قاعدة البيانات (مرة واحدة فقط)، بعد ذلك يتم تخزينها فى الـ(Cache)، وعند طلبها مرة أخرى يتم إحضارها من الـ(Cache) بسرعة.
- الزرار (Fill (ID, First Name) into Combobox)، يقوم بجلب جزء صغير من البيانات (ID and Firstname)، ليملئ الـ(Combo Box)، وإحضار باقى البيانات لاحقاً عند الاحتياج إليها، وهذا يوفر فى السرعة فى حالة إن احتوت البيانات على معلومات طويلة (كصورة مثلاً).
عامةً بالنسبة لقواعد البيانات، يمكن استخدام المصفوفة (Array)، وذلك لأنه غالباً ممكن معرفة العدد الأقصى الحقول التى سيتم التعامل معها، وحجز مصفوفة لهذا العدد، - ولكن استخدام الـ (Linked list) يوفر فى استهلاك الذاكرة، حيث يتم حجز الذاكرة للعنصر عند الاحتياج لذلك فقط ، كذلك سهولة الترتيب داخل الـ (Linked list) بإدخال كل عنصر فى ترتيبه الصحيح ، ومن ثم استخدام أى طريقة بحث مثل (Binary Search).
والمثال هنا للتوضيح، ويمكن تطبيق ذلك فى تطبيقات عديدة مثل استقبال بيانات من المستخدم وغير معروف عددها مسبقاً ... الخ
ملحوظة: المثال الأصلى لهذا التطبيق بدون استخدام الـ(Cache): كيف أجعل Combo1 يحفظ البيانات
مثال على استخدام (Singly Linked list) فى قاعدة بيانات (Microsoft Access): ترقيم تلقائى مسلسل واحد عبر عدة جداول فى قواعد بيانات مختلفة
مثال على تطبيق (Doubly Linked list) فى قاعدة بيانات (Microsoft Access): تحميل بيانات من قاعدة البيانات (بعيدة) إلى الذاكرة (Cache)
شكراً

