MariaDB و MySQL هر دو پایگاه دادههای رابطهای (relational database) هستند، اما داستانی خواندنی دارند: در سال ۲۰۰۹ شرکت بزرگ اوراکل، شرکت Sun Microsystems را خرید. در آن زمان MySQL که کاملا متنباز بود به همین شرکت Sun Microsystems تعلق داشت. بنابراین سازندگان MySQL نگران شدند که نکند اوراکل MySQL را کمتر متنباز کند یا اینکه ویژگیهای خوب آن را پولی کند. به همین دلیل، تیم سازنده MySQL یک کپی کامل از کدهای MySQL برداشتند و شروع کردند به توسعه آن به صورت جداگانه و نام این نسخه جدید را گذاشتند MariaDB.
در اصطلاح تخصصی برنامهنویسی به انشعاب گرفتن از کدهای یک پروژه متنباز برای شروع یک مسیر جداگانه، فورک (Fork) میگویند. خیلی از پروژههای متنباز که فورک میشوند، بعد از مدتی به دلایل مختلف (کمبود نیرو و بودجه، کمشدن اشتیاق) رها میشوند و از بین میروند. مردم و کارشناسان در مورد MariaDB نیز همین فکر را میکردند. اما این فورک نهتنها زنده ماند بلکه خیلی فراتر از MySQL رفت.
فورک MariaDB یک کپی ساده و ابتدایی از MySQL نبود و از همان ابتدا مسیر خود را جدا کرد و راهی متفاوت در زمینه موتورهای ذخیرهسازی، بهینهسازی عملکرد، مجوزدهی و مدیریت جامعه کاربری در پیش گرفت. اکنون دیگر MariaDB یک جایگزین جدی MySQL محسوب میشود و آنقدر بالغ و پایدار شده که بسیاری از تیمها آن را ترجیح میدهند.
در این مقاله 8 دلیلی را که باعث شده است توسعهدهندگان به MariaDB مهاجرت کنند، با هم بررسی میکنیم و به مقایسه MySQL با MongoDB میپردازیم.
در شفافیت در لایسنسها بین MySQL و MariaDB تفاوت بزرگی وجود دارد:
اهمیت موتور ذخیرهسازی یا storage engine در یک پایگاه داده این است که تعیین میکند داده چگونه روی دیسک ذخیره، ایندکسگذاری و بازیابی شود. از این نظر MariaDB با اختلاف زیادی برتر از MySQL است زیرا MySQL موتور پیشفرض InnoDB را دارد و موتورهای تخصصی مثل موتور ستونی (columnar engine) را به صورت داخلی ارائه نمیدهد اما MariaDB علاوه بر InnoDB، موتورهای تخصصی زیر را داراست:
نکته مهم: اگر پروژهای دارید که که بار کاری ترکیبی دارد-یعنی هم بار تراکنشی (OLTP) و هم بار تحلیلی (OLAP)- یا با دادههای بزرگ سروکار دارید، MariaDB به شما کمک میکند بدون نیاز به ابزار جداگانه، هر دو را مدیریت کنید.
در ابتدای این بخش باید با مفهومی بهنام همروندی (concurrency) آشنا باشید. وقتی هزاران کاربر همزمان با هم یه یک دیتابیس وصل میشوند، دیتابیس باید بتواند اتصالات آنها را بهدرستی مدیریت کند.
من از یک مثال ساده استفاده میکنم تا بحث همروندی را یکبار برای همیشه برایتان جا بیندازم: فرض کنید شما صاحب یک رستوران شلوع هستید. در این رستوران:
connection = یک مشتری که وارد رستوران شده و پشت میز نشسته است.
thread = یک گارسون که به آن مشتری سرویس میدهد.
در این مدل به ازای هر مشتری که وارد رستوران میشود، باید یک گارسون جدید استخدام کنید. اگر صد مشتری وارد رستوران شود، باید صد گارسون استخدام کنید. بدیهی است که این تعداد گارسون فضای رستوران را بشدت شلوغ میکنند و دائما در حین رفتوآمد با هم برخورد میکنند. همچنین بهجای اینکه وقتشان صرف رسیدگی به مشتری شود، مشغول این هستند که چه کسی باید سراغ کدام میز برود! پس با افزایش مشتریها، رستوران کند و بینظم شده و پاسخگویی ضعیف میشود.
در این مدل شما تعداد مشخصی گارسون دارید. مشتریها وارد رستوران میشوند و منتظر خدمات میمانند. گارسونها بهصورت دستهجمعی به مشتریان سرویسدهی میکنند و یک گارسون ممکن است چندین مشتری را پشتسرهم راه بیندازد. پس خبری از رستوران شلوغ و نامنظم نیست و در عین حال هیچ گارسونی بیکار نیست و همه در حال انجام کار مفید هستند. مهمتر از همه اینکه زمان پاسخ ثابت و پایدار است، حتی اگر صدها مشتری وجود داشته باشد.
ماریادیبی قابلیت Thread Pool را در نسخه متنباز خود و بدون دریافت هزینه ارائه میکند، در حالیکه این قابلیت بصورت داخلی برای MySQL در نسخه Enterprise و با پرداخت هزینه در اختیار قرار میگیرد. Thread Pool هزاران اتصال همروند را با گروهبندی آنها در یک pool و پردازش دستهای (batch) بهطور بینظیری مدیریت میکند.
تفاوت عملکرد دو مدل فوق زمانی به وضوح دیده میشود که صدها یا هزاران اتصال همزمان داشته باشید. در محیطهای زیر، Thread Pool یک نیاز ضروری و اجتنابناپذیر است، نه یک انتخاب:
۱. برنامههای load balancer
وقتی چندین سرور وب به یک پایگاه داده مرکزی وصل میشوند و تعداد اتصالات همزمان بالا میرود.
۲. معماری میکروسرویس (microservices)
اگر ۵۰ سرویس کوچک داشته باشید و هر کدام ۱۰ اتصال باز کند، ۵۰۰ اتصال همزمان دارید.
۳. محیطهای serverless
در سرویسهایی مثل AWS Lambda، هر بار که تابع اجرا میشود، یک اتصال جدید به پایگاه داده شکل میگیرد. این اتصالات سریعا ایجاد و بسته میشوند. thread pool میتواند این نوسانات را مدیریت کند.
کاربرد عملی: برنامههای وب با ترافیک بالا، معماریهای میکروسرویس (microservice) و محیطهای serverless همگی از این قابلیت سود میبرند.
یکی از مهمترین تفاوتهایی که بین MySQL و MariaDB وجود دارد در شیوه مدیریت آنهاست؛ اینکه چه کسی تصمیمگیری میکند که چه ویژگی اضافه شود؟ رفع چه باگی اولویت داشته باشد و آینده نرمافزار به کجا رود؟
در MySQL تقریبا تمام تصمیمگیریهای مهم توسط اوراکل و در پشت درهای بسته انجام میشود و توسعهدهندگان هم تاثیر چندانی بر مسیر پروژه ندارند. اما در MariaDB داستان بهکلی فرق میکند. تصمیمگیریها اساسا بر عهده بنیاد MariaDB است و نقشه راه در معرض دید عموم قرار میگیرد و از جامعه کاربری بازخوردهای مداوم دریافت میکند. همچنین شرکتهای متعددی در این تصمیمگیریها مشارکت میکنند. بنابراین هیچ نهاد واحدی کنترل کامل پروژه را در دست ندارد.
اما چرا این حاکمیت اوراکل بر MySQL ضعف محسوب میشود؟ سوابق اوراکل نشان میدهد که پس از خرید پروژههای متنباز، معمولا آنها را محدود میکند. مثلا OpenSolaris که نسخه متنباز سیستمعامل سولاریس بود، پس از ورود اوراکل متوقف شد یا Hudson (یک ابزار یکپارچهسازی مداوم) پس از اختلاف با اوراکل به Jenkins تغییر نام داد و فورک شد.
همیشه پروژهای که توسط جامعه کاربری مدیریت میشود، در بلندمدت پیشبینیپذیرتر است. بخاطر همین برای توسعهدهندگان امنتر و قابلاعتمادتر است.
هنگامی که شما یک کوئری SQL مینویسید، query optimizer یا بهینهساز کوئری تصمیم میگیرد کدام راه سریعتر و بهتر است. مثلا از کدام ایندکس استفاده شود، ترتیب Joinها چطور باشد، ترکیب دادهها چگونه باشد و ...
بهینهساز کوئری در MariaDB فاصله قابل توجهی از MySQL گرفته است. یک کوئری سنگین و پیچیده گزارشگیری با زیرکوئریها و JOINهای متعدد میتواند در MariaDB خیلی سریعتر اجرا شود.
در جدول زیر، لیستی از تفاوتهای MariaDB و MySQL در بحث بهینهسازی کوئریها مشاهده میکنید:
| قابلیت | شرح | در MariaDB | در MySQL |
| بهینهسازی زیرکوئریها | تبدیل خودکار زیرکوئریها به JOIN | سریعتر و بیشتر | کندتر و کمتر |
| حذف جداول | اگر جدولی در JOIN به نتیجه نهایی کمک نکند، آن را از execution plan حذف میکند | دارد | ندارد |
| Hash Join | روشی سریع برای JOIN کردن دو جدول بر اساس تابع hash | دارد | نسخه 8.0 به بالا دارد |
| نزدیکتر آوردن شرط (Condition pushdown) | شروط WHERE را به جایی نزدیکتر به داده منتقل میکند تا فیلتر کردن زودتر انجام شود |
دارد | دارد ولی محدودتر است |
ناگفته نماند MySQL در حال نزدیک شدن به MariaDB است. MySQL در نسخه ۸.۰ به بالا hash JOIN را اضافه کرده و بهینهساز خود را بهتر کرده است. اما MariaDB هنوز هم در پردازش کوئریهای پیچیده، به ویژه زمانی که زیرکوئریها درگیرند، قدرتمندتر است.
توصیه میشود بخوانید: سرعت کوئریهای MySQL را ۱۰ برابر بالا ببرید
گاهی لازم است به منظور دسترسی بیشتر به دادهها، تقسیم بار کاری پایگاه داده و یا امنیت در برابر خرابی احتمالی پایگاه داده، دادهها را از پایگاه داده اصلی (primary) به یک یا چند پایگاه داده کپی (Replica) کپی کرد. به این فرآیند Replication میگویند.
GTID شناسهای است که به هر تراکنش (transaction) یک کد منحصربهفرد جهانی میدهد تا ردگیری آن بین primary و replicaها به سادگی امکانپذیر باشد. در MariaDB فرمت این شناسه مبتنی بر دامنه (domain-based) است. در نتیجه اگر به هردلیلی، مثلا خرابی primary، چنانچه یک replica بخواهد به primary جدیدی وصل شود، این کار خیلی راحت و بدون دردسر انجام میشود اما در MySQL شناسه GTID مبتنی بر UUID است و ممکن است در شرایطی مثل خرابی primary، تراکنشهای پاکشده دردسر درست کنند.
همچنین در بحث تکثیر موازی، در هر دو پایگاه داده، replicaها میتوانند چندین تراکنش را به طور موازی انجام دهند تا با سرعت primary همگام بمانند. اما در MariaDB کنترل دقیقتری روی نحوه موازیسازی وجود دارد و MySQL در این زمینه کمتر منعطف است.
تکثیر چندمنبعی یا Multi-source Replication به این معنی است که یک replica بتواند از چندین primary همزمان دریافت کند.
MariaDB از نسخه 1.0 به بعد از این قابلیت پشتیبانی میکند ولی این ویژگی از نسخه 7.5 به بعد به MySQL اضافه شد.
اگر تیم شما چندین مرکز داده (data center) را مدیریت میکند یا تعداد زیادی replica خواندنی (read replica) در مقیاس بزرگ دارد، این برتریهای MariaDB اصطکاک عملیاتها را کاهش میدهد. خصوصا در هنگام خرابی primary و جایگزینی آن و تغییرات توپولوژی (چیدمان و ارتباط بین سرورها) این برتریها واقعا به دادتان میرسند.
هر وقت لازم باشد داده در چندجا تکثیر شود، پشتیبانگیری قابل اعتماد حیاتی میشود. اگر زنجیره تکثیر بشکند یا دادهها خراب شوند، یک پشتیبان خوب واقعا نجاتدهنده است. ابزارهایی مثل Databasus برای MariaDB این کار را اتوماتیک و رمزگذاری شده انجام میدهند.
Temporal Tables یا تاریخچه جداول چیست؟ گاهی پیش میآید که لازم است بدانید دادهها قبلا جه شکلی بودهاند. مثلا قیمت یک کالا در یک تاریخ خاص چقدر بوده است یا آدرس یک کاربر قبل از ویرایش چه بوده است؟
در یک پایگاههای داده معمولی، وقتی یک رکورد را تغییر میدهید یا حذف میکنید، اطلاعات قبلی برای همیشه از بین میرود و برای نگهداری تاریخچه، باید خودتان مکانیزمی طراحی کنید اما MariaDB این قابلیت را به صورت Built-in در خود دارد. یعنی پایگاه داده به طور اتوماتیک تاریخچه هر سطر (row) را در خود نگه میدارد. این تاریخچه شامل این موارد است: سطر چه زمانی ایجاد شده است؟ سطر چه زمانی آپدیت شده است؟ سطر چه زمانی حذف شده است؟
برای استفاده از قابلیت شگفتانگیز و جذاب MariaDB کافیست عبارت WITH SYSTEM VERSIONING را بیفزایید:
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(255),
price DECIMAL(10,2)
) WITH SYSTEM VERSIONING;
برای دیدن وضعیت جدول در هر زمان دلخواه، از دستور FOR SYSTEM_TIME AS OF استفاده کنید:
SELECT * FROM products FOR SYSTEM_TIME AS OF '2026-01-15 10:00:00';
بدین ترتیب میتوانید ببینید که جدول products در تاریخ دلخواه شما چه شکلی بوده است.
قابلیت Temporal Tables کجاها کاربرد دارد؟ چند مثال از این ویژگی فوقالعاده را در جدولی که در ادامه آوردهام، ببینید:
| سیستمهای مالی | مشاهده ماندهحساب مشتری در یک روز خاص در گذشته |
| سیستمهای پزشکی | مشاهده سوابق تغییرات در پرونده یک بیمار |
| سیستمهای حقوقی | اثبات اینکه یک پرونده در یک زمان خاص چه محتویاتی داشته است |
| دیباگ کردن پروژه | فهمیدن اینکه چه کسی و در چه زمانی یک رکورد را حذف کرده یا تغییر داده است |
MySQL چنین قابلتی ندارد و باید خودتان با استفاده از triggerها یا shadow tableها آن را ایجاد کنید. این کار هم وقتگیر است و هم احتمال خطا دارد.
فرض کنید یک تیم برای سالهای طولانی از MySQL استفاده کرده است و حالا قصد دارد به ماریادیبی مهاجرت کند. اولین پرسشی که با آن مواجه میشود این است که کدها را چقدر باید تغییر دهند؟ خوشبختانه پاسخ این است: خیلی اندک!
MariaDB سازگاری در سطح شبکه را با MySQL حفظ کرده است. یعنی در سطح ارتباط شبکه بین برنامه و پایگاه داده، رفتار MariaDB عینا مثل MySQL است. بنابراین مواردی مثل کتابخانههای کلاینت، ORMها، سینتکسها و اشیاء پایگاه داده بدون تغییر کار میکنند.
| دسته | مثال |
| کتابخانههای کلاینت | Python's mysql-connector، JDBC برای جاوا، Node.js mysql2 |
| ORMها | Hibernate (جاوا)، Entity Framework (داتنت)، Django ORM (پایتون) |
| سینتکس SQL | دستورات SELECT، INSERT، CREATE TABLE و غیره |
| اشیاء پایگاه داده | رویههای ذخیرهشده (stored procedures)، نماها (views)، تریگرها |
درست است که مزایای متعددی برای MariaDB برشمردیم و در بسیاری از موارد ماریادیبی واقعا بهتر از مایاسکیوال است اما قرار نیست همیشه به MariaDB مهاجرت کنیم. شرایطی وجود دارند که بهتر است در MySQL بمانیم:
الف) اگر تیم شما برای سالها در MySQL کار کرده است و همه فرآیندها شامل بکآپگیری، مانیتورینگ و بازیابی و غیره را بر اساس MySQL تنظیم کرده است، شاید مهاجرت برای شما هزینه زمانی زیادی داشته و اصلا ارزشش را نداشته باشد.
ب) اگر به میزان قابل توجهی از MySQL Shell، MySQL Router یا Group Replication استفاده میکنید، جایگزینهای MariaDB احتمال دارد بصورت صددرصد مشابه کار نکنند.
ج) اگر از AWS RDS استفاده میکنید، باید بدانید که پشتیبانی آن از MySQL بهتر و آپدیتتر است.
د) اگر برنامه شما روی MySQL Community دارد به خوبی کار میکند و به محدودیت چندانی برخورد نکردهاید، صرفا برای مزیتهای تئوریک راه خود را تغییر ندهید.
در این مقاله به مقایسه MariaDB با MySQL پرداختیم و دلایلی را برشمردیم که بخاطرشان توسعهدهندگان ماریادیبی را انتخاب میکنند. اگر پروژه جدیدی را آغاز میکنید، حتما بهطور جدی ماریادیبی را بررسی کنید اما اگر سالهاست در یک پروژه قدیمی از MySQL استفاده میکنید، در صورتی که به محدودیت جدی (مثل محدودیت در thread pool، نبود جداول زمانی، عملکرد ضعیف بهینهساز، یا نگرانیهای مربوط به لایسنسها) برنخوردهاید روی مایاسکیوال بمانید.
هر دو پایگاه داده بزرگ و قدرتمندند. در مورد آنها این پرسش را از خودتان بپرسید که آیا مایل هستید آینده نرمافزارتان را چه کسی تعیین کند؟ شرکت تجاری و بزرگ اوراکل که کمی مودی است :)؟ یا یک بنیاد غیرانتفاعی که جامعه کاربری نقش مهمی در آن ایفا میکند و تا همیشه متنباز است؟
انتخاب شما کدام است؟ دلایلتان را برایمان بنویسید.
منبع مورد استفاده در این مقاله: Medium
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.