Realm هي قاعدة بيانات NoSQL كائنية التوجه للأجهزة المحمولة، تم تطويرها كبديل لـ SQLite وCore Data لنظامي iOS وAndroid. يتم تخزين البيانات بتنسيق خاص مع وصول مباشر إلى الكائنات في الذاكرة، مما يوفر سرعة عالية في القراءة والكتابة. بفضل الإشعارات التفاعلية، والمزامنة التلقائية عبر Realm Sync ونموذج البيانات عبر المنصات، يُستخدم Realm في أكثر من مليار جهاز (بيانات MongoDB، 2025).
الخلاصة
Realm هي قاعدة بيانات كائنية التوجه تم إنشاؤها خصيصاً للتطبيقات المحمولة. على عكس SQLite، لا تستخدم Realm SQL أو النموذج العلائقي — يتم تخزين البيانات ككائنات حية (Live Objects) يتم الوصول إليها مباشرة دون طبقة ORM وسيطة. يعمل المطور مع كائنات اللغة العادية (Swift، Kotlin، Dart) التي يتم حفظها تلقائياً في قاعدة البيانات.
ظهرت Realm في عام 2014 كشركة ناشئة Realm Inc.، وفي عام 2019 استحوذت عليها MongoDB Inc. منذ ذلك الحين، تم تطوير Realm باسم MongoDB Realm — كجزء من منصة Atlas Device Sync الموحدة لمزامنة البيانات المحمولة. تظل قاعدة البيانات المحلية الأساسية لـ Realm مجانية ومفتوحة المصدر (رخصة Apache 2.0)، بينما يتم توزيع Realm Sync (المزامنة السحابية) عبر الاشتراك.
وفقاً لتقرير MongoDB Developer Report (2025)، يُستخدم Realm في 15% من التطبيقات المحمولة كتخزين محلي أساسي. حالات الاستخدام الرئيسية هي التطبيقات ذات وضع عدم الاتصال، ونماذج الكائنات المعقدة، والحاجة إلى المزامنة بين الأجهزة، حيث يتفوق Realm على SQLite في سرعة التطوير وسهولة العمل مع الكائنات.
Live Objects — كل كائن Realm مرتبط بالقرص عبر ملف معين في الذاكرة (memory-mapped file). تغيير كائن في أي سلسلة ينعكس فوراً في جميع السلاسل الأخرى دون إشعار يدوي. تعاد واجهة المستخدم رسمياً تلقائياً عند تغير البيانات عبر إشعارات Realm. Zero-copy — لا تنسخ Realm البيانات من قاعدة البيانات إلى الكائنات؛ الكائنات هي البيانات في الذاكرة.
نواة Realm مكتوبة بلغة C++ وتستخدم B+ Tree لفهرسة البيانات. على عكس SQLite، حيث كل صف هو سجل في جدول علائقي، تخزن Realm الكائنات كعقد في بنية بيانية مع مراجع مباشرة بينها (forward pointers). العلاقات بين الكائنات ليست مفاتيح خارجية بل مؤشرات مباشرة، مما يلغي الحاجة إلى عمليات JOIN.
ملفات Realm (امتداد .realm) معينة في الذاكرة (memory-mapped) — نظام التشغيل نفسه يدير تحميل صفحات الملف إلى الذاكرة عند الوصول إليها. وهذا يسمح لـ Realm بالعمل مع قواعد بيانات أكبر من الذاكرة المتوفرة ويوفر زمن وصول للقراءة على مستوى هياكل البيانات الأصلية للغة (Swift Array أو Kotlin List) للبيانات التي تتسع في RAM.
الملفات المعينة في الذاكرة — التقنية الأساسية لـ Realm. بدلاً من نسخ البيانات من ملف قاعدة البيانات إلى كائنات اللغة (كما تفعل SQLite عبر sqlite3_step + sqlite3_column_*)، تعيّن Realm ملف قاعدة البيانات مباشرة في مساحة عنوان العملية. كائنات اللغة هي مجرد مؤشرات للبيانات في الذاكرة المعينة. تغيير كائن يعدل قاعدة البيانات على القرص دون استدعاء save منفصل.
| الخاصية | Realm (zero-copy) | SQLite (نسخ) |
|---|---|---|
| القراءة | وصول مباشر للذاكرة (نانوثانية) | نسخ إلى كائن (ميكروثانية) |
| الكتابة | كتابة فورية في ملف memory-mapped | save() مع معاملة SQL INSERT/UPDATE |
| العلاقات | مؤشرات مباشرة (forward pointers) | مفتاح خارجي + JOIN |
| استهلاك الذاكرة | ملف + ذاكرة تخزين مؤقت لصفحات OS | كائنات + ذاكرة تخزين مؤقت لصفحات SQLite |
| كائنات حية | نعم (تحديث تلقائي) | لا (يتطلب جلب جديد) |
استهلاك الذاكرة أعلى في Realm أثناء القراءة النشطة (الملف بأكمله أو جزء كبير منه معين في الذاكرة)، ولكنه أقل أثناء عمليات الكتابة حيث لا يلزم تخصيص ذاكرة لنسخ الكائنات. لقواعد بيانات حتى 1 جيجابايت على الأجهزة المحمولة، يوفر نهج memory-mapped أداءً عاماً أفضل من SQLite مع نسخه الوسيط.
SQLite هو نظام إدارة قواعد بيانات علائقي مع SQL ومعاملات ACID. Realm هي قاعدة بيانات NoSQL كائنية مع وصول memory-mapped. Core Data هي طبقة ORM من Apple فوق SQLite. لكل نهج من هذه النهج الثلاثة مجال تطبيقه ونقاط قوته. تتفوق Realm في سرعة الوصول المباشر إلى الكائنات والتفاعلية، وSQLite في التنوع والنضج، وCore Data في التكامل مع نظام Apple البيئي.
أداء القراءة لـ Realm أعلى بنسبة 10-50% من SQLite بفضل الوصول zero-copy. Realm أيضاً أسرع في الكتابة بسبب غياب تحليل SQL النحوي والتعديل المباشر لصفحات memory-mapped. ومع ذلك، قد تستهلك Realm ذاكرة RAM أكبر عند العمل مع قواعد بيانات كبيرة (>500 ميجابايت)، حيث يتم تعيين الملف بالكامل في مساحة العنوان.
| المعيار | Realm | SQLite | Core Data |
|---|---|---|---|
| النوع | قاعدة بيانات NoSQL كائنية | نظام إدارة قواعد بيانات علائقي (SQL) | ORM فوق SQLite |
| سرعة القراءة | عالية (zero-copy) | متوسطة | متوسطة (حمل ORM) |
| التفاعلية | Live Objects (مدمجة) | تحتاج غلاف (Room/GRDB) | NSFetchedResultsController |
| المزامنة | Realm Sync (MongoDB Atlas) | تتطلب تنفيذاً مخصصاً | NSPersistentCloudKitContainer |
| المنصات | iOS، Android، Flutter، RN، Node.js | iOS، Android، Web، سطح المكتب | iOS/macOS فقط |
| حجم المكتبة | ~4 ميجابايت | ~600 كيلوبايت | مدمج في SDK |
الاختيار بين Realm وSQLite غالباً ما يعود إلى الأولويات: سرعة التطوير والتفاعلية (Realm) مقابل التحكم والتنوع (SQLite). Realm جيدة بشكل خاص للنماذج الأولية (MVP) حيث يتغير نموذج البيانات بشكل متكرر ومن المهم الحصول على تحديثات حية لواجهة المستخدم بسرعة. SQLite/Room أفضل للمنتجات الناضجة ذات أحجام البيانات الكبيرة والاستعلامات التحليلية المعقدة.
Realm Kotlin SDK هي المكتبة الرسمية لنظام Android، مكتوبة بلغة Kotlin (ليست غلافاً فوق Java SDK). يتم تعريف نموذج البيانات عبر فئات ترث من RealmObject، مع التعليق @PrimaryKey للمعرف الفريد. يدعم Realm Kotlin كل من Kotlin Coroutines وFlow وKSP (Kotlin Symbol Processing) لتوليد الكود في وقت الترجمة.
RealmQuery يوفر واجهة برمجة تطبيقات type-safe للتصفية بدون SQL. يتم بناء الاستعلامات عبر سلسلة من الدوال: query → filter → sort → find. يمكن إرجاع النتيجة كقائمة (محملة في الذاكرة) أو كـ Flow (تيار تفاعلي يتم تحديثه عند تغير البيانات). يدعم Realm Kotlin أيضاً الكائنات المتداخلة والقوائم (RealmList).
نموذج البيانات يُعرف Realm كـ data class ينفذ واجهة RealmObject. حقل _id محدد بـ @PrimaryKey للتعريف الفريد. يتم تنفيذ علاقة واحد-إلى-متعدد عبر RealmList — قائمة من كائنات RealmObject الأخرى. جميع عمليات الكتابة (إنشاء، تحديث، حذف) تتم داخل كتلة معاملة write.
class Project : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var name: String = ""
var tasks: RealmList<Task> = realmListOf()
}
class Task : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId().generate()
var title: String = ""
var isComplete: Boolean = false
}
val config = Realm.Configuration.Builder(
schema = setOf(Project::class, Task::class)
).build()
val realm = Realm.open(config)
realm.write { transactionRealm ->
val project = copyToRealm(Project().apply {
name = "Mobile App"
})
project.tasks.add(copyToRealm(Task().apply {
title = "Design UI"
}))
}
val projects: Flow<RealmResults<Project>> =
realm.query<Project>()
.sort(Project::name, Sort.ASCENDING)
.asFlow()
استعلام يُرجع Flow يصدر تلقائياً نتائج جديدة عند أي تغيير في البيانات في Realm: إضافة أو تحديث أو حذف Project أو Task. يتناسب نهج Flow بشكل مثالي مع Compose: يقوم collectAsState() في ViewModel بإعادة تركيب واجهة المستخدم تلقائياً عند تغير البيانات دون تحديث يدوي لمحولات القوائم أو استخدام LiveData.
Realm Swift SDK يوفر واجهة برمجة تطبيقات Swift أصلية مع دعم async/await وCombine Publishers وSwift Concurrency. يتم تعريف نماذج البيانات كفئات ترث من Object، باستخدام @Persisted للخصائص. يقوم Realm Swift بتحديث الكائنات تلقائياً عند التغييرات، وتسمح الإشعارات (NotificationToken) بالاشتراك في تغييرات الكائنات أو المجموعات الفردية.
@ObservedRealmObject و @ObservedResults هما مغلفا خصائص (Property Wrappers) لـ SwiftUI يعيدان رسم العرض تلقائياً عند تغير بيانات Realm. @ObservedResults يعمل مع نتائج الاستعلام، @ObservedRealmObject يعمل مع كائن محدد. كلا الخاصيتين تلغيان الاشتراك عند إلغاء تهيئة العرض.
التكامل مع SwiftUI Realm هي إحدى نقاط القوة في SDK. Property Wrapper @ObservedResults يربط استعلام Realm بعرض SwiftUI. عندما تتغير أي مهمة، يعيد SwiftUI تركيب القائمة تلقائياً. realm.writeAsync ينفذ المعاملات في خيط خلفية دون حظر واجهة المستخدم.
import RealmSwift
class TaskItem: Object, Identifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var title: String = ""
@Persisted var isDone: Bool = false
@Persisted var priority: Int = 0
}
struct TaskListView: View {
@ObservedResults(TaskItem.self,
sortDescriptor: SortDescriptor(["priority"]))
var tasks
var body: some View {
List {
ForEach(tasks) { task in
TaskRow(task: task)
}
}
Button("Add Task") {
let realm = try! Realm()
try! realm.write {
realm.add(TaskItem(value: ["title": "New task"]))
}
}
}
}
@ObservedResults يدير تلقائياً دورة حياة استعلام Realm: عند إنشاء العرض، يتم إنشاء اشتراك للتغييرات؛ عند التدمير، يتم إلغاؤه. يقبل Property Wrapper مسنداً اختيارياً (NSPredicate) ووصف فرز. هذا يلغي الحاجة إلى كتابة استعلامات الجلب يدوياً، وإنشاء ViewModels والاشتراك في إشعارات Realm.
التطبيقات غير المتصلة — Realm مثالية للسيناريوهات حيث يجب أن تكون البيانات متاحة بدون إنترنت. المزامنة المدمجة (Realm Sync مع MongoDB Atlas) تحل التعارضات تلقائياً عند الاتصال بالشبكة. يستمر التطبيق في العمل مع البيانات المحلية، وتقوم المزامنة الخلفية بتحديثها عند توفر الاتصال.
الواجهات التفاعلية — Live Objects وإشعارات Flow/Combine تجعل Realm خياراً مناسباً للتطبيقات ذات البيانات المتغيرة باستمرار: الدردشات، خلاصات المهام، المستندات التعاونية. يتم تحديث واجهة المستخدم تلقائياً عند إضافة البيانات أو تغييرها أو حذفها دون استدعاء يدوي لـ reloadData أو invalidate.
المشاريع عبر المنصات — تدعم Realm كلاً من Kotlin Multiplatform (KMP) وFlutter وReact Native وXamarin. يتم تعريف نموذج البيانات مرة واحدة واستخدامه على جميع المنصات. هذا يقلل من تكرار الكود ويضمن اتساق المخطط بين تطبيقات iOS وAndroid ذات منطق الأعمال المشترك.
Realm Sync هي خدمة سحابية مدمجة في MongoDB Atlas. يقوم التطبيق بمزامنة البيانات تلقائياً بين أجهزة المستخدم والخادم. يتم حل التعارضات باستراتيجية "last write wins" أو عبر وظائف حل تعارضات مخصصة على الخادم. تدعم Realm Sync المزامنة الجزئية (مجموعة فرعية من البيانات) لتقليل حركة المرور.
class SyncRepository {
private val app = App(
AppConfiguration(
appId = "my-realm-app-id"
)
)
suspend fun syncData() {
val user = app.login(Credentials.anonymous())
val config = SyncConfiguration.Builder(
user, setOf(Project::class)
).build()
val syncedRealm = Realm.open(config)
// المزامنة التلقائية نشطة
}
}
SyncConfiguration يهيئ الاتصال بـ MongoDB Atlas ويحدد مجموعة النماذج المراد مزامنتها. بعد مصادقة المستخدم، يقوم Realm تلقائياً بتحميل البيانات من السحابة ودمجها مع التغييرات المحلية. تعمل المزامنة في خيط خلفية ولا تتطلب استدعاءات يدوية — فقط قم بإنشاء مثيل Realm مع SyncConfiguration.
الأسئلة الشائعة
نعم، قاعدة البيانات المحلية Realm مجانية تماماً (رخصة Apache 2.0). Realm Sync (المزامنة السحابية) عبر MongoDB Atlas هي خدمة مدفوعة ضمن اشتراك Atlas Device Sync. تشمل الطبقة المجانية من Atlas أول 500 ميجابايت من البيانات ومليون عملية شهرياً.
نعم، الترحيل ممكن عبر تصدير البيانات من SQLite إلى JSON واستيرادها إلى Realm عند أول تحميل للتطبيق. للأحجام الكبيرة، استخدم الترحيل التدفقي: اكتب البيانات في كلتا قاعدتي البيانات بالتوازي بينما ينتقل المستخدمون إلى إصدار التطبيق الجديد، ثم احذف ملف SQLite.
Realm Sync يستخدم افتراضياً استراتيجية "last write wins" — آخر كتابة تلغي السابقة. للتعارضات المعقدة، قم بتكوين وظائف حل تعارضات مخصصة على خادم MongoDB Atlas تدمج التغييرات من الأجهزة المختلفة وفقاً لمنطق الأعمال للتطبيق (على سبيل المثال، دمج القيم بدلاً من الاستبدال).
Realm لا يدعم تجميعات SQL (SUM، AVG، GROUP BY) على مستوى قاعدة البيانات. للاستعلامات التحليلية، يُنصح بتصدير البيانات من Realm إلى MongoDB Atlas عبر Realm Sync وتنفيذ التجميعات عبر MongoDB Aggregation Pipeline. للعد البسيط، استخدم realm.query<T>().count().
Realm لا يشفر البيانات افتراضياً. للتشفير، قم بتوفير مفتاح 64 بايت في الإعدادات: Realm.Configuration(encryptionKey: key). يستخدم التشفير AES-256 + SHA-2 HMAC ويزيد الحمل على العمليات بنسبة 10-20%. بدون تشفير، يمكن قراءة ملف .realm بواسطة أي عملية لديها وصول إلى نظام الملفات.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا