انجین های دیتابیس و ذخیره سازی اطلاعات
سلام؛
1) کدامیک از انجین های innoDb و myIsam بهتر است؟ چرا؟ و روش تبدیل انجین ها بدون از دست رفتن اطلاعات چیست؟
2) چجوری میشه کاری کرد که توی یک فیلد از نوع varchar، بصورت پیشفرض همیشه یک prefix زده بشه؟
سلام
در مورد سوال اول به این شکل نیست که بشه گفت فلان انجین از انجین دیگر بهتر یا بدتر هست. هر یک از این انجین ها قابلیت هایی دارند.
طبق داکیومنت های MySQL در جداولی که تغییرات زیاد هست (مثلا هر لحظه یا هر دقیقه چندین update یا insert صورت میگیره ) انجین InnoDB خوب ، و در جداولی که کوئری های متعدد از آنها میگیریم (select) در صورتی که index ها به درستی سِت شده باشند ، MyISAM بهتر عمل میکنه.
یا یکی از تفاوت های مهم دیگه ی این دو پشتیبانی InnoDB از Transaction ها هست.
اگر میخواهید حرفه ای با این انجین ها کار کنید نیاز به مطالعه داکیومنت ها و آموزش های مرتبط دارید.
در مورد سوال دوم ، یک روش خیلی ساده ای که به ذهن من میرسه استفاده از CONCAT در کوئری هست ، به عنوان نمونه :
INSERT INTO x_user (username,password) values (CONCAT('your_prefix','$username'), '$password')
نکته : امن سازی کوئری رو فراموش نکنید (SQL Injection)
۱) اگر میزان کوئری های select و insert به یک اندازه باشند و update نداشته باشیم، کدوم انجین بیشتر به کار میاد؟
و اینکه منظورتون رو از transaction ها واضح تر کنید.
۲) میخوام در سطح phpmyadmin و mysql کاری کنم که اتوماتیک prefix بزنه و کاری به کد SQL نداشته باشم.
(در واقع بزارید مشکلمو با prefix بگم. در فرم ثبت نام من از کاربر شماره موبایل و شماره تلفن ثابت به همراه پیش شماره میگیرم و در فیلدی از جنس varchar۱۱ ذخیره می کنم. طبق بررسی هام هنگام ذخیره سازی موقت داده ها در متغیر ها پس از دریافت اطلاعات از فرم توسط متد post هیچ مشکلی وجود نداره. اما در کلاس Db هنگام کوئری زدن، عدد "۰" پیشوند شماره ها حذف میشه. توی SQL مستقیم در phpmyadmin این مشکل وجود نداره.)
ممنون میشم راهنمایی بفرمایید.
در مورد سوال اول ، انجین InnoDB رو پیشنهاد میکنم. ضمن اینکه اگر این جدول مربوط به یوزرها میشه ، احتمالا باید از Foreign Key ها درش استفاده کنید ، که این هم یکی دیگر از تفاوت های InnobDB و MyISAM هست ؛ و در واقع MyISAM از Foreign Key پشتیبانی نمیکنه.
Transaction ها یا همان تراکنش ها ، یکی از قابلیت های پیشرفته در انجین InnoDB هست که در پست بعدی توضیح مختصری میدم براتون.
جالبه بدونید انجین InnoDB تا همین چندسال پیش رایگان نبود ، و خیلی خوب شد که رایگان شد چون امکانات خوبی داره.
سوال دوم برای من عجیب هست ، چون وقتی نوع فیلد varchar باشه ، عدد صفر باید در ابتدا بدون مشکل در دیتابیس ذخیره بشه.
شاید مشکل دیگری در کدهای شما وجود داشته باشه که باعث این موضوع میشه.
توی جستجوی هایی که من کردم ، روش خاصی برای اینکه در phpMyAdmin بشه اینکارو کرد وجود نداره.
از دستور LPAD طبق عکس زیر هم میتونید بنوعی اینکار رو انجام بدید (البته این روش هم در کوئری جواب میده)
اما در مجموع چون نوع فیلد شما varchar هست باید صفر در ابتدای استرینگ insert بشه بدون مشکل ؛ پس کدهاتون رو دوباره چک کنید.
در مورد Transaction ها که یکی از قابلیت های مهم به حساب میاد ؛ یک مثال ساده میزنم تا متوجه بشید.
فرض کنید در نرم افزاری که مینویسید ، یکسری عملیات و یا محاسباتی ، بر اساس یک فرآیند و ترتیب مشخصی باید انجام بشه ،
مثلا باید مقدار 100 از حساب کاربر A کم بشه ، و همون عدد به حساب کاربر B اضافه بشه.
این عمل در دو کوئری با update صورت میگیره ، یعنی :
UPDATE x_user SET value = value – 100 WHERE user_id = ‘A’;
UPDATE x_user SET value = value + 100 WHERE user_id = ‘B’;
حالا فرض کنید زمانی که در سرور کوئری اول زده میشه ، به هر دلیلی اتفاقی بیفته و کوئری دوم زده نشه ، مثلا برق سرور قطع بشه (در بعید ترین حالت) و خلاصه کوئری دوم زده نشه.
در این صورت تمام حساب و کتاب های سیستم بهم میریزه و در گزارش های مالی اشکالات خیلی بدی پیش میاد و تا سر منشا این مشکل پیدا بشه وقت و انرژی و هزینه زیادی باید صرف بشه.
راه حال اینجور کوئری ها استفاده از Transaction ها هست .
مثال بالا با استفاده از Transaction در MySQL :
START TRANSACTION;
UPDATE x_user SET value = value – 100 WHERE user_id = ‘A’;
UPDATE x_user SET value = value + 100 WHERE user_id = ‘B’;
COMMIT;
در این حالت کوئری ها در حافظه ذخیره میشن و در زمانی که به خط commit میرسیم ، به شکل درست و بدون اشکالی تمام کوئری هایی که بین start تا commit نوشته شده اعمال میشه. (این دستوراتی که من نوشتم مربوط به SQL هست و با یک سرچ ساده میتونید دستورات Transaction در PHP رو پیدا کنید و به کلاس Db اضافه کنید)
تراکنش ها به شدت کاربردی هستند ، مخصوصا در سیستم های فروشگاهی. تمام فروشگاه های آنلاینی که میبینید در اکثر کوئری هاشون از تراکنش ها استفاده میکنند ، چون محاسباتشون حساس هست.
به این نکته هم توجه کنید که InnoDB از تراکنش ها پشتیبانی میکنه ، ولی MyISAM پشتیبانی نمیکنه .
:)
در مورد تغییر انجین یک جدول ، من هر موقع از دستور زیر استفاده کردم مشکلی نداشتم.
ALTER TABLE table_name ENGINE = MyISAM;
در مورد تغییر انجین ها باید خیلی خیلی مراقب باشید ، مخصوصا اگر جدولی با انجین InnoDB دارید و بعضی از فیلدهای اون جدول Foreign Key هستند ، با تغییر انجین این جدول ممکنه ساختار دیتابیستون بهم بریزه.
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .