نوشته شده توسط
armintirand
اگه با دیتابیس بخوام شمارنده بسازم مگه مشکلات همزمان نوشتن و خوندن رو نداره؟ در ضمن باید تو دیتابیس فقط عدد رو بذارم؟
والا الان که گفتی دقیقا مطمئن نیستم؛ خودمم شک کردم
ولی شاید قبلا اینو تست کردم و یادم نیست.
بهرحال دیتابیس حداقل جلوی بعضی خطاهای متداول و مهم رو میگیره، چون خودش مکانیزمهایی برای جلوگیری از دسترسی همزمان و خراب شدن داده ها داره؛ وگرنه هر اطلاعاتی که توی دیتابیس ذخیره میکردید ممکن بود خراب بشه، چون اطلاعات زیادی میتونن بصورت همزمان به دیتابیس برای درج ارسال یا ازش خونده بشن و این یک شرایط عادی برای تمام دیتابیس های استاندارد هست.
بنده بطور مثال از چنین کوئری ای برای درج اطلاعات مختلفی از کلاینت ها در دیتابیس استفاده میکنم:
$query="insert into `{$table_names[0][1]}` values(NULL, $raddr, $userAgent, $time, $hostRequested, $rport, $scrRes, $referer)";
بعد با شمردن تعداد رکوردهای موجود در جدول با کوئری ای مثل select count(no) as num from `{$table_names[0][1]}` هم میشه تعداد بازدید کننده ها رو شمرد (فیلد اول یک فیلد autoincrement بنام no هست).
خب حداقل امنیتی که کوئری درج اطلاعات به ما میده اینه که امکان نداره دو دستور درج (INSERT) مختلف با هم تداخل کنن. ولی در روشی که شما با فایل کار میکنید، این امکان وجود داره که دو برنامه بصورت همزمان توی فایل در نقاطی بنویسن که باعث قاطی شدن اطلاعات هردو بشه.
حالا چه حالت دیگری باقی میمونه؟
اینکه کوئری درج ما اگر قبل از اینکه موفق بشه اطلاعات رو در دیتابیس ثبت بکنه، اگر یک اسکریپت PHP دیگر هم اجرا بشه و کوئری درج دیگری رو به دیتابیس بفرسته چی میشه؟
خب در اینجا هم فکر نمیکنم هیچ مشکلی پیش بیاد، حتی اگر کوئری دوم زودتر از کوئری قبلی موفق به درج اطلاعات در دیتابیس بشه (با اینکه بنظرم یا امکان نداره یا احتمالش خیلی کمه)؛ یعنی در هر صورت هر دو کوئری موفق به درج اطلاعات در دیتابیس خواهند شد و بنابراین هر دو بازدید کننده در نهایت شمرده میشن؛ فقط در دسترسی هایی که در همون زمان برای خواندن تعداد رکوردها جهت نمایش مقدار شمارنده در صفحه صورت میگیره، این امکان وجود داره که تعداد معدودی از بازدید کننده ها بحساب نیان (چون ممکنه MySQL هنوز اجرای چند کوئری INSERT رو تموم نکرده باشه) که اینم بنظرم در شرایط عادی نادر هست و تعدادش نهایتا از یکی دوتا بالاتر نمیره (مگر در شرایط ترافیک بسیار سنگین و بازدید کننده های جدید همزمان زیاد)، و در نهایت برای شمارش های بعدی این تعداد هم اضافه خواهند شد و شمارش هیچ کاربری جز برای مدت و تعداد بسیار محدودی از نمایش شمارنده از دست نخواهد رفت.
خب بنظرم روشن شد که این روش بقدر کافی ایمن و دقیق هست!
ولی روشی که فقط یک عدد رو در دیتابیس درج کنید و همون رو افزایش بدید بنظرم جای تحلیل بیشتری داره و باید با طرز کار DBMS بیشتر آشنا باشیم و شاید تنظیمات خاصی باید انجام بدیم (مثلا اعمال Lock). فکر میکنم اگر از روشی که بنده بکار گرفتم استفاده کنید، خیلی بهتر هست و این ریسک از بین میره و حتی کارایی هم میتونه بالاتر بره (چون در شرایط ترافیک سنگین، کوئری های دیگه لزوما مجبور نیستن بخاطر یک کوئری دیگه صبر کنن). یعنی به ازای هر کاربر یک رکورد در جدول مخصوص شمارنده درج کنید (شامل هر اطلاعاتی که میخواید ذخیره بشه که میتونه فقط درج یک رکورد با یک فیلد فاقد اطلاعات خاصی هم باشه). بعد برای گرفتن تعداد بازدیدکننده ها کافیه تعداد رکوردهای موجود در جدول رو بشمارید.