SQLite یک پایگاه دادهٔ اسباب‌بازی نیست — و شمار فزاینده‌ای از برنامه‌های تولیدی این را ثابت می‌کنند

اشتراک‌گذاری:
SQLite یک پایگاه دادهٔ اسباب‌بازی نیست — و شمار فزاینده‌ای از برنامه‌های تولیدی این را ثابت می‌کنند

SQLite پرمصرف‌ترین موتور پایگاه داده در جهان است. این موتور درون هر دستگاه اندرویدی، هر آیفون، هر مرورگر رومیزی، هر مک و اکثر سیستم‌های ویندوزی اجرا می‌شود. تخمین زده می‌شود بیش از یک تریلیون پایگاه داده SQLite به‌طور فعال استفاده می‌شود. و در بیشتر تاریخ خود، قاعدهٔ ضمنی در توسعه وب این بوده است: SQLite برای توسعه و آزمایش مناسب است، اما پیش از عرضهٔ محصول باید به Postgres یا MySQL مهاجرت کنید.

این قاعده به‌طور فعال به چالش کشیده می‌شود — نه به عنوان یک نظر مخالف، بلکه توسط توسعه‌دهندگانی که سیستم‌های تولیدی واقعی را اجرا می‌کنند و نتایج واقعی گزارش می‌دهند. این تغییر تا حدودی فلسفی و تا حدودی فنی است.

مخالفت سنتی

مورد استاندارد علیه SQLite در برنامه‌های تحت وب تولیدی بر پایهٔ همروندی است. SQLite یک پایگاه داده مبتنی بر فایل است: همهٔ خواندن‌ها و نوشتن‌ها به یک فایل واحد بر روی دیسک می‌خورند، و در حالی که از چندین خوانندهٔ همزمان پشتیبانی می‌کند، فقط در یک زمان یک نویسنده را مجاز می‌داند. در حالت WAL (Write-Ahead Logging) که از سال ۲۰۱۰ فعال شده است، خوانندگان و آن نویسندهٔ واحد مانع یکدیگر نمی‌شوند — اما همچنان فقط یک نویسنده دارید. برای برنامه‌هایی با همروندی بالای نوشتن، این یک محدودیت سخت است.

مخالفت دوم عملیاتی است: اگر برنامه‌تان روی چندین سرور اجرا شود، نمی‌توانند یک فایل SQLite را به اشتراک بگذارند. پایگاه‌های داده توزیع‌شده مانند Postgres از طریق TCP/IP برای این منظور طراحی شده‌اند؛ SQLite چنین نیست. این باعث می‌شد SQLite برای برنامه‌های تحت وب با مقیاس افقی اساساً غیرقابل اجرا باشد.

هر دو مخالفت واقعی هستند. هیچکدام جهانی نیستند.

چه تغییری کرد: اکوسیستم تکرارپذیری

در سال ۲۰۲۱، بن جانسون Litestream را منتشر کرد — یک ابزار متن‌باز که فایل WAL SQLite را در زمان نزدیک به واقعی به ذخیره‌سازی سازگار با S3 استریم می‌کند. ایده: شما پشتیبان‌گیری خودکار خارج از سایت با RPO زیر یک ثانیه دریافت می‌کنید، بدون اینکه کد برنامه‌تان را تغییر دهید یا به یک پایگاه داده مشتری-سرور سوئیچ کنید. Litestream محدودیت تک‌نویسنده را حل نمی‌کند؛ مشکل بازیابی فاجعه و پشتیبان‌گیری را حل می‌کند که SQLite را برای تولید ناامن جلوه می‌داد. برای بسیاری از موارد استفاده، این نگرانی فوری‌تر است.

Fly.io این را با LiteFS جلوتر برد، یک سیستم فایل توزیع‌شده که از FUSE برای رهگیری نوشتن‌های SQLite و تکرار آنها به گره‌های کپی استفاده می‌کند. LiteFS به شما یک گرهٔ اصلی می‌دهد که نوشتن‌ها را می‌پذیرد و کپی‌های خواندنی که از آن پیروی می‌کنند — مشابه تکرار استریم Postgres، اما برای SQLite. برنامه‌هایی که می‌توانند نوشتن را به اصلی و خواندن را به هر کپی هدایت کنند، از مقیاس‌دهی افقی خواندن بدون تغییر موتور پایگاه داده بهره می‌برند.

بلندپروازانه‌ترین تلاش Turso است که بر پایهٔ libSQL ساخته شده است — یک فورک از کدپایهٔ SQLite که یک پروتکل شبکه، چندمستأجری و تکرار لبه را اضافه می‌کند. ایدهٔ Turso "SQLite در لبه" است: هر کاربر یک خرده‌پایگاه داده دریافت می‌کند که از نظر جغرافیایی نزدیک به آنها اجرا می‌شود و تأخیر یک پایگاه داده مرکزی را حذف می‌کند. این شرکت در سال ۲۰۲۳ در یک سری A مبلغ ۳۲ میلیون دلار جذب کرد. libSQL متن‌باز است؛ سرویس مدیریت‌شدهٔ Turso محصول تجاری است. سرویس پایگاه داده D1 کلودفلر از معماری مشابهی استفاده می‌کند و ذخیره‌سازی سازگار با SQLite را به عنوان یک اولیهٔ بدون سرور ارائه می‌دهد.

استدلال عملکرد

برای برنامه‌هایی که پایگاه داده روی همان ماشین سرور برنامه قرار دارد — که برای درصد زیادی از برنامه‌های خودمیزبان و کوچک تا متوسط صادق است — SQLite با حالت WAL اغلب برای بارهای کاری OLTP سنگین خواندن سریع‌تر از Postgres یا MySQL بنچمارک می‌شود. دلیل آن حذف تأخیر شبکه است: یک پرسش SQLite محلی از یک اتصال TCP عبور نمی‌کند. هزینهٔ یک رفت‌وبرگشت شبکه به یک سرور Postgres، حتی روی localhost، چند صد میکروثانیه است. در حجم بالای پرسش، این هزینه جمع می‌شود.

مقالهٔ COST در سال ۲۰۱۵ ("مقیاس‌پذیری! اما به چه هزینه‌ای؟") نکتهٔ مشابهی را در زمینهٔ پردازش گراف توزیع‌شده مطرح کرد: یک ماشین واحد که کد تک‌رشته‌ای خوب تنظیم‌شده را اجرا می‌کند، اغلب از سیستم‌های توزیع‌شده مانند Hadoop برای گراف‌هایی که در RAM جا می‌گیرند بهتر عمل می‌کند. این بینش تعمیم می‌یابد: سیستم‌های توزیع‌شده سربار دارند و اگر داده‌های شما روی یک ماشین جا می‌گیرد، ممکن است آن سربار را بدون هیچ سودی پرداخت کنید.

حالت WAL SQLite همچنین برای همروندی بالای خواندن بسیار خوب بهینه شده است. بنچمارک‌های Turso و توسعه‌دهندگان مستقل به طور مداوم نشان می‌دهند که SQLite ده‌ها هزار خواندن در ثانیه را روی سخت‌افزار متوسط مدیریت می‌کند، که کاملاً در محدودهٔ اکثر برنامه‌های تحت وب تولیدی قرار دارد.

چه کسانی واقعاً این کار را می‌کنند

37signals — شرکتی پشت Basecamp و Hey — پرصداترین حامی عمومی بوده است. پست وبلاگی DHH در سال ۲۰۲۳ که استدلال می‌کرد SQLite با Litestream برای اکثر برنامه‌های تحت وب کافی است، بحث قابل توجهی ایجاد کرد. 37signals از مدل "یک پایگاه داده به ازای هر مشتری" برای برخی از زیرساخت‌های خود استفاده می‌کند، جایی که ویژگی یک فایل به ازای هر پایگاه داده SQLite به یک مزیت تبدیل می‌شود: داده‌های هر مشتری در فایل خودش ایزوله است و پشتیبان‌گیری به‌سادگی انجام می‌شود.

بسیاری از توسعه‌دهندگان مستقل و تیم‌های کوچک به دلایل مشابه به SQLite مهاجرت کرده‌اند: مدل عملیاتی ساده‌تر، عدم نیاز به مدیریت یک فرایند سرور پایگاه داده جداگانه، پشتیبان‌گیری ساده (کپی کردن فایل)، و عملکردی که نیازهایشان را برآورده می‌کند. ظهور پلتفرم‌هایی مانند Railway و Fly.io که اجرای SQLite پایدار را در کنار یک برنامهٔ وب ساده می‌کنند، مانع عملیاتی را بیشتر کاهش داده است.

جایی که هنوز منطقی نیست

محدودیت تک‌نویسنده یک سقف واقعی است. برنامه‌هایی با توان عملیاتی نوشتن پایدار بالا — خطوط لولهٔ ورود داده‌های تحلیلی، سیستم‌های معاملات با فرکانس بالا، پلتفرم‌های اجتماعی با میلیون‌ها عملیات نوشتن همزمان — واقعاً به یک پایگاه داده نیاز دارند که بتواند نوشتن را در چندین گره پخش کند. SQLite به صورت بومی نمی‌تواند این کار را انجام دهد و ابزارهای تکرارپذیری که پیرامون آن ساخته شده‌اند، مدل نوشتن اصلی را تغییر نمی‌دهند.

مجموعه داده‌های بسیار بزرگ نیز چالش‌هایی ایجاد می‌کنند. SQLite از نظر تئوری از پایگاه‌های داده تا ۲۸۱ ترابایت پشتیبانی می‌کند، اما عملکرد عملی در پایگاه‌های داده با اندازه بیش از چند صد گیگابایت کاهش می‌یابد. ویژگی‌های Vacuum، Autovacuum و پارتیشن‌بندی Postgres بالغ و در مقیاس بزرگ به خوبی شناخته شده‌اند؛ مکانیسم‌های معادل SQLite ساده‌تر و در اندازه‌های بزرگ کمتر آزمایش شده‌اند.

قاعده‌ای که از جامعه در حال ظهور است: اگر QPS نوشتن شما زیر چند هزار در ثانیه است و مجموعه داده‌تان به راحتی روی یک دیسک جا می‌گیرد، SQLite با WAL ارزش ارزیابی جدی دارد. اگر به نوشتن چند اصلی، تکرار همزمان میان مراکز داده، یا امنیت در سطح ردیف با سلسله‌مراتب نقش‌های پیچیده نیاز دارید، Postgres همچنان ابزار مناسب است.

آنچه تغییر کرده است چارچوب‌بندی است. SQLite یک اسباب‌بازی نیست. این یک موتور پایگاه داده بالغ با تست‌های گسترده است که بیش از دو دهه استفادهٔ تولیدی در زمینه‌های بسیار سخت‌تر از اکثر برنامه‌های تحت وب دارد. سوال این نیست که آیا SQLite جدی است — بلکه این است که آیا محدودیت‌های خاص برنامهٔ شما با مدل آن مطابقت دارد یا خیر. برای تعداد فزاینده‌ای از سیستم‌های تولیدی، چنین است.

اشتراک‌گذاری:
SQLite یک پایگاه دادهٔ اسباب‌بازی نیست — و شمار فزاینده‌ای از برنامه‌های تولیدی این را ثابت می‌کنند | AIO APEX