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 في كل تطبيق — إما مباشرة أو من خلال أغلفة.
عدم الحاجة إلى تهيئة — لا تتطلب SQLite تثبيتاً أو إعداد صلاحيات أو إنشاء مستخدمين أو تشغيل خدمة. يتم ربط المكتبة بالمشروع، ويتم إنشاء قاعدة البيانات باستدعاء دالة واحدة. هذا يُبسّط النشر بشكل جذري مقارنة بأنظمة إدارة قواعد البيانات من نوع خادم-عميل التي تتطلب تثبيت الخادم وإعداد المنافذ وتكوين المستخدمين.
ملف قاعدة بيانات SQLite هو ملف عادي متعدد المنصات يمكن نسخه وتحليله وإرساله عبر الشبكة أو استعادته من نسخة احتياطية. تنسيق الملف مستقر على مستوى API: ملفات SQLite 3 التي تم إنشاؤها في عام 2004 تُفتح بالإصدار الحالي من المكتبة، مما يضمن توافق البيانات على المدى الطويل.
تتكون بنية SQLite من ثماني آلات افتراضية: Tokenizer و Parser و Code Generator و VM و B-Tree و Pager و OS Interface و Utilities. يمر استعلام SQL عبر Tokenizer (تقسيم إلى رموز) و Parser (بناء شجرة بناء الجملة) و 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. لتطبيقات المحمول ذات المزامنة الخلفية وخيط واجهة المستخدم الذي يقرأ البيانات في وقت واحد، يوفر WAL أداءً أفضل وغياباً لتجميد الواجهة.
SQLite ليست الخيار الوحيد للتخزين المحلي للبيانات، لكنها الأكثر تنوعاً. تقدم Realm سرعة أعلى للوصول المباشر إلى الكائنات في الذاكرة ولكنها تستخدم تنسيق NoSQL الخاص بها ولها حجم مكتبة أكبر. Core Data على iOS هي طبقة ORM فوق SQLite تُضيف إدارة الرسم البياني للكائنات وتراجع العمليات.
معظم التطبيقات، تظل SQLite الخيار الأمثل بفضل أدائها المتوقع وغياب تقييد البائع وثباتها المختبر عبر الزمن. تُبرر Realm و Core Data في المشاريع ذات الرسوم البيانية المعقدة للكائنات أو الاستعلامات التفاعلية أو متطلبات المزامنة عبر الأجهزة.
| الخاصية | SQLite | Realm | Core Data |
|---|---|---|---|
| نوع قاعدة البيانات | علائقية (SQL) | NoSQL (كائنية) | ORM (فوق SQLite) |
| حجم المكتبة | ~600 كيلوبايت | ~4 ميجابايت | مضمن في SDK أبل |
| الأداء | متوسط | عالٍ (كائنات في الذاكرة) | متوسط (تكلفة ORM) |
| المنصات | iOS, Android, ويب, سطح المكتب | iOS, Android, Node.js | iOS, macOS |
| تقييد البائع | لا يوجد (معيار مفتوح) | متوسط (تنسيق خاص) | عالي (أبل فقط) |
يعتمد الاختيار بين SQLite و Realm و Core Data على المنصة ومتطلبات نموذج الكائنات واستراتيجية المزامنة. للمشاريع متعددة المنصات (KMP, Flutter)، تظل SQLite الخيار العالمي الوحيد الذي يعمل على جميع المنصات المستهدفة بدون تغييرات في نموذج البيانات.
Room هي مكتبة من Android Jetpack توفر طبقة ORM فوق SQLite. تنشئ Room تلقائياً استعلامات SQL من واجهات DAO المُعلَّقة، وتتحقق من صحة الاستعلامات في وقت الترجمة، وتدعم ترحيل قاعدة البيانات عند تغيير المخطط. Room هي الطريقة الموصى بها للعمل مع SQLite على Android.
SQLiteOpenHelper هي واجهة برمجة تطبيقات منخفضة المستوى للإدارة المباشرة لـ 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 الداخلي. بفضل coroutines (suspend)، يتم تنفيذ طرق DAO بشكل غير متزامن على خيط خلفي دون حظر واجهة المستخدم. أنواع الإرجاع Flow في @Query تُحدّث النتيجة تلقائياً عند تغيير الجدول.
FMDB هي غلاف بلغة Objective-C حول واجهة C لـ SQLite، تاريخياً أول مكتبة شائعة لنظام iOS. توفر كائنات FMDatabase و FMResultSet لتنفيذ الاستعلامات والحصول على النتائج. FMDB بسيطة وحديثة، لكنها لا تدعم تراكيب Swift الخاصة — القيم الاختيارية، Codable، async/await.
GRDB هي مكتبة Swift حديثة للعمل مع SQLite. توفر واجهة برمجة تطبيقات آمنة من حيث النوع، ودعماً لـ Codable، و Combine Publishers، و async/await، والترحيلات، ومراقبة التغييرات في الوقت الفعلي. يُفضّل GRDB للمشاريع الجديدة على Swift بفضل تكامله الكامل مع Swift Concurrency وقابلية قراءة أفضل للكود.
يُعرِّف 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. لجدول يحتوي على 100000 سجل، يستغرق البحث بعمود مفهرس ميلي ثوانٍ بدلاً من ثوانٍ. ومع ذلك، تُبطئ الفهارس عمليات INSERT و UPDATE، لذلك يجب موازنة عددها مع تكرار الكتابة.
الإدراج بالدفعة (batch insert) ضمن معاملة واحدة يُسرّع تحميل البيانات بشكل جذري. إدراج 1000 سجل واحداً تلو الآخر يُحدث تكلفة إضافية تبلغ ~1 ثانية. نفس 1000 سجل في معاملة واحدة يستغرق ~5-10 ميلي ثانية. يُفسَّر الفرق بأن كل INSERT فردي يُنشئ معاملة جديدة مع كتابة متزامنة على القرص.
PRAGMA هي أوامر SQLite لتكوين سلوك المكتبة. براغمات التحسين الرئيسية: PRAGMA synchronous=NORMAL (يقلل تكرار fsync)، PRAGMA cache_size=-8000 (يخصص 8 ميجابايت مخبأ)، PRAGMA temp_store=MEMORY (الجداول المؤقتة في الذاكرة). لتطبيقات المحمول ذات أحجام البيانات الكبيرة، يُسرّع دمج هذه البراغمات الاستعلامات بمقدار 2-3 مرات.
تحسين مهم آخر هو التجميع المسبق لاستعلامات SQL (prepared statements). إذا تم تنفيذ استعلام بشكل متكرر (على سبيل المثال، إدراج 10000 صف)، فإن تجميع SQL مرة واحدة ثم إعادة استخدام العبارة يُقلل حمل وحدة المعالجة المركزية بنسبة 30-50%. تقوم Room و GRDB بتخزين prepared statements مؤقتاً تلقائياً، ولكن عند استخدام واجهة C لـ 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 سجل التوازن الأمثل بين السرعة واستجابة واجهة المستخدم.
الأسئلة الشائعة
نعم، تدعم SQLite الوصول متعدد الخيوط في وضع WAL. يمكن لخيوط متعددة قراءة البيانات في وقت واحد، ولكن يمكن لخيط واحد فقط الكتابة. تدير Room و GRDB المزامنة تلقائياً. في وضع rollback journal (الافتراضي)، يتم قفل قاعدة البيانات بالكامل أثناء أي عملية كتابة.
الحد لـ SQLite هو 281 تيرابايت (الحد الأقصى النظري). عملياً، حجم قاعدة البيانات محدود بالذاكرة المتاحة للجهاز. لتطبيقات المحمول، الحجم المريح يصل إلى 1-2 جيجابايت. قواعد البيانات الأكبر من 2 جيجابايت تُبطئ النسخ الاحتياطي وتحديثات App Store وتزيد من استهلاك RAM.
SQLite لا تُشفّر البيانات افتراضياً — أي عملية لديها حق الوصول إلى الملف يمكنها قراءتها. للتشفير، استخدم SQLCipher (إضافة مع AES-256) أو Room مع EncryptedDatabase (Android) أو Encrypted Core Data على iOS. يُضيف التشفير 5-15% تكلفة إضافية على عمليات قراءة وكتابة البيانات.
SQLite هي مكتبة مدمجة لا تتطلب عملية خادم. MySQL هو نظام إدارة قواعد بيانات من نوع خادم-عميل مع خادم منفصل ومستخدمين وحقوق وصول وبروتوكول شبكة. تخزّن SQLite قاعدة البيانات في ملف واحد؛ يخزّنها MySQL في عدة ملفات يديرها الخادم. SQLite أبسط وأخف؛ MySQL أقوى وأكثر قابلية للتوسع.
للـ ترحيل في SQLite، استخدم ALTER TABLE (إضافة أعمدة) أو أنشئ جدولاً جديداً مع نقل البيانات وحذف الجدول القديم. تُؤتمت Room هذه العملية من خلال فئات Migration: حدد startVersion و endVersion واستعلامات SQL لتغييرات المخطط. توفر GRDB و FMDB DatabaseMigrator مماثلة.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.