كاش قواعد البيانات – درس متقدم
ما هي عملية الكاش Cache ؟
هي عملية حفظ ملفات الانترنت ( صفحات المواقع عبارة عن مجموعة من الملفات ) أو أجزاء منها على السيرفر لعدم استدعائها من الانترنت عند طلبها للمرات القادمة ..
هذا هو التعريف المتداول لعملية الكاش Cache ..
بالنسبة لقواعد البيانات فإن الكاش يعتبر أحياناً أمراً ضروريا و خاصة إذا كان الجدول الذي نتعامل معه يحتوي على 10 آلاف مدخل أو أكثر على سبيل المثال ..
هذا هو التعريف المتداول لعملية الكاش Cache ..
بالنسبة لقواعد البيانات فإن الكاش يعتبر أحياناً أمراً ضروريا و خاصة إذا كان الجدول الذي نتعامل معه يحتوي على 10 آلاف مدخل أو أكثر على سبيل المثال ..
عملية الكاش بالنسبة لقواعد البيانات تعتمد على تخزين البيانات المطلوبة في ملف ثم جلبها من الملف طالما أنها ثابتة .. و عند قيامنا بأي تعديل على الملف يتوجب علينا حذف ملف الكاش و انشاءه من جديد ..
العملية تصبح كالتالي :
- جلب البيانات من جدول في قاعدة البيانات ( المرة الأولى ) و تستغرق وقتاً طويلاً في حال كنا نجلب 60 مدخلاً من اصل 100000 مدخل قد تستغرق العملية ثانيتان ( قد يبدو الزمن قليلاً لكن مقارنة بالزمن الذي يستغرقه جلب البيانات من ملف الكاش سيبدو هذا الرقم هائلاً )
- تخزين البيانات التي قمنا بجلبها في ملف مهما كان امتداده ( في المثال الملف سيكون باللاحقة tmp )
- عند تكرار الدخول للصفحة فإن المتصفح سيقوم بالبحث عن ملف الكاش و في حال تواجده سيتم جلب البيانات منه و إن لم يكن موجوداً فيتم جلب البيانات من جدول بقاعدة البيانات ثم انشاء ملف الكاش .
- عند اجراء أي تعديل على قاعدة البيانات في القسم المتعلق بما قمنا بتخزينه في ملف الكاش يجب علينا حذف ملف الكاش .
- تخزين البيانات التي قمنا بجلبها في ملف مهما كان امتداده ( في المثال الملف سيكون باللاحقة tmp )
- عند تكرار الدخول للصفحة فإن المتصفح سيقوم بالبحث عن ملف الكاش و في حال تواجده سيتم جلب البيانات منه و إن لم يكن موجوداً فيتم جلب البيانات من جدول بقاعدة البيانات ثم انشاء ملف الكاش .
- عند اجراء أي تعديل على قاعدة البيانات في القسم المتعلق بما قمنا بتخزينه في ملف الكاش يجب علينا حذف ملف الكاش .
سنقوم بتعيين مجلد الكاش و الذي يجب أن يكون قابلاً للكتابة
1 | $dir = 'cache/'; | |
2 | $file = $dir.'cachefile.tmp'; |
في الكود السابق قمنا بتحديد مجلد الكاش و سميناه cache ثم قمنا بتحديد مسار ملف الكاش و أسندناه إلى متغير .
الخطوة الأولى
1 | if (!file_exists($file)) { | |
2 | // جلب البيانات من قاعدة البيانات |
3 | } |
قمنا بعمل شرط .. باستخدام دالة file_exists و مهمتها التأكد من وجود ملف الكاش في المسار المحدد لها وقد وضعنا قبلها اشارة ( ! ) و التي تعني ( إذا لم يكن ) أي أنه في حال لم يكن الملف موجوداً سيتم تنفيذ الشرط و هو جلب البيانات من قاعدة البيانات و تخزينها في ملف الكاش .
01 | if (!file_exists($file)) { | |
02 | $SQL = mysql_query("SELECT id,title FROM news ORDER BY id DESC"); |
03 | while ($row = mysql_fetch_array($SQL)) { | |
04 | $data[]= $row; |
05 | echo $row['title'].' | |
06 | ' |
07 | } | |
08 | $cached_data = base64_encode(serialize($data)); |
09 | $openfile = fopen($file,"w"); | |
10 | fputs($openfile, $cached_data); |
11 | fclose($openfile); | |
12 | } |
قمنا ضمن الكود السابق بجلب المدخلات من قاعدة البيانات بافتراض ان اسم الجدول هو news ، ثم قمنا بادخال البيانات ضمن مصفوفة و قمنا بطباعة الناتج و هو عنوان كل خبر ( مدخل ) ضمن جدول الأخبار ( news ) و التي سنفترض أن عددها 5000 خبر ( مدخل ) .
بعد أن انهينا طباعة الناتج .. نقوم بتحويل البيانات إلى مصادر قابلة للتخزين عن طريق الدالة serialize . هناك أمر اختياري لكنني اعتقد بأنه مفيد و هو تشفير البيانات المخزنة عن طريق الدالة base64_encode و ذلك ليس لحمايتها من العبث إذ أن الدالة base64_encode سهلة الفك و هناك دالة معاكسة لها وظيفتها فك تشفير البيانات المشفرة بهذه الدالة و انما استخدامنا لها يعتبر احتياطاً لمشاكل قد تحدث نتيجة علامة اقتباس او اي شيء من هذا القبيل ..
بعد أن نقوم بتهيئة البيانات و تشفيرها نقوم بفتح ملف الكاش مع اعطاءه صلاحية الكتابة عن طريق الدالة fopen و التي حددنا فيها مسار الملف ثم حددنا لها الإجراء المتخذ و هو الكتابة في الملف (w).
نقوم بالكتابة في الملف عن طريق الدالة fputs و التي حددنا لها الملف المراد الكتابة فيه ثم مررنا إليها البيانات التي نريد ادخالها في الملف .
نقوم باغلاق الاتصال مع الملف عن طريق الدالة fclose مع تحديد الملف المراد اغلاقه .
و بهذا نكون قد انجزنا الجزء الأول من الكود و هو انشاء ملف الكاش .
بعد أن انهينا طباعة الناتج .. نقوم بتحويل البيانات إلى مصادر قابلة للتخزين عن طريق الدالة serialize . هناك أمر اختياري لكنني اعتقد بأنه مفيد و هو تشفير البيانات المخزنة عن طريق الدالة base64_encode و ذلك ليس لحمايتها من العبث إذ أن الدالة base64_encode سهلة الفك و هناك دالة معاكسة لها وظيفتها فك تشفير البيانات المشفرة بهذه الدالة و انما استخدامنا لها يعتبر احتياطاً لمشاكل قد تحدث نتيجة علامة اقتباس او اي شيء من هذا القبيل ..
بعد أن نقوم بتهيئة البيانات و تشفيرها نقوم بفتح ملف الكاش مع اعطاءه صلاحية الكتابة عن طريق الدالة fopen و التي حددنا فيها مسار الملف ثم حددنا لها الإجراء المتخذ و هو الكتابة في الملف (w).
نقوم بالكتابة في الملف عن طريق الدالة fputs و التي حددنا لها الملف المراد الكتابة فيه ثم مررنا إليها البيانات التي نريد ادخالها في الملف .
نقوم باغلاق الاتصال مع الملف عن طريق الدالة fclose مع تحديد الملف المراد اغلاقه .
و بهذا نكون قد انجزنا الجزء الأول من الكود و هو انشاء ملف الكاش .
الخطوة الثانية
الآن لقراءة ملف الكاش و الذي هو الشرط البديل للشرط الأول أي :
1 | if (!file_exists($file)) { | |
2 | // الجلب من قاعدة البيانات و انشاء ملف الكاش |
3 | } else { | |
4 | // الجلب من ملف الكاش |
5 | } |
نقوم بجلب ملف الكاش عن طريق الدالة file_get_contents ثم نقوم بفك تشفير البيانات عن طريق الدالة base64_decode ثم نقوم بإعادة البيانات إلى مصفوفة لكي نتمكن من التعامل معها .
1 | $cached_data = unserialize(base64_decode(file_get_contents($file))); |
الآن نتج لدينا مصفوفة نقوم بتجزئتها ضمن حلقة تكرار لكي نقوم بطباعة البيانات التي نريدها
1 | foreach ($records as $id=>$row) { | |
2 | echo $row['title'].' |
3 | '; | |
4 | } |
و بهذا نكون قد انهينا كتابة الكود ليصبح كاملاً كالتالي :
01 | $dir = 'cache/'; | |
02 | $file = $dir.'cachefile.tmp'; |
03 | if (!file_exists($file)) { | |
04 | $SQL = mysql_query("SELECT id,title FROM news ORDER BY id DESC"); |
05 | while ($row = mysql_fetch_array($SQL)) { | |
06 | $data[]= $row; |
07 | echo $row['title'].' | |
08 | ' |
09 | } | |
10 | $cached_data = base64_encode(serialize($data)); |
11 | $openfile = fopen($file,"w"); | |
12 | fputs($openfile, $cached_data); |
13 | fclose($openfile); | |
14 | } else { |
15 | $cached_data = unserialize(base64_decode(file_get_contents($file))); | |
16 | foreach ($records as $id=>$row) { |
17 | echo $row['title'].' | |
18 | '; |
19 | } |
20 | } |
ملاحظة : عند قيامنا بأي أمر ( إدخال – تحديث – حذف ) ضمن الجدول news يجب علينا أن نقوم بحذف ملف الكاش عن طريق دالة unlink
1 | mysql_query('UPDATE news SET ... .... ..'); | |
2 | unlink($file); |
الدوال التي قمنا باستخدامها في المثال و هي :
file_exists
و ظيفة هذه الدالة هي التأكد من وجود الملف الممرر لها و تعود بالقيمة true في حال كان موجوداً و القيمة false في حال لم يكن موجوداً .
base64_encode
وظيفة الدالة هي تشفير النص الممرر لها .
base64_decode
وظيفة الدالة هي فك تشفير النص المشفر عن طريق base64_encode
serialize
وظيفة الدالة هي تحويل المصفوفة إلى بيانات قابلة للتخزين .
unserialize
وظيفتها عكس الدالة السابقة أي إعادة البيانات المخزنة إلى مصفوفة .
fopen
وظيفة الدالة هي فتح اتصال مع ملف مع تحديد الإجراء الذي سنقوم به ضمن ذلك الملف و في مثالنا كان الإجراء هو الكتابة ( w ) .
fputs
وظيفة الدالة هي نقل أو كتابة البيانات إلى ملف محدد حيث أن البارامتر ( العامل ) الأول هو الملف الذي نتعامل معه و البارامتر ( العامل ) الثاني هو البيانات التي سننقلها أو نكتبها فيه .
fclose
وظيفة الدالة هي غلق الاتصال مع الملف .
file_get_contents
وظيفة الدالة هي جلب محتويات الملف الممرر لها .
و ظيفة هذه الدالة هي التأكد من وجود الملف الممرر لها و تعود بالقيمة true في حال كان موجوداً و القيمة false في حال لم يكن موجوداً .
base64_encode
وظيفة الدالة هي تشفير النص الممرر لها .
base64_decode
وظيفة الدالة هي فك تشفير النص المشفر عن طريق base64_encode
serialize
وظيفة الدالة هي تحويل المصفوفة إلى بيانات قابلة للتخزين .
unserialize
وظيفتها عكس الدالة السابقة أي إعادة البيانات المخزنة إلى مصفوفة .
fopen
وظيفة الدالة هي فتح اتصال مع ملف مع تحديد الإجراء الذي سنقوم به ضمن ذلك الملف و في مثالنا كان الإجراء هو الكتابة ( w ) .
fputs
وظيفة الدالة هي نقل أو كتابة البيانات إلى ملف محدد حيث أن البارامتر ( العامل ) الأول هو الملف الذي نتعامل معه و البارامتر ( العامل ) الثاني هو البيانات التي سننقلها أو نكتبها فيه .
fclose
وظيفة الدالة هي غلق الاتصال مع الملف .
file_get_contents
وظيفة الدالة هي جلب محتويات الملف الممرر لها .