در یکی از پروژه های اخیر نیاز بود یکسری داده سریالایز شده (serialize) در دیتابیس ذخیره شود.
پروژه قدیمی بود وگرنه چه چیزی بهتر از NOSQL !
در شروع کار خیلی راحت میشه به این شکل اطلاعات را سریالایز کرد :
<?php $data = ................; $output = serialize($data);
مرحله بعد هم که در دیتابیس ذخیره میشود.
همین طور که می دانید در php دو تابع برای این کار داریم ، یعنی serialize و unserialize که عمل سریالایز را برای ما مدیریت می کنند.
برای مثال:
echo serialize(['name'=>'saeed','test'=>true]);
که خروجی میشود:
a:2:{s:4:"name"s:5:"saeed"s:4:"test"b:1;}
حالا فرض کنید اطلاعات خیلی بیشتری را بخواهید ذخیره کنید.
طبیعتا حجم جدول بسیار بالا میرود.
خب راه حل چیه؟
آیا نمی توان داده ها را فشرده شده در دیتابیس ذخیره کرد و در مرحله واکشی اطلاعات آن ها از حالت فشرده خارج کرد و unserialize کرد؟
خبر خوب اینکه php برای این کار هم توابعی در نظر گرفته یعنی gzcompress و gzuncompress.
فقط نکته ای که وجود دارد این هست که برای ذخیره در دیتابیس باید به صورت base64 در دیتابیس ذخیره کرد.
$compressedData = base64_encode(gzcompress(serialize($data), 9)); $unCompressedData = unserialize(gzuncompress(base64_decode($your_encoded_data)));
حالا بیایید یک بنچمارک ساده بگیریم.
اگر اطلاعات به صورت سریالایز ساده ذخیره شود ، هر مورد چیزی در حدود 35.42 کیلوبایت هست و اگر فشرده شده ذخیره کنیم ، چیزی در حدود 2.86 کیلوبایت هست.
با یک حساب سر انگشتی می توانید بفهمید با 1000 مورد چقدر فضا در دیتابیس اشغال میشد !
یعنی برای ذخیره 1 و 100 و 1000 و 10000 مورد در دیتابیس
Serialize (default) data: [ 0.01 ms, 2.44 ms, 22.55 ms, 208.7 ms ] Compressed data: [ 0.01 ms , 2.04 ms, 18.98 ms, 176.60 ms ]
همین طور که می بینید با وجود این عملیات فشرده سازی ، زمان ذخیره در دیتابیس کمتر از حالی هست که اطلاعات سریالایز تنها شوند.
از نظر رم اشغال شده هم حالت فشرده شده مقدار کمتری را اشغال می کند برای مثال برای 100 مورد ذخیره در دیتابیس :
Serialize (default): 6,948.19 (KB) - 2,428.15 (ms) Compressed: 1,941.72 (KB) - 2,087.33 (ms)
تنها در مورد مصرف CPU ، حالت فشرده سازی ، تقریبا مقدار بیشتری (یعنی چیزی نزدیک دو برابر) مصرف می کند.
امیدوارم از این مقایسه استفاده برده باشید ...