Realm في التطبيقات المحمولة: ما هو وكيف يعمل

المؤلف: IT Sectr نُشر: 2026-03-12 وقت القراءة: 11 دق

Realm هي قاعدة بيانات NoSQL كائنية التوجه للأجهزة المحمولة، تم تطويرها كبديل لـ SQLite وCore Data لنظامي iOS وAndroid. يتم تخزين البيانات بتنسيق خاص مع وصول مباشر إلى الكائنات في الذاكرة، مما يوفر سرعة عالية في القراءة والكتابة. بفضل الإشعارات التفاعلية، والمزامنة التلقائية عبر Realm Sync ونموذج البيانات عبر المنصات، يُستخدم Realm في أكثر من مليار جهاز (بيانات MongoDB، 2025).

الخلاصة

  • Realm هي قاعدة بيانات NoSQL كائنية للمنصات المحمولة مع وصول مباشر إلى البيانات في الذاكرة.
  • Live Objects — يتم تحديث كائنات Realm تلقائياً عند تغير البيانات دون إعادة تحميل يدوية.
  • Zero-copy — لا يتم نسخ البيانات بين طبقات التطبيق، مما يلغي الحمل الزائد لـ ORM.
  • Realm Sync — مزامنة مدمجة بين الأجهزة عبر MongoDB Atlas Device Sync.
  • عبر المنصات — يتم تعريف نموذج البيانات مرة واحدة لنظام iOS وAndroid وFlutter وReact Native.

ما هو Realm؟

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 في سرعة التطوير وسهولة العمل مع الكائنات.

مبادئ Realm

Live Objects — كل كائن Realm مرتبط بالقرص عبر ملف معين في الذاكرة (memory-mapped file). تغيير كائن في أي سلسلة ينعكس فوراً في جميع السلاسل الأخرى دون إشعار يدوي. تعاد واجهة المستخدم رسمياً تلقائياً عند تغير البيانات عبر إشعارات Realm. Zero-copy — لا تنسخ Realm البيانات من قاعدة البيانات إلى الكائنات؛ الكائنات هي البيانات في الذاكرة.

كيف يعمل Realm: البنية والتخزين

نواة Realm مكتوبة بلغة C++ وتستخدم B+ Tree لفهرسة البيانات. على عكس SQLite، حيث كل صف هو سجل في جدول علائقي، تخزن Realm الكائنات كعقد في بنية بيانية مع مراجع مباشرة بينها (forward pointers). العلاقات بين الكائنات ليست مفاتيح خارجية بل مؤشرات مباشرة، مما يلغي الحاجة إلى عمليات JOIN.

ملفات Realm (امتداد .realm) معينة في الذاكرة (memory-mapped) — نظام التشغيل نفسه يدير تحميل صفحات الملف إلى الذاكرة عند الوصول إليها. وهذا يسمح لـ Realm بالعمل مع قواعد بيانات أكبر من الذاكرة المتوفرة ويوفر زمن وصول للقراءة على مستوى هياكل البيانات الأصلية للغة (Swift Array أو Kotlin List) للبيانات التي تتسع في RAM.

Zero-copy و Live Objects

الملفات المعينة في الذاكرة — التقنية الأساسية لـ Realm. بدلاً من نسخ البيانات من ملف قاعدة البيانات إلى كائنات اللغة (كما تفعل SQLite عبر sqlite3_step + sqlite3_column_*)، تعيّن Realm ملف قاعدة البيانات مباشرة في مساحة عنوان العملية. كائنات اللغة هي مجرد مؤشرات للبيانات في الذاكرة المعينة. تغيير كائن يعدل قاعدة البيانات على القرص دون استدعاء save منفصل.

الخاصيةRealm (zero-copy)SQLite (نسخ)
القراءةوصول مباشر للذاكرة (نانوثانية)نسخ إلى كائن (ميكروثانية)
الكتابةكتابة فورية في ملف memory-mappedsave() مع معاملة SQL INSERT/UPDATE
العلاقاتمؤشرات مباشرة (forward pointers)مفتاح خارجي + JOIN
استهلاك الذاكرةملف + ذاكرة تخزين مؤقت لصفحات OSكائنات + ذاكرة تخزين مؤقت لصفحات SQLite
كائنات حيةنعم (تحديث تلقائي)لا (يتطلب جلب جديد)

استهلاك الذاكرة أعلى في Realm أثناء القراءة النشطة (الملف بأكمله أو جزء كبير منه معين في الذاكرة)، ولكنه أقل أثناء عمليات الكتابة حيث لا يلزم تخصيص ذاكرة لنسخ الكائنات. لقواعد بيانات حتى 1 جيجابايت على الأجهزة المحمولة، يوفر نهج memory-mapped أداءً عاماً أفضل من SQLite مع نسخه الوسيط.

Realm مقابل SQLite مقابل Core Data: مقارنة

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 ميجابايت)، حيث يتم تعيين الملف بالكامل في مساحة العنوان.

المعيارRealmSQLiteCore Data
النوعقاعدة بيانات NoSQL كائنيةنظام إدارة قواعد بيانات علائقي (SQL)ORM فوق SQLite
سرعة القراءةعالية (zero-copy)متوسطةمتوسطة (حمل ORM)
التفاعليةLive Objects (مدمجة)تحتاج غلاف (Room/GRDB)NSFetchedResultsController
المزامنةRealm Sync (MongoDB Atlas)تتطلب تنفيذاً مخصصاًNSPersistentCloudKitContainer
المنصاتiOS، Android، Flutter، RN، Node.jsiOS، Android، Web، سطح المكتبiOS/macOS فقط
حجم المكتبة~4 ميجابايت~600 كيلوبايتمدمج في SDK

الاختيار بين Realm وSQLite غالباً ما يعود إلى الأولويات: سرعة التطوير والتفاعلية (Realm) مقابل التحكم والتنوع (SQLite). Realm جيدة بشكل خاص للنماذج الأولية (MVP) حيث يتغير نموذج البيانات بشكل متكرر ومن المهم الحصول على تحديثات حية لواجهة المستخدم بسرعة. SQLite/Room أفضل للمنتجات الناضجة ذات أحجام البيانات الكبيرة والاستعلامات التحليلية المعقدة.

Realm على Android: Kotlin SDK

Realm Kotlin SDK هي المكتبة الرسمية لنظام Android، مكتوبة بلغة Kotlin (ليست غلافاً فوق Java SDK). يتم تعريف نموذج البيانات عبر فئات ترث من RealmObject، مع التعليق @PrimaryKey للمعرف الفريد. يدعم Realm Kotlin كل من Kotlin Coroutines وFlow وKSP (Kotlin Symbol Processing) لتوليد الكود في وقت الترجمة.

RealmQuery يوفر واجهة برمجة تطبيقات type-safe للتصفية بدون SQL. يتم بناء الاستعلامات عبر سلسلة من الدوال: queryfiltersortfind. يمكن إرجاع النتيجة كقائمة (محملة في الذاكرة) أو كـ Flow (تيار تفاعلي يتم تحديثه عند تغير البيانات). يدعم Realm Kotlin أيضاً الكائنات المتداخلة والقوائم (RealmList).

مثال على Realm Kotlin SDK

نموذج البيانات يُعرف Realm كـ data class ينفذ واجهة RealmObject. حقل _id محدد بـ @PrimaryKey للتعريف الفريد. يتم تنفيذ علاقة واحد-إلى-متعدد عبر RealmList — قائمة من كائنات RealmObject الأخرى. جميع عمليات الكتابة (إنشاء، تحديث، حذف) تتم داخل كتلة معاملة write.

kotlin
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 على iOS: Swift SDK

Realm Swift SDK يوفر واجهة برمجة تطبيقات Swift أصلية مع دعم async/await وCombine Publishers وSwift Concurrency. يتم تعريف نماذج البيانات كفئات ترث من Object، باستخدام @Persisted للخصائص. يقوم Realm Swift بتحديث الكائنات تلقائياً عند التغييرات، وتسمح الإشعارات (NotificationToken) بالاشتراك في تغييرات الكائنات أو المجموعات الفردية.

@ObservedRealmObject و @ObservedResults هما مغلفا خصائص (Property Wrappers) لـ SwiftUI يعيدان رسم العرض تلقائياً عند تغير بيانات Realm. @ObservedResults يعمل مع نتائج الاستعلام، @ObservedRealmObject يعمل مع كائن محدد. كلا الخاصيتين تلغيان الاشتراك عند إلغاء تهيئة العرض.

مثال على Realm Swift SDK

التكامل مع SwiftUI Realm هي إحدى نقاط القوة في SDK. Property Wrapper @ObservedResults يربط استعلام Realm بعرض SwiftUI. عندما تتغير أي مهمة، يعيد SwiftUI تركيب القائمة تلقائياً. realm.writeAsync ينفذ المعاملات في خيط خلفية دون حظر واجهة المستخدم.

swift
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 مثالية للسيناريوهات حيث يجب أن تكون البيانات متاحة بدون إنترنت. المزامنة المدمجة (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

Realm Sync هي خدمة سحابية مدمجة في MongoDB Atlas. يقوم التطبيق بمزامنة البيانات تلقائياً بين أجهزة المستخدم والخادم. يتم حل التعارضات باستراتيجية "last write wins" أو عبر وظائف حل تعارضات مخصصة على الخادم. تدعم Realm Sync المزامنة الجزئية (مجموعة فرعية من البيانات) لتقليل حركة المرور.

kotlin
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 مجاني للاستخدام التجاري؟

نعم، قاعدة البيانات المحلية Realm مجانية تماماً (رخصة Apache 2.0). Realm Sync (المزامنة السحابية) عبر MongoDB Atlas هي خدمة مدفوعة ضمن اشتراك Atlas Device Sync. تشمل الطبقة المجانية من Atlas أول 500 ميجابايت من البيانات ومليون عملية شهرياً.

هل يمكن الترحيل من SQLite إلى Realm؟

نعم، الترحيل ممكن عبر تصدير البيانات من SQLite إلى JSON واستيرادها إلى Realm عند أول تحميل للتطبيق. للأحجام الكبيرة، استخدم الترحيل التدفقي: اكتب البيانات في كلتا قاعدتي البيانات بالتوازي بينما ينتقل المستخدمون إلى إصدار التطبيق الجديد، ثم احذف ملف SQLite.

كيف يتعامل Realm مع تعارضات المزامنة؟

Realm Sync يستخدم افتراضياً استراتيجية "last write wins" — آخر كتابة تلغي السابقة. للتعارضات المعقدة، قم بتكوين وظائف حل تعارضات مخصصة على خادم MongoDB Atlas تدمج التغييرات من الأجهزة المختلفة وفقاً لمنطق الأعمال للتطبيق (على سبيل المثال، دمج القيم بدلاً من الاستبدال).

هل يدعم Realm استعلامات التجميع؟

Realm لا يدعم تجميعات SQL (SUM، AVG، GROUP BY) على مستوى قاعدة البيانات. للاستعلامات التحليلية، يُنصح بتصدير البيانات من Realm إلى MongoDB Atlas عبر Realm Sync وتنفيذ التجميعات عبر MongoDB Aggregation Pipeline. للعد البسيط، استخدم realm.query<T>().count().

هل بيانات Realm آمنة؟

Realm لا يشفر البيانات افتراضياً. للتشفير، قم بتوفير مفتاح 64 بايت في الإعدادات: Realm.Configuration(encryptionKey: key). يستخدم التشفير AES-256 + SHA-2 HMAC ويزيد الحمل على العمليات بنسبة 10-20%. بدون تشفير، يمكن قراءة ملف .realm بواسطة أي عملية لديها وصول إلى نظام الملفات.

الملخص

  • Realm هي قاعدة بيانات NoSQL كائنية التوجه مع وصول memory-mapped وكائنات حية ونموذج بيانات عبر المنصات للتطبيقات المحمولة.
  • بنية Zero-copy تسمح بقراءة البيانات مباشرة من ملف معين في الذاكرة دون نسخ إلى كائنات اللغة، مما يجعل Realm أسرع بنسبة 10-50% من SQLite في القراءة.
  • Live Objects و @ObservedResults (SwiftUI) / Flow (Kotlin) توفر تحديثات تلقائية لواجهة المستخدم عند تغير البيانات دون استعلامات يدوية لقاعدة البيانات.
  • Realm Sync مع MongoDB Atlas يوفر مزامنة سحابية مدمجة مع حل التعارضات باستراتيجية "last write wins".
  • SDK عبر المنصات تدعم Kotlin Multiplatform وFlutter وReact Native — يتم تعريف نموذج البيانات مرة واحدة لجميع المنصات.
  • للاستعلامات التحليلية Realm أقل من SQLite بسبب عدم وجود تجميعات جماعية — التقارير المعقدة تُنفذ عبر MongoDB Aggregation Pipeline.
  • توصية — استخدم Realm للتطبيقات غير المتصلة مع تحديثات متكررة لواجهة المستخدم والحاجة إلى مزامنة عبر المنصات، وSQLite/Room للمشاريع ذات التحليلات ومجموعات البيانات المستقرة.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا