طراحی مناسب دیتابیس(یا پایگاه داده) در وبسایتها و برنامههای تحت وب، تاثیری زیادی در کارایی و توسعه آنها دارد. اگر شما برنامه نویس php هستید به احتمال فراوان از MySQL هم استفاده کرده اید.PHP با توجه به ساختار ساده و قابل فهمی که دارد، به برنامه نویسان تازه کار کمک می کند تا در زمان محدود، ساختار functional ای بسازند.
البته ارتباط با دیتابیس کمی تجربه بیشتری نیاز دارد، ولی آن هم غیر ممکن نیست. پس اگر تازه شروع به برنامه نویسی php کرده اید، این مطلب را به دقت بخوانید، همیشه پیشگیری بهتر از درمان است. اگر از ابتدای کار روش درست را یاد بگیرید، سعی و خطای کمتری را تجربه می کنید!
در این نوشته (که مطلبی برگرفته از sitepoint است) به معرفی ۱۰ اشتباه شایع در طراحی و پیادهسازی دیتابیس MySQL می پردازیم، البته این مطلب برای برنامه نویسان زبانهای دیگر همچون JAVA، RUBY و … که با دیتابیس MySQL کار میکنند نیز مفید است. بگونه ای آموزش mysql نیز بحساب می آید.
۱- استفاده از MYISAM بجای INNODB یا بالعکس
MySQL تعدادی موتور(بخوانید engine) دارد ولی بیشتر برنامه نویسان، بدون توجه به کارایی هر کدام، از موتور MyISAM که بصورت پیش فرض انتخاب می شود استفاده می کنند؛ این در حالی است که انتخاب این موتور برای همه حالتهای ذخیره سازی اشتباه است! این موتور از کلیدهای خارجی(foreign keys) و ارتباطات آنها پشتیبانی نمیکند. یعنی شما نمی توانید جدولهایی بسازید که با هم ارتباط موثر داشته باشند(مثلا جدول محتوا و جدول دستهبندی در یک سیستم مدیریت محتوا که اگر ارتباط درستی داشته باشند، با تغییر یا حذف یک دسته بندی تمام محتواهای مرتبط با آن تغییر کرده یا حذف می شوند). مشکل دیگری که ممکن است پیش بیاید، تداخل داده ها است. زمانی که تقدم و تاخر در ورود اطلاعات مهم باشد، باید بتوان اولویت را به یک جدول داد و موقع insert و update جدول را بست.
برای حل این مشکلات از موتور InnoDB استفاده کنید.
پس کارایی MyISAM چه میشود؟ این موتور در جایی که نیاز به توابع خاصی مثل fulltext search دارید کارایی دارد. برای جستجوی جمله در دیتابیس MySQL، استفاده از LIKE و … ارزش جستجوی شما را تا حد زیادی پایین میآورد. پس برای جداولی که نیاز به جستجوی متنی در آنها دارید از موتور MyISAM استفاده نمایید.
۲- استفاده از توابع مستقیم برای دسترسی به MYSQL
همیشه زبان php و MySQL دو جزئ جدایی ناپذیر بودهاند. بهمین دلیل php، برای ارتباط و کار با MySQL، دارای توابع توکاری هست که اجازه دسترسی و کار با MySQL را براحتی فراهم میسازد. توابع mysql_connect، mysql_query، mysql_fetch_assoc و … خیلی برای برنامه نویسان آشنا است؟! بعد از رواج برنامه نویسی شی گرا، استفاده از کتابخانههای شی گرا اهمیت زیادی پیدا کرده است. پس میتوان بجای توابع قدیمی گفته شده از کتابخانه های جدیدی مانند mysqli و … استفاده نمایید(حتماً بخاطر داشته باشید که در سرور شما باید قابلیت استفاده از آنها وجود داشته باشد). از جمله مزیتهای کار با این کتابخانه ها، امنیت بالاتر، ساختار شیگرا و پشتیبانی از چند دستور همزمان است.
کتابخانه فوق العاده دیگر PDO است، که برای ارتباط با انواع دیتابیس مثل MS SQL، ORACLE و POSGER علاوه بر MySQL مناسب است.
۳- اطمینان به دادههای کاربران
یک اصل مهم در امنیت وبسایت وجود دارد و آن این است که “هیچگاه به دادههای ورودی توسط کاربر اطمینان نداشته باشید”، همیشه ممکن از هکری بعنوان یک کاربر، اطلاعات آلوده را وارد برنامه شما کند. همیشه اطلاعات وارد شده توسط کاربر را در سمت سرور اعتبارسنجی کنید. هیچگاه به اعتبارسنجیهایی سمت کاربر(client-side) مثل جاوااسکریپت اطمینان نکنید. یک نمونه کد ساده که براحتی اجازه نفوذ(sql inject) به سایت شما را خواهد داد!
$username = $_POST["name"];
$password = $_POST["password"];
$sql = "SELECT userid FROM usertable WHERE username='$username' AND password='$password';";
تنها کافی است که هکر بجای نام کاربری admin’; را وارد کند. به این صورت بجای مدیر سیستم، وارد سیستم می شود.
نکته جالب اینجاست که، هکر حتی بخود زحمت وارد کردن پسورد را هم نمیدهد، چون query بالا معادل این query میشود.
SELECT userid FROM usertable WHERE username='admin';
۴- عدم استفاده از UTF-8
این مورد بیشتر برای انگلیسی زبانها پیش می آید، ولی در خیلی از موارد ما نیز بجای استفاده از یونیکد صحیح از Unicode های پیشفرض استفاده می کنیم. توجه داشته باشید که برای پشتیبانی از زبانهای غیر لاتین در دیتابیس، باید از یونیکد درست استفاده کنید. مثلاً برای زبانهای فارسی، عربی و … باید از utf8 استفاده شود. در خیلی از تالارهای گفتگو(forumها) در مورد نمایش فارسی MySQL و چاپ صحیح متن فارسی MySQL پرسیده می شود. برای اینکار لازم است که نوع دیتابیس، جدول و فیلدهای مورد نظر را utf8 انتخاب کنید.
۵- ترجیح دادن توابع PHP به MYSQL
خیلی از تازه کارها، بجای استفاده از توبع داخلی MySQL از توابع php استفاده می کنند. مثلاً بجای استفاده از تابع AVG() در MySQL از یک حلقه برای تولید میانگین در php استفاده میکنند. این را بخاطر داشته باشید که سرعت اجرای توابع در MySQL خیلی بیشتر از php است. درست از که برای تولید نتیجه مناسب گاهی نیاز به پیمایش نتایج در حلقه داریم، ولی تا جایی که امکان دارد از توابع داخلی MySQL استفاده کنید.
۶- بهینه نکردن پرس و جوها(QUERIES)
۹۹ درصد مشکلات کارایی و سرعت در برنامه های php به دیتابیس و پرس وجوهای نادرست آن مربوط میشود. عدم بهینهسازی پرس و جوها و استفاده نادرست از دستورات علت اصلی این مشکلات است. برای اطلاع از نوشتن پرس و جوها مناسب و بهینه این مستندات را مطالعه کنید.
۷- استفاده از نوع دادههای(DATA TYPES) اشتباه
MySQL انواع دادهی زیادی دارد. انتخاب درست نوع داده برای هر فیلد تاثیر زیادی در کارایی و سرعت فهرستبندی(indexing) جداول دارد. مثلاً اگر قرار است تاریخ ذخیره کنید، نوع داده DATE یا DATETIME را انتخاب کنید. استفاده از INT یا STRING باعث افزایش پیچیدگی می شود. البته میتوانید زمان را بصورت timestamp هم ذخیره نمایید که حجم کمتری از دیتابیس گرفته و محاسبات آن سادهتر انجام میشود.
بعضی اوقات نیز اتفاق می افتد که انواع داده جدیدی توسط برنامه نویس در دیتابیس ذخیره می شود. مثل ذخیره کردن یک object بصورت serialize، که بعد از ذخیره سازی ممکن است اطلاعات آن توسط دیتابیس آسیب ببیند.
۸- استفاده از * در پرس و جوهای دیتابیس
هیچگاه از * برای دریافت تمامی فیلدهای یک جدول استفاده نکنید، همیشه سعی کنید تنها فیلدهایی که نیاز دارید را صدا بزنید! یک راه این است که اگر تعداد فیلدهای یک جدول خیلی زیاد است؛ آن جدول را تغییر دهید تا نیازی به درخواست تمامی فیلدها نباشد. دلیل این همه تاکید میتواند کاهش سرعت این نوع پرس وجوها باشد.
۹- استفاده نامناسب از فهرستسازی(INDEXING)
بعنوان یک قاعده کلی، ما برای دسترسی به اطلاعات ذخیره شده دیتابیس از index ها برای SELECT استفاده میکنیم.
فرض کنید که یک جدول برای ذخیره اطلاعات کاربران داریم که دارای یک شماره ID بعنوان کلید اصلی(primary key) و یک ایمیل است. حال برای لاگین کردن کاربر، نیاز است که اطلاعات آن از دیتابیس خوانده شود؛ MySQL برای جستجوی ایمیل شخص باید تعیین کند که مربوط به چه ID ای است. با استفاده از همین فهرست(index) MySQL با الگوریتم پرسرعت خود، ایمیل مورد نظر را به سرعت پیدا میکند. بدون این فهرست(index)، MySQL باید تمامی داده ها موجود را به ترتیب بررسی کند تا نتیجه لازم پیدا شود.
درست است که استفاده از indexing خیلی در سرعت جستجوی اطلاعات موثر است، ولی این نباید باعث شود ما تمامی ستونها را index کنیم؛ بهرحال همیشه نباید از indexing استفاده کرد، چرا که کارایی را پایین می آورد. تنها در مواقع لازم از این قابلیت استفاده کنید.
۱۰- فراموش کردن BACKUP
این موارد ممکن است خیلی نادر باشد، دیتابیس crash میکند. هارددیسک میتواند متوقف شود. سرور می تواند منفجر شود. میزبان وب می تواند ورشکسته شود. از دست دادن اطلاعات فاجعه بار است، بنابراین شما باید پشتیبانگیری خودکار و تکرارپذیری در محلی امن داشته باشید. سرویس های تحت وب زیادی برای این کار وجود دارند که میتوان از آنها برای تهیه پشتیبان استفاده نمود.
درست است که مثالهای بالا از MySQL و php بود، ولی در دیتابیسهای دیگری همچون postgerSQL و Firebird هم از جمله پرطرفدارها هستند، هم کارایی دارند.