التخزين المؤقت للبيانات – SQL Query Caching
اخوتي زوار الموقع بداية دعوني أحييكم قبل أن أبدا مقالتي لهذا اليوم والتي سأتكلم فيها عن عمليات التخزين المؤقت للاستعلامات أو نتائج الاستعلامات المطبقة على قواعد البيانات ...
ما رأيكم أن نفترض أنه لدينا موقع الكتروني يعج بالزوار كما موقعنا وفيه العديد من الصفحات التي يكون محتواها عبارة عن نتائج استعلامات معينة من قواعد بيانات الموقع ... إنه لا يخفى على أحد إن كثرة الزوار وطلبهم لهذه الصفحات سؤدي إلى فتح مئات أو حتى آلاف الاتصالات مع قاعدة البيانات الموقع مما يؤدي إلى بطء ملحوظ في تصفح أو عرض صفحات موقعنا ...
بالتأكيد هذا أمر لا نرضاه أن يكون في موقعنا وكذلك الأمر نحن حريصون جدا على وقت زوارنا ... فيكفيهم بطء النت الذي نعاني منه نحن ككل / طبعا اتكلم عن سوريا / ... إذا ما العمل ... دعونا نفكر بطريقة ما تحسن من أداء برامجنا وبالتالي سرعة في تصفح موقعنا ...
أجل يمكننا حل هذه المشكلة عن طريق التخزين المؤقت لنتائج الاستعلامات وبالتالي نحن لسنا بحاجة إلى اجراء اتصال جديد مع قاعدة البيانات وتطبيق الاستعلام المعين عليها وثم استرجاع او قراءة نتائج الاستعلام وبدلا منها سنقوم بقراءة نتائج الاستعلام المنفذ والمخزن في ملف ما في موقعنا ...
أوه نسيت أن أخبركم عن الأمور الاساسية التي يجب أن تكون متوفرة لديك كي تستطيع تطبيق المثال الذي سأطرحه لاحقا خلال المقالة ... لا تهتم كثيرا فالمتطلبات ليست كثيرة , فما عليك سوى الحصول على نسخة من محرك قواعد البيانات MySQL والمتوفر مجانا على الموقع www.mysql.com كما يجب أن تكون لديك معرفة اساسية في PHP إضافة إلى لغة الاستفسارات البنوية SQL ( Structured Query Language ) ...
الآن دعونا نرتب افكارنا أكثر ولنقل ما هي المراحل التي نمر بها عند قراءة المعلومات من قاعدة بيانات الموقع ؟؟؟
1)فتح اتصال مع قاعدة البيانات .
2)تحضير الاستعلام .
3)وثم نرسل الاستعلام أو نطبق الاستعلام على الجدول / الجداول المعينة في قاعدة بياناتنا .
4)استرجاع أو قراءة نتائج الاستعلام .
5)قطع الاتصال مع قاعدة البيانات .
إذا وكما اتفقنا منذ قليل سنقوم بعملية تخزين مؤقت للبيانات المجلوبة من جرّاء تنفيذ الاستعلام وبالتالي سنخفف الكثير من الجهد على موقعنا وعندها سيكون أكثر سرعة في الاستجابة لطلبات الزوار بقراءة المعلومات التي يطلبوها من ذاكرة التخزين المؤقت ...
نحن نستخدم الـ SQL كواجهة للتعامل مع جداول قواعد بياناتنا والمعلومات المحتواة ضمنها فعن طريقها نجري عمليات التخزين والتعديل والحذف للبيانات وحتى قرأتها من جداولنا...
في مثالنا الذي سأطرحه بعد قليل سأستخدم تعليمة SELECT لقراءة المعلومات من الجدول الموجود في قاعدة البيانات ...
بصراحة هناك أكثر من طريقة أو استراتيجية لعمليات التخزين المؤقت سأذكر أهم ثلاثة طرق او نماذج مهنا :
1)التخزين المؤقت المحدد بزمن ( Expiry Timestamp ).
2)تغير المعلومات : نراقب البيانات وفي لحظة حدوث التغير / التحديث / للبيانات نقوم بحذف ملف التخزين المؤقت وننشئ واحد جديدا ...
3)التخزين المؤقت اليدوي : نحن من يقوم بإجبار برنامجنا على القيام بعملية تحديث لملفات التخزين المؤقت ...
بالتأكيد يمكنك اتباع أي من الاستراتيجيات السابقة أو حتى ربما تتبع أكثر من واحدة ولكن سأكمل مقالتي بالاعتماد على الطريقة الأولى ...
ربما الآن تتسأل أين سنقوم بتخزين هذه البيانات المؤقتة ؟؟؟
هلأ ... لا أخفيك سرا انه هناك أيضا العديد من الطرق لتخزين البيانات المؤقتة وسأعرض لأشهرها دون ذكر التفاصيل عنها :
1)استخدام قاعدة بيانات .
2)استخدام الملفات , ملف واحد لكل إدخال .
3)استخدام ملف DBM ملف واحد لكل الادخالات.
4)استخدام ذاكرة مشتركة .
الآن وبعد كل هذا الكلام وكل هذه المقدمات دعنا نبدأ بالكود ...
للقيام بعملية التخزين المؤقت سنستخدم دالتي ( تابعي ) PHP المخصصين لهذه العمليات وهما : serialize() و unserialize() .
التابع serialize() : يستخدم هذا التابع لتخزين قيم متحولات PHP دون فقدان أنواعها أو حتى بنيهتا وبطبيعة الحال تخزن القيم على شكل بايتات متتالية ( Byte-Stream ) ...
في حقيقة الامر توابع جلسات ( PHP SESSIONS ) تخزن متحولات الجلسة ( $_SESSION ) بنفس هذه الطريقة ...
أما عن وظيفة التابع الآخر المستخدم وهو unserialize() يقوم بعكس عمل التابع الاول تماما ويعيد السلاسل المنشورة ( serialized string ) إلى بنيتها الطبيعية كما وكأنها نتيجة استعلام مطبق على قعدة بيانات ...
طيب ما رأيكم أن نفترض أنه لدينا متجر الكتروني فيه تقسيمسن اساسين وهما التصنيف Categories والمنتجات Products ... معلومات المنتجات تجدد باستمرار وربما بشكل يومي بينما تبقى التصنيفات كما هي دون أي تغيير وكأنها صفحات استاتيكية ( Static's pages ) , إذا سنقوم بعملية تخزين مؤقت لنتيجة الاستعلام الخاص بالتصنيفات ونحتفظ بالخرج الناتج في ملف لاستخدامه لاحقا ...
وليكن لجدول التصنيفات البناء التالي :
كما ذكرت منذ قليل سأستخدم التقنية الاولى المتبعة لتخزين الملفات المؤقتة وبالتالي سنمر بالمراجل التالية:
1)نتصل مع قاعدة البيانات.
2)ننفذ الاستعلام.
3)وضع نتائج الاستعلام في سلسلة لقرأتها لاحقا .
4)نشر المصفوفة الناتجة , Serialize Array .
5)حفط المصفوفة المنشورة إلى ملف .
$file = 'sql_cache.txt';
$link = mysql_connect('localhost','username','password')
or die (mysql_error());
mysql_select_db('shop')
or die (mysql_error());
/* form SQL query */
$query = "SELECT * FROM categories";
$result = mysql_query($query)
or die (mysql_error());
while ($record = mysql_fetch_array($result) ) {
$records[] = $record;
}
$OUTPUT = serialize($records);
$fp = fopen($file,"w"); // open file with Write permission
fputs($fp, $OUTPUT);
fclose($fp);
الآن انظر افتح الملف sql-cashe.txt ستلاحظ نصا ما من قبيل هذا :
a:1:{i:0;a:6:{i:0;s:1:"1";s:11:"category_id";s:1:"1";i:1;s:9:"Computers";s:13:"category_name";s:9:
"Computers" ;i:2;s:25:"Description for computers";s:20:"category_description"
;s:25:"Description for computers";}}
هذا الخرج الذي لاحظته هو مجرد تمثيل داخلي للمتحولات وأنواعها ...
الآن وبعد جلبنا لنتائج الاستعلام وخزنها في الملف sql_cashe.txt كيف لنا أن تقرأ هذه المعلومات لاحقا ...
بالتأكيد نحن بحاجة إلى اجراء عملية Unserialize لهذه المعلومات لتعود إلى حالتها الطبيعية , يمكننا قراءة محتوي الملف النصي عن طريق التابع file_get_contents() ولكن يجب ملاحظة أن هذا التابع متوفر فقط في الإصدارة 4.3.0 أو أعلى من PHP لذلك سأستخدم التابع file() ( قرأءة كامل الملف وتخزينة في مصفوفة جديدة ).
التابع implode() يستخدم للوصول إلى عناصر المصوفة في سلسلة واحدة , تقوم بقرأتها وإعادتها على شكل محتولات PHP.
// file_get_contents() workaround for PHP < 4.3.0
$file = 'sql_cache.txt';
$records = unserialize(implode('',file($file)));
الآن أصبح بإمكانك استعرض كل معلومات الاستعلام من المصوفة $records .
foreach ($records as $id=>$row) {
print $row['category_name']."
";
}
الآن كيف لنا أن نختير الملف؟ هل سنقوم بتجديد بياناته أم لا ؟
أولا سنقوم باختبار وجود الملف وثم هل تجاوز المدة المخصةصة له أم لا !وثم سنقوم بقراءة البينات المخزنة مؤقتا أو سنقوم بتطبيق الاستعلام مجددا على قاعدة البيانات .
$file = 'sql_cache.txt';
$expire = 86400; // 24 hours (in seconds)
if (file_exists($file) &&
filemtime($file) > (time() - $expire)) {
// Get the records stored in cache
$records = unserialize(file_get_contents($file));
} else {
// Create the cache using serialize() function
}
التابع filemtime() يعيد الفترة الزمنية بين آخر تحديث / تعديل / للملف المعين أو يعيد FALSE عند حدوث خطأ ما .
هذا كل شيء عن مقالتي لهذا اليوم ... هناك المزيد وتفاصيل أكثر عن هذا الموضوع ربما أنشرها لاحقا في حال أعجبتكم هذه المشاركة ...
بقى أن أذكر المصادر المعتمدة لكتابة هذه المقالة وهي التالية :
1)موقع Zend : www.zend.com
2)PHP for Developer / RAY Publishing & Science
3)PHP Manual .
ملاحظة هذه المشاركة منشورة لأول مرة على موقع المبرمجين العرب www.arabprogrammers.net
ختاما أيضا أحييكم
Nassar
اخوتي زوار الموقع بداية دعوني أحييكم قبل أن أبدا مقالتي لهذا اليوم والتي سأتكلم فيها عن عمليات التخزين المؤقت للاستعلامات أو نتائج الاستعلامات المطبقة على قواعد البيانات ...
ما رأيكم أن نفترض أنه لدينا موقع الكتروني يعج بالزوار كما موقعنا وفيه العديد من الصفحات التي يكون محتواها عبارة عن نتائج استعلامات معينة من قواعد بيانات الموقع ... إنه لا يخفى على أحد إن كثرة الزوار وطلبهم لهذه الصفحات سؤدي إلى فتح مئات أو حتى آلاف الاتصالات مع قاعدة البيانات الموقع مما يؤدي إلى بطء ملحوظ في تصفح أو عرض صفحات موقعنا ...
بالتأكيد هذا أمر لا نرضاه أن يكون في موقعنا وكذلك الأمر نحن حريصون جدا على وقت زوارنا ... فيكفيهم بطء النت الذي نعاني منه نحن ككل / طبعا اتكلم عن سوريا / ... إذا ما العمل ... دعونا نفكر بطريقة ما تحسن من أداء برامجنا وبالتالي سرعة في تصفح موقعنا ...
أجل يمكننا حل هذه المشكلة عن طريق التخزين المؤقت لنتائج الاستعلامات وبالتالي نحن لسنا بحاجة إلى اجراء اتصال جديد مع قاعدة البيانات وتطبيق الاستعلام المعين عليها وثم استرجاع او قراءة نتائج الاستعلام وبدلا منها سنقوم بقراءة نتائج الاستعلام المنفذ والمخزن في ملف ما في موقعنا ...
أوه نسيت أن أخبركم عن الأمور الاساسية التي يجب أن تكون متوفرة لديك كي تستطيع تطبيق المثال الذي سأطرحه لاحقا خلال المقالة ... لا تهتم كثيرا فالمتطلبات ليست كثيرة , فما عليك سوى الحصول على نسخة من محرك قواعد البيانات MySQL والمتوفر مجانا على الموقع www.mysql.com كما يجب أن تكون لديك معرفة اساسية في PHP إضافة إلى لغة الاستفسارات البنوية SQL ( Structured Query Language ) ...
الآن دعونا نرتب افكارنا أكثر ولنقل ما هي المراحل التي نمر بها عند قراءة المعلومات من قاعدة بيانات الموقع ؟؟؟
1)فتح اتصال مع قاعدة البيانات .
2)تحضير الاستعلام .
3)وثم نرسل الاستعلام أو نطبق الاستعلام على الجدول / الجداول المعينة في قاعدة بياناتنا .
4)استرجاع أو قراءة نتائج الاستعلام .
5)قطع الاتصال مع قاعدة البيانات .
إذا وكما اتفقنا منذ قليل سنقوم بعملية تخزين مؤقت للبيانات المجلوبة من جرّاء تنفيذ الاستعلام وبالتالي سنخفف الكثير من الجهد على موقعنا وعندها سيكون أكثر سرعة في الاستجابة لطلبات الزوار بقراءة المعلومات التي يطلبوها من ذاكرة التخزين المؤقت ...
نحن نستخدم الـ SQL كواجهة للتعامل مع جداول قواعد بياناتنا والمعلومات المحتواة ضمنها فعن طريقها نجري عمليات التخزين والتعديل والحذف للبيانات وحتى قرأتها من جداولنا...
في مثالنا الذي سأطرحه بعد قليل سأستخدم تعليمة SELECT لقراءة المعلومات من الجدول الموجود في قاعدة البيانات ...
بصراحة هناك أكثر من طريقة أو استراتيجية لعمليات التخزين المؤقت سأذكر أهم ثلاثة طرق او نماذج مهنا :
1)التخزين المؤقت المحدد بزمن ( Expiry Timestamp ).
2)تغير المعلومات : نراقب البيانات وفي لحظة حدوث التغير / التحديث / للبيانات نقوم بحذف ملف التخزين المؤقت وننشئ واحد جديدا ...
3)التخزين المؤقت اليدوي : نحن من يقوم بإجبار برنامجنا على القيام بعملية تحديث لملفات التخزين المؤقت ...
بالتأكيد يمكنك اتباع أي من الاستراتيجيات السابقة أو حتى ربما تتبع أكثر من واحدة ولكن سأكمل مقالتي بالاعتماد على الطريقة الأولى ...
ربما الآن تتسأل أين سنقوم بتخزين هذه البيانات المؤقتة ؟؟؟
هلأ ... لا أخفيك سرا انه هناك أيضا العديد من الطرق لتخزين البيانات المؤقتة وسأعرض لأشهرها دون ذكر التفاصيل عنها :
1)استخدام قاعدة بيانات .
2)استخدام الملفات , ملف واحد لكل إدخال .
3)استخدام ملف DBM ملف واحد لكل الادخالات.
4)استخدام ذاكرة مشتركة .
الآن وبعد كل هذا الكلام وكل هذه المقدمات دعنا نبدأ بالكود ...
للقيام بعملية التخزين المؤقت سنستخدم دالتي ( تابعي ) PHP المخصصين لهذه العمليات وهما : serialize() و unserialize() .
التابع serialize() : يستخدم هذا التابع لتخزين قيم متحولات PHP دون فقدان أنواعها أو حتى بنيهتا وبطبيعة الحال تخزن القيم على شكل بايتات متتالية ( Byte-Stream ) ...
في حقيقة الامر توابع جلسات ( PHP SESSIONS ) تخزن متحولات الجلسة ( $_SESSION ) بنفس هذه الطريقة ...
أما عن وظيفة التابع الآخر المستخدم وهو unserialize() يقوم بعكس عمل التابع الاول تماما ويعيد السلاسل المنشورة ( serialized string ) إلى بنيتها الطبيعية كما وكأنها نتيجة استعلام مطبق على قعدة بيانات ...
طيب ما رأيكم أن نفترض أنه لدينا متجر الكتروني فيه تقسيمسن اساسين وهما التصنيف Categories والمنتجات Products ... معلومات المنتجات تجدد باستمرار وربما بشكل يومي بينما تبقى التصنيفات كما هي دون أي تغيير وكأنها صفحات استاتيكية ( Static's pages ) , إذا سنقوم بعملية تخزين مؤقت لنتيجة الاستعلام الخاص بالتصنيفات ونحتفظ بالخرج الناتج في ملف لاستخدامه لاحقا ...
وليكن لجدول التصنيفات البناء التالي :
كما ذكرت منذ قليل سأستخدم التقنية الاولى المتبعة لتخزين الملفات المؤقتة وبالتالي سنمر بالمراجل التالية:
1)نتصل مع قاعدة البيانات.
2)ننفذ الاستعلام.
3)وضع نتائج الاستعلام في سلسلة لقرأتها لاحقا .
4)نشر المصفوفة الناتجة , Serialize Array .
5)حفط المصفوفة المنشورة إلى ملف .
$file = 'sql_cache.txt';
$link = mysql_connect('localhost','username','password')
or die (mysql_error());
mysql_select_db('shop')
or die (mysql_error());
/* form SQL query */
$query = "SELECT * FROM categories";
$result = mysql_query($query)
or die (mysql_error());
while ($record = mysql_fetch_array($result) ) {
$records[] = $record;
}
$OUTPUT = serialize($records);
$fp = fopen($file,"w"); // open file with Write permission
fputs($fp, $OUTPUT);
fclose($fp);
الآن انظر افتح الملف sql-cashe.txt ستلاحظ نصا ما من قبيل هذا :
a:1:{i:0;a:6:{i:0;s:1:"1";s:11:"category_id";s:1:"1";i:1;s:9:"Computers";s:13:"category_name";s:9:
"Computers" ;i:2;s:25:"Description for computers";s:20:"category_description"
;s:25:"Description for computers";}}
هذا الخرج الذي لاحظته هو مجرد تمثيل داخلي للمتحولات وأنواعها ...
الآن وبعد جلبنا لنتائج الاستعلام وخزنها في الملف sql_cashe.txt كيف لنا أن تقرأ هذه المعلومات لاحقا ...
بالتأكيد نحن بحاجة إلى اجراء عملية Unserialize لهذه المعلومات لتعود إلى حالتها الطبيعية , يمكننا قراءة محتوي الملف النصي عن طريق التابع file_get_contents() ولكن يجب ملاحظة أن هذا التابع متوفر فقط في الإصدارة 4.3.0 أو أعلى من PHP لذلك سأستخدم التابع file() ( قرأءة كامل الملف وتخزينة في مصفوفة جديدة ).
التابع implode() يستخدم للوصول إلى عناصر المصوفة في سلسلة واحدة , تقوم بقرأتها وإعادتها على شكل محتولات PHP.
// file_get_contents() workaround for PHP < 4.3.0
$file = 'sql_cache.txt';
$records = unserialize(implode('',file($file)));
الآن أصبح بإمكانك استعرض كل معلومات الاستعلام من المصوفة $records .
foreach ($records as $id=>$row) {
print $row['category_name']."
";
}
الآن كيف لنا أن نختير الملف؟ هل سنقوم بتجديد بياناته أم لا ؟
أولا سنقوم باختبار وجود الملف وثم هل تجاوز المدة المخصةصة له أم لا !وثم سنقوم بقراءة البينات المخزنة مؤقتا أو سنقوم بتطبيق الاستعلام مجددا على قاعدة البيانات .
$file = 'sql_cache.txt';
$expire = 86400; // 24 hours (in seconds)
if (file_exists($file) &&
filemtime($file) > (time() - $expire)) {
// Get the records stored in cache
$records = unserialize(file_get_contents($file));
} else {
// Create the cache using serialize() function
}
التابع filemtime() يعيد الفترة الزمنية بين آخر تحديث / تعديل / للملف المعين أو يعيد FALSE عند حدوث خطأ ما .
هذا كل شيء عن مقالتي لهذا اليوم ... هناك المزيد وتفاصيل أكثر عن هذا الموضوع ربما أنشرها لاحقا في حال أعجبتكم هذه المشاركة ...
بقى أن أذكر المصادر المعتمدة لكتابة هذه المقالة وهي التالية :
1)موقع Zend : www.zend.com
2)PHP for Developer / RAY Publishing & Science
3)PHP Manual .
ملاحظة هذه المشاركة منشورة لأول مرة على موقع المبرمجين العرب www.arabprogrammers.net
ختاما أيضا أحييكم
Nassar
المنتديات
التعليقات
Re: التخزين المؤقت لنتائج الاستعلامات
Re: التخزين المؤقت لنتائج الاستعلامات
إضافة تعليق جديد