تفاوت MySQL و MariaDB برای توسعهدهنده Laravel — کدام را انتخاب کنیم؟
مقایسه MySQL 8 و MariaDB 10.11 برای Laravel: سازگاری، performance، licensing، migration و تنظیمات .env — با توصیه عملی برای ایران.
MySQL و MariaDB هر دو با Laravel و از طریق همان extension یعنی pdo_mysql کار میکنند و Eloquent روی هر دو یکسان نوشته میشود. اما از Laravel 11 به بعد، MariaDB درایور جدای mariadb هم دارد، و تفاوت نسخهها در JSON، collation، قفلگذاری و ابزارهای dump میتواند روی migration، انتقال داده و نگهداری اثر بگذارد. در XAMPP معمولاً MariaDB نصب است؛ روی VPS یا سرویس managed ممکن است MySQL 8 باشد. این مقاله کمک میکند بدون تعصب انتخاب کنید.
خلاصه: برای بیشتر پروژههای Laravel هر دو کار میکنند، اما «قابل تعویض کامل» نیستند. تصمیم را بر اساس نسخهٔ دقیقی که در production دارید بگیرید، نه نام محصول: Laravel 12 طبق مستندات رسمی MariaDB 10.3+ و MySQL 5.7+ را پشتیبانی میکند، ولی بسیاری از قابلیتها به نسخه وابستهاند. local، CI و production را روی یک محصول و نسخهٔ یکسان نگه دارید و قبل از جابهجایی بین این دو، روی staging تست کنید.
رابطه تاریخی — چرا دو تا داریم؟
MariaDB فورک community-driven از MySQL است که پس از خرید Sun (مالک MySQL) توسط Oracle شکل گرفت. سالها تقریباً جایگزین مستقیم هم بودند؛ اما از MySQL 8 و نسلهای جدید MariaDB، مسیر دو محصول جداتر شده: پیادهسازی JSON، collationهای پیشفرض، replication و بخشی از optimizer متفاوتاند. برای CRUD معمولی Laravel این تفاوتها اغلب دیده نمیشوند؛ در migration، انتقال داده و queryهای خاص دیده میشوند.
سازگاری با Laravel
Laravel رسماً هر دو را پشتیبانی میکند. در config/database.php دو اتصال جدا وجود دارد: mysql و mariadb:
# MySQL
DB_CONNECTION=mysql
# MariaDB
DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
درایور mariadb همان اتصال MySQL را گسترش میدهد اما grammar مخصوص MariaDB را به کار میبرد. چند نمونه از کد Laravel 12:
- ستون
uuid()در migration روی MariaDB 10.7 به بالا نوع بومیuuidمیسازد و در نسخههای قدیمیترchar(36). renameColumnروی MariaDB قدیمیتر از 10.5.2 با syntax قدیمی اجرا میشود.- شرطهای JSON مثل
where('options->lang', 'fa')روی MariaDB بهjson_value()و روی MySQL بهjson_unquote(json_extract())ترجمه میشوند. php artisan schema:dumpروی MariaDB ازmariadb-dumpاستفاده میکند.
اتصال mysql روی سرور MariaDB هم در عمل برای بیشتر کارها جواب میدهد و در پروژههای قدیمی رایج است، اما با درایور mariadb این تفاوتها را Laravel خودش مدیریت میکند. از utf8mb4 با collationی مثل utf8mb4_unicode_ci برای فارسی استفاده کنید. برای دیدن نسخه و نوع سرور: php artisan db:show یا SELECT VERSION(); — در MariaDB رشتهٔ نسخه شامل کلمهٔ MariaDB است.
نسخهها مهمتر از نام محصول
«MySQL» و «MariaDB» هرکدام چند خط انتشار دارند. MySQL از 8.4 مدل LTS در کنار نسخههای Innovation دارد و MySQL 5.7 در اکتبر ۲۰۲۳ به پایان پشتیبانی رسیده است. MariaDB هم نسخههای LTS (مثل 10.11 و 11.4) و نسخههای کوتاهمدت دارد. قبل از هر مقایسه، نسخهٔ دقیق production را مشخص کنید و تاریخ پایان پشتیبانی آن را در صفحهٔ رسمی lifecycle همان محصول ببینید. قابلیتی که در یک نسخه هست ممکن است در نسخهٔ نصبشده روی هاست شما نباشد.
مقایسه فنی خلاصه
| معیار | MySQL | MariaDB |
|---|---|---|
| لایسنس | Community با GPLv2 + نسخههای تجاری Oracle | MariaDB Server با GPLv2 |
| درایور Laravel | mysql | mariadb (از Laravel 11) |
| JSON | نوع JSON بومی با ذخیرهسازی باینری | JSON نام مستعار LONGTEXT با بررسی اعتبار JSON |
| UUID بومی | نوع جدا ندارد (Laravel: char(36)) | نوع uuid از 10.7 |
| collation پیشفرض | در MySQL 8: utf8mb4_0900_ai_ci | متفاوت و وابسته به نسخه |
SKIP LOCKED | از 8.0.1 | از 10.6 |
| Window functions و CTE | از 8.0 | از 10.2 |
| Replication و cluster | Group Replication / InnoDB Cluster | Galera Cluster؛ پیادهسازی GTID با MySQL متفاوت است |
| Performance | وابسته به نسخه، تنظیمات، schema و workload — benchmark با دادهٔ خودتان | |
کی MySQL؟
- هاست یا تیم ops فقط MySQL ارائه یا پشتیبانی میکند
- نیاز به ویژگی یا ابزار خاص Oracle MySQL، یا قرارداد پشتیبانی تجاری آن
- managed service که موتور MySQL را با نسخهٔ مشخص ارائه میدهد
- داده و ابزارهای موجود (مثلاً collation
0900یا replication فعلی) بر پایهٔ MySQL است
کی MariaDB؟
- XAMPP/local پیشفرض و هاستی که MariaDB نصب دارد
- هاست ایرانی با MariaDB رایج
- ترجیح open-source خالص بدون نسخهٔ تجاری Oracle
- برخی توزیعهای لینوکس MariaDB را بهعنوان بستهٔ پیشفرض ارائه میکنند
- نیاز به Galera Cluster یا قابلیتهای خاص MariaDB
تفاوتهایی که Laravel dev باید بداند
JSON
متد json() در migration روی هر دو کار میکند و castهای Eloquent یکساناند. تفاوت در لایهٔ دیتابیس است: MySQL ستون JSON را در قالب باینری مخصوص ذخیره میکند، اما در MariaDB نوع JSON نام دیگر LONGTEXT است که اعتبارش با constraint بررسی میشود. در queryهای ساده تفاوتی حس نمیکنید؛ در index روی مقادیر JSON، توابع کمتر رایج JSON و انتقال dump بین دو محصول، مستندات نسخهٔ خودتان را چک کنید.
collation و charset
اگر دیتابیس روی MySQL 8 با collation پیشفرض utf8mb4_0900_ai_ci ساخته شده باشد، restore کردن dump آن روی نسخهای از MariaDB که این collation را نمیشناسد با خطای «Unknown collation» متوقف میشود. Laravel برای جدولهایی که خودش میسازد از مقدار DB_COLLATION (پیشفرض utf8mb4_unicode_ci) استفاده میکند، اما collation پیشفرض خود دیتابیس و جدولهایی که دستی ساخته شدهاند ممکن است متفاوت باشند. قبل از انتقال، collation جدولها و ستونها را بررسی کنید.
fulltext و index
در جستجوی fulltext فارسی هر دو محدودیت دارند — اغلب Elasticsearch یا Meilisearch جدا میآوریم. indexهای معمولی B-tree، index ترکیبی و unique در هر دو یکسان در migration تعریف میشوند.
تفاوت در EXPLAIN
optimizer دو محصول یکسان نیست و خروجی EXPLAIN ممکن است برای یک query متفاوت باشد. برای بهینهسازی کوئری روی همان engine و نسخهای تست کنید که production است.
تراکنش و قفلگذاری
هر دو بهطور پیشفرض از InnoDB با سطح ایزولاسیون REPEATABLE READ استفاده میکنند و DB::transaction()، lockForUpdate() و sharedLock() روی هر دو کار میکنند. تفاوت در جزئیات نسخه است: مثلاً driver صف database در Laravel فقط روی MySQL 8.0.1+ و MariaDB 10.6+ از FOR UPDATE SKIP LOCKED استفاده میکند تا workerها روی یک job منتظر هم نمانند. deadlock و retry در تراکنشهای دیتابیس در Laravel بررسی شده.
migration از یکی به دیگری
جابهجایی بین MySQL و MariaDB معمولاً با dump و restore انجام میشود، اما بین نسخههای جدید همیشه ساده نیست — بهخصوص از MySQL 8 به MariaDB. مراحل محتاطانه:
- نسخهٔ دقیق مبدأ و مقصد را مشخص کنید و از دیتابیس فعلی backup کامل و قابل restore بگیرید — راهنمای بکاپ سایت.
- dump را با ابزار مبدأ بگیرید (
mysqldumpدر MySQL یاmariadb-dumpدر MariaDB؛ در بسیاری از نسخههای MariaDB نامmysqldumpهم برای سازگاری هست) و برای InnoDB از--single-transactionاستفاده کنید؛ اگر routine و trigger دارید--routinesو--triggersرا اضافه کنید. - collationهای
0900، ستونهای JSON و syntax خاص هر محصول را در dump بررسی کنید. - روی staging با همان نسخهٔ مقصد restore کنید،
DB_CONNECTIONرا به درایور درست تغییر دهید وphp artisan migrate:statusو تستهای پروژه را اجرا کنید. - بعد از تأیید، در زمان کمترافیک انتقال دهید و مسیر بازگشت را آماده نگه دارید.
تنظیم Laravel برای production
DB_CONNECTION=mariadb # یا mysql، مطابق سرور واقعی
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
در مقیاس بالا، ابزارهای proxy و connection pooling مثل ProxySQL با هر دو کار میکنند؛ برای بیشتر سایتها لازم نیست. پیش از انتخاب هاست یا سرویس managed، نسخهٔ موجود، سیاست بهروزرسانی، امکان backup و restore و دسترسی به لاگ کندی query را بپرسید.
توسعه local و production
رایجترین مشکل، تفاوت محیطهاست: local روی MariaDB در XAMPP، production روی MySQL 8 (یا برعکس) و تستها روی SQLite. SQLite برای تست سریع مفید است، اما رفتار JSON، collation و قفلگذاری را مثل MySQL/MariaDB شبیهسازی نمیکند. دستکم یک مرحله در CI یا staging داشته باشید که migrationها و تستهای مهم را روی همان محصول و نسخهٔ production اجرا کند؛ Docker با image نسخهٔ مشخص این کار را ساده میکند — Docker Compose برای Laravel.
Redis جدا از بحث SQL
کش و صف — REDIS_HOST — مکمل دیتابیس است نه جایگزین؛ انتخاب MySQL یا MariaDB روی آن اثری ندارد.
چکلیست انتخاب
- هاست یا سرویس production کدام محصول و چه نسخهای را ارائه میدهد؟ پایان پشتیبانی آن نسخه کی است؟
- داده یا اپلیکیشن موجود به قابلیت خاصی (JSON سنگین، collation خاص، replication فعلی) وابسته است؟
- local، CI و production روی یک محصول و نسخهٔ یکساناند؟
DB_CONNECTIONبا نوع واقعی سرور (mysqlیاmariadb) هماهنگ است؟- تیم ops با ابزارهای backup، مانیتورینگ و ارتقای کدام محصول آشناتر است؟
- مسیر ارتقای نسخه و restore از backup تست شده است؟
اشتباهات رایج
- تست روی SQLite و deploy روی MySQL یا MariaDB بدون اجرای migrationها روی همان دیتابیس.
- استفاده از latin1 یا
utf8سهبایتی برای فارسی بهجایutf8mb4. - فرض یکسان بودن optimizer یا رفتار JSON در هر دو بدون تست.
- restore مستقیم dump از MySQL 8 روی MariaDB بدون بررسی collation.
- تکیه بر عدد benchmark عمومی بهجای اندازهگیری با دادهٔ خودتان.
- ارتقای major نسخهٔ دیتابیس روی production بدون backup و تست روی staging.
جمعبندی
برای Laravel هر دو انتخاب معتبرند، اما یکسان نیستند. محصول و نسخهای را انتخاب کنید که production واقعاً ارائه میدهد، درایور mysql یا mariadb را مطابق آن تنظیم کنید، محیطها را یکسان نگه دارید و هر جابهجایی را با backup و staging انجام دهید. مهمتر از نام دیتابیس: index درست، backup قابل restore و env امن. نصب: XAMPP.
طراحی دیتابیس پروژه — مشاوره دهید.