SQLite یک پایگاه داده ارتباطی رابطهای تودرمانی است که بدون فرآیند سرور جداگانه کار میکند و کل پایگاه را در یک فایل روی دستگاه ذخیره میکند. به دلیل پیکربندی صفر، اندازه کوچک کتابخانه و پشتیبانی کامل از SQL، SQLite به استانداردی برای ذخیره محلی دادهها در برنامههای موبایل تبدیل شده است. به گزارش SQLite Consortium (2025)، این سیستم مدیریت پایگاه داده در بیش از 4 میلیارد دستگاه از جمله هر گوشی هوشمند در iOS و Android استفاده میشود.
نکات کلیدی
SQLite یک کتابخانه به زبان C است که یک سیستم مدیریت پایگاه داده ارتباطی بدون سرور جداگانه پیاده سازی میکند. آن مستقیماً در برنامه جایگزین میشود و دادهها را در یک فایل عادی روی سیستم فایلی دستگاه میخواند و مینویسد. اندازه کتابخانه حدود 600 کیلوبایت است که SQLite را سبکترین پایگاه داده SQL کاملاً عملکردی میسازد.
SQLite از بخش بزرگی از استاندارد SQL:1999 از جمله JOIN، زیرپرسها، تریگرها، نمایشها، اندکسها و توابع پنجرهای پشتیبانی میکند. محدودیتها مربوط به ALTER TABLE (پشتیبانی محدود) و RIGHT/FULL OUTER JOIN کامل است. با این حال، برای برنامههای موبایل کارکرد SQLite در 99% موارد ذخیره محلی کافی است.
به گزارش نظرسنجی توسعهدهندگان Stack Overflow (2025)، SQLite محبوبترین پایگاه داده برای راهحلهای تودرمانی است و پس از MySQL و PostgreSQL سومین محبوبترین سیستم مدیریت پایگاه داده است. در توسعه موبایل، SQLite در هر برنامهای — مستقیماً یا از طریق پیچیدهسازیها — استفاده میشود.
Zero-configuration — SQLite نیازی به نصب، پیکربندی دسترسیها، ایجاد کاربران یا راهاندازی سرویس ندارد. کتابخانه به پروژه متصل میشود و پایگاه داده با فراخوانی یک تابع ایجاد میشود. این نسبت به سیستمهای مدیریت پایگاه داده مشتری-سرور که نیازمند نصب سرور، پیکربندی پورتها و تنظیم کاربران هستند، استقرار را به طور اساسی ساده میکند.
فایل پایگاه داده SQLite یک فایل عادی چند سیستمی است که میتوان آن را کپی، تحلیل، از طریق شبکه ارسال یا از پشتیبان بازیابی کرد. فرمت فایل در سطح API پایدار است: فایلهای SQLite 3 ایجادشده در سال 2004 با نسخه فعلی کتابخانه باز میشوند که سازگاری بلندمدت دادهها را تضمین میکند.
معماری SQLite از هشت ماشین مجازی تشکیل شده: Tokenizer، Parser، Code Generator، VM، B-Tree، Pager، OS Interface و Utilities. پرسوجوی SQL از Tokenizer (تقسیم به توکنها)، Parser (ساخت AST)، Code Generator (تبدیل به کد بایت) عبور کرده و روی ماشین مجازی اجرا میشود که صفحات داده را از طریق B-Tree و Pager میخواند.
SQLite برای ذخیره جداول و اندکسها از B-Tree استفاده میکند. هر جدول به عنوان یک B-Tree جداگانه ذخیره میشود که در آن گرههای برگی شامل سطرهای داده هستند. اندکسها نیز به عنوان B-Tree ذخیره میشوند اما با کلیدهایی در برگها. Pager بارگذاری صفحات (پیشفرض 4096 بایت) از فایل به حافظه را مدیریت کرده و تراکنشهای ACID را از طریق ژورنال یا WAL تامین میکند.
WAL (Write-Ahead Logging) — حالت توصیهشده برای برنامههای موبایل. تغییرات ابتدا در یک فایل WAL جداگانه نوشته میشوند و سپس به طور دورهای به پایگاه داده اصلی منتقل میشوند. WAL اجازه خواندن همزمان از پایگاه داده (دادههای قدیمی) و نوشتن به آن (از طریق WAL) را فراهم میکند که بازدهی برنامههای چند رشتهای را افزایش میدهد. ژورنال استاندارد (rollback journal) خواندن را در زمان نوشتن بلوک میکند.
| پارامتر | Rollback Journal | WAL (Write-Ahead Logging) |
|---|---|---|
| خواندن در زمان نوشتن | بلوک میشود | مجاز است (دادههای قدیمی را میخواند) |
| کارایی نوشتن | متوسط | بالا (نوشتن پیاپی در WAL) |
| مصرف دیسک | کمتر (فقط ژورنال بازگشت) | بیشتر (WAL + پایگاه داده اصلی) |
| بازیابی پس از خطا | بازگشت به آخرین چکپوینت | بازیابی از WAL (دادهها از دست نمیروند) |
| توصیه | برای سناریوهای تک رشتهای | برای برنامههای موبایل تیپیک |
تغییر بین حالتها با یک پرسوجوی SQL انجام میشود: PRAGMA journal_mode=WAL. برای برنامههای موبایل با همگامسازی پسزمینه و رشته UI که همزمان دادهها را میخواند، WAL کارایی بهتر و عدم بلوکشدگی رایکرد را فراهم میکند.
SQLite تنها گزینه برای ذخیره محلی دادهها نیست، اما افزونه عاملانه ترین است. Realm سرعت بالاتری در دسترسی مستقیم به اشیا در حافظه ارائه میدهد، اما از فرمات NoSQL خود استفاده کرده و اندازه کتابخانه بزرگتری دارد. Core Data در iOS یک لایه ORM بر روی SQLite است که مدیریت گراف اشیا و الغو عملیات را اضافه میکند.
برای اکثر برنامهها، SQLite به دلیل کارایی قابل پیشبینی، عدم وابستگی به فروشنده و پایداری آزمایششده از زمان، گزینه بهینه باقی میماند. Realm و Core Data در پروژههایی با گرافهای اشیای پیچیده، پرسوجوهای واکنشی یا نیاز به همگامسازی بین دستگاهها موجه هستند.
| ویژگی | SQLite | Realm | Core Data |
|---|---|---|---|
| نوع پایگاه داده | ارتباطی (SQL) | NoSQL (شییگرا) | ORM (روی SQLite) |
| اندازه کتابخانه | ~600 کیلوبایت | ~4 مگابایت | ساختهشده در SDK Apple |
| کارایی | متوسط | بالا (اشیا در حافظه) | متوسط (سرریار ORM) |
| سیستمهای عامل | iOS، Android، Web، Desktop | iOS، Android، Node.js | iOS، macOS |
| وابستگی به فروشنده | ندارد (استاندارد باز) | متوسط (فرمات خود) | بالا (فقط Apple) |
انتخاب بین SQLite، Realm و Core Data بستگی به سیستم عامل، نیازمندیهای مدل شییی و استراتژی همگامسازی دارد. برای پروژههای چند سیستمی (KMP، Flutter)، SQLite تنها گزینه جهانی است که بدون تغییر در مدل داده، روی همه سیستمهای هدف کار میکند.
Room — کتابخانهای از Android Jetpack است که یک لایه ORM بر روی SQLite ارائه میدهد. Room به طور خودکار پرسوجوهای SQL را از رابطهای DAO انوتاسیونشده تولید میکند، صحت پرسوجوها را در مرحله کامپایل بررسی میکند و از مهاجرتهای پایگاه داده در زمان تغییر شما پشتیبانی میکند. Room روش توصیهشده کار با SQLite در Android است.
SQLiteOpenHelper — API سطح پایین برای مدیریت مستقیم SQLite بدون ORM. این کلاس ایجاد، باز کردن و بهروزرسانی پایگاه داده را مدیریت میکند. SQLiteOpenHelper برای پروژههایی با پرسوجوهای SQL ساده یا وقتی کنترل کامل بر منطق SQL بدون چکیدگی Room لازم است مناسب است.
واحد در Room با @Entity و DAO با @Dao انوتاسیون میشود. Room روشهای انوتاسیونشده را به پرسوجوهای SQL تبدیل میکند: @Insert INSERT تولید میکند، @Query — SELECT با SQL مشخص. مهاجرتها از طریق Migration با مشخص کردن نسخه شما قدیمی و جدید اضافه میشوند. Room SQL را در مرحله کامپایل بررسی میکند که خطاهای نحوی را در تولید حذف میکند.
@Entity
data class User(
@PrimaryKey val id: Long,
val name: String,
@ColumnInfo(name = "created_at")
val createdAt: Long
)
@Dao
interface UserDao {
@Query("SELECT * FROM user ORDER BY name ASC")
suspend fun getAllUsers(): List<User>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: User)
@Query("DELETE FROM user WHERE id = :id")
suspend fun deleteUser(id: Long)
}
Room به طور خودکار پیادهسازی UserDao_Impl را تولید میکند که شامل پرسوجوهای زمان اجرا به SQLite از طریق RoomDatabase داخلی است. به دلیل کوروتینها (suspend)، روشهای DAO به طور ناهمگام در رشته پسزمینه اجرا شده و UI را بلوک نمیکنند. انواع بازگشتی Flow در @Query به طور خودکار نتیجه را در زمان تغییر جدول بهروز میکنند.
FMDB — پیچیدهسازی Objective-C بر روی C API SQLite، تاریخچان اولین کتابخانه محبوب برای iOS است. آن اشیای FMDatabase و FMResultSet را برای اجرای پرسوجوها و دریافت نتایج فراهم میکند. FMDB ساده و مینیمالیستی است، اما از ساختارهای مخصوص Swift — اپشنالها، Codable، async/await — پشتیبانی نمیکند.
GRDB — یک کتابخانه مدرن Swift برای کار با SQLite است. آن API با امنیت نوع، پشتیبانی از Codable، Combine Publishers، async/await، مهاجرتها و نظارت بر تغییرات در زمان واقعی را فراهم میکند. GRDB به دلیل یکپارچگی کامل با Swift Concurrency و خوانایی بهتر کد، برای پروژههای جدید در Swift ترجیح داده میشود.
GRDB جداول را از طریق کلاسهای Record مطابق با پروتکلهای FetchableRecord و TableRecord تعریف میکند. پرسوجوها با نحو امن از نظر نوع در Swift نوشته میشوند نه با SQL خام. GRDB همچنین از DatabaseMigrator برای نسخهبندی شما و مهاجرت بین نسخههای برنامه پشتیبانی میکند.
struct User: Codable, FetchableRecord, TableRecord {
var id: Int64
var name: String
var createdAt: Date
}
let dbPool = try DatabasePool(path: dbPath)
var migrator = DatabaseMigrator()
migrator.registerMigration("v1") { db in
try db.create(table: "user") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
t.column("createdAt", .datetime).notNull()
}
}
let users = try await dbPool.read { db in
try User.order(Column("name")).fetchAll(db)
}
DatabasePool از حالت WAL SQLite برای خواندن همزمان استفاده میکند. چندین خواننده میتوانند همزمان به پایگاه داده دسترسی داشته باشند در حالی که یک نویسنده از طریق WAL دادهها را بهروز میکند. GRDB اتصالات و تراکنشها را به طور خودکار مدیریت کرده و دسترسی ایمن به رشته را بدون همگامسازی دستی از هر رشتهای فراهم میکند.
اندکسها — موثرترین راه سرعت بخشیدن به پرسوجوهای SQLite. اندکس بر روی ستونهایی که در WHERE، JOIN و ORDER BY شرکت دارند ایجاد میشود. برای جدولی با 100 000 رکرد، جستجو در ستون اندکسشده به جای ثانیه ها در میلیثانیه انجام میشود. اما اندکسها INSERT و UPDATE را کند میکنند، بنابراین تعداد آنها باید با تعداد نوشتن متوازن باشد.
درج تودرمانی دستهای (batch insert) در چارچوب یک تراکنش بارگذاری انبوه داده را به طور اساسی سرعت میبخشد. درج 1000 رکرد به صورت تکتک حدود 1 ثانیه سرریار دارد. همین 1000 رکرد در یک تراکنش — حدود ۵–۱۰ میلیثانیه. این تفاوت به این دلیل است که هر INSERT جداگانه یک تراکنش جدید با نوشتن همگام روی دیسک ایجاد میکند.
PRAGMA — دستورات SQLite برای پیکربندی رفتار کتابخانه. PRAGMAهای کلیدی بهینهسازی: PRAGMA synchronous=NORMAL (کاهش دفعات fsync)، PRAGMA cache_size=-8000 (تخصیص 8 مگابایت کش)، PRAGMA temp_store=MEMORY (جداول موقت در حافظه). برای برنامههای موبایل با حجم زیاد داده، ترکیب این PRAGMAها پرسوجوها را 2–3 برابر سرعت میبخشد.
یک بهینهسازی مهم دیگر — کامپایل پیشفرض پرسوجوهای SQL (prepared statements). اگر پرسوجو چندین بار اجرا میشود (مثلاً درج 10 000 سطر)، کامپایل یکبار SQL و سپس استفاده از statement بار CPU را 30–50% کاهش میدهد. Room و GRDB به طور خودکار prepared statements را کش میکنند، اما در استفاده مستقیم از C API SQLite، کامپایل باید دستی انجام شود.
class UserRepository(private val db: RoomDatabase) {
suspend fun insertBatch(users: List<User>) {
db.withTransaction {
users.chunked(500).forEach { batch ->
batch.forEach { user ->
insertUser(user)
}
}
}
}
}
درج تودرمانی دستهای با withTransaction تضمین میدهد که همه INSERTها در چارچوب یک تراکنش اجرا شوند. تقسیم به زیردستهها (chunked) از ایجاد یک تراکنش خیلی بزرگ که میتواند سایر رشتهها را برای مدت طولانی بلوک کند جلوگیری میکند. برای همگامسازی پسزمینه، اندازه زیردسته 500 رکرد تعادل بهینهای از سرعت و واکنشگرایی UI را فراهم میکند.
سوالات متداول
بله، SQLite از دسترسی چند رشتهای در حالت WAL پشتیبانی میکند. چندین رشته میتوانند همزمان دادهها را بخوانند، اما فقط یکی میتواند بنویسد. Room و GRDB همگامسازی را به طور خودکار مدیریت میکنند. در حالت rollback journal (پیشفرض)، پایگاه داده در هر نوشتن کاملاً بلوک میشود.
محدودیت SQLite — 281 ترابایت (حداکثر نظری). در عمل، اندازه پایگاه داده به حافظه موجود دستگاه محدود میشود. برای برنامههای موبایل، اندازه مناسب تا ۱–۲ گیگابایت است. پایگاههای داده بزرگتر از ۲ گیگابایت پشتیبان گیری، بهروزرسانی از طریق App Store را کند کرده و مصرف حافظه RAM را افزایش میدهند.
SQLite دادهها را به صورت پیشفرض رمزگزاری نمیکند — هر فرآیندی که به فایل دسترسی داشته باشد میتواند آنها را بخواند. برای رمزگزاری از SQLCipher (افزونه با AES-256)، Room با EncryptedDatabase (Android) یا Encrypted Core Data در iOS استفاده کنید. رمزگزاری ۵–۱۵% سرریار بر خواندن و نوشتن دادهها اضافه میکند.
SQLite یک کتابخانه تودرمانی (embedded) است که نیازی به فرآیند سرور ندارد. MySQL یک سیستم مدیریت پایگاه داده مشتری-سرور با سرور جداگانه، کاربران، حقوق دسترسی و پروتکل شبکه است. SQLite پایگاه داده را در یک فایل ذخیره میکند، MySQL در چندین فایل مدیریتشده توسط سرور. SQLite سادهتر و سبکتر، MySQL قدرتمندتر و مقیاسپذیرتر است.
برای مهاجرت، از ALTER TABLE (افزودن ستون) یا ایجاد جدول جدید با انتقال دادهها و حذف جدول قدیمی استفاده کنید. Room این فرآیند را از طریق کلاسهای Migration خودکار میکند: startVersion، endVersion و پرسوجوهای SQL برای تغییر شما را مشخص کنید. GRDB و FMDB DatabaseMigrator مشابهی را ارائه میدهند.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید