ObjectBox е високопроизводителна NoSQL база данни, оптимизирана за мобилни и edge устройства. За разлика от SQLite, тя използва собствен формат за съхранение, базиран на плоски файлове без SQL слой. Според ObjectBox Benchmarks, 2024, ObjectBox изпълнява операции по вмъкване и четене 10–100 пъти по-бързо от SQLite на Android устройства, което го прави най-добрият избор за високонатоварени мобилни приложения.
Основни точки
ObjectBox е in-memory NoSQL база данни, разработена от немската компания ObjectBox.io. За разлика от традиционните релационни бази данни, ObjectBox съхранява обекти директно в плоски файлове, използвайки собствен SLOT (Super Lightweight Object Tree) формат. Това елиминира допълнителната тежест на ORM и SQL парсера. SLOT форматът е оптимизиран за работа на устройства с ограничена памет: данните се дефрагментират автоматично, а размерът на базата данни е средно 4–6 пъти по-малък от еквивалентна SQLite база със същия брой записи.
ObjectBox поддържа всички основни мобилни платформи: Android, iOS и Flutter. За Android е достъпно генериране на код чрез ObjectBox Gradle Plugin, който обработва анотирани обекти и създава Box класове за работа с данни. За Flutter се използва native плъгин с Dart обвивка. Освен мобилни платформи, ObjectBox работи на Linux, macOS, Windows и WebAssembly, позволявайки повторно използване на модела данни между мобилното приложение и сървърната синхронизация.
Според данни от изследване на ObjectBox (2023), базата данни се използва в над 5000 приложения в Google Play, включително приложения с аудитория над 10 милиона потребители. Основни сценарии: кеширане на данни, работа в офлайн режим и съхранение на времеви редове (IoT). ObjectBox е особено популярен в приложения за проследяване на здравето и фитнес, където се изисква бързо записване на показания от сензори на устройството без постоянна интернет връзка и събиране на аналитика от няколко устройства.
ObjectBox се появи като алтернатива на Realm и SQLite за платформата Android. Първата стабилна версия беше пусната през 2018 г. Ключова разлика от Realm — ObjectBox няма GPL ограничения (използва Apache 2.0) и поддържа повече платформи: от мобилни устройства до Linux сървъри.
ObjectBox предоставя: автоматично генериране на Box класове, вградени индекси за бързо търсене, транзакции с поддръжка на отмяна, реактивни заявки чрез RxJava и Kotlin Flow, както и синхронизация между устройства чрез ObjectBox Sync (собствен протокол). За разлика от Firebase Realtime Database, ObjectBox Sync работи в peer-to-peer модел без централен сървър, което намалява закъсненията и разходите за инфраструктура.
ObjectBox съхранява данни в собствен двоичен .mdb (ObjectBox Data File) формат. Всеки обект (Entity) се картографира към един файл, където записите се съхраняват последователно с фиксирано отместване. Това позволява четене и запис на отделни обекти без пълно сканиране на файла.
За работа с ObjectBox не е необходим SQL: заявките се изграждат чрез fluent-API в кода. Компилаторът генерира помощни класове MyObjectBox и кутии (Box), които капсулират всички CRUD операции. Моделът данни се описва чрез анотации @Entity, @Id, @Index и @Relation.
// Свързване на ObjectBox в Android
class App: Application() {
lateinit var boxStore: BoxStore
override fun onCreate() {
super.onCreate()
boxStore = MyObjectBox.builder()
.androidContext(this)
.build()
}
}
Според официални бенчмаркове, ObjectBox значително превъзхожда SQLite по скорост на операциите, особено при пакетно вмъкване и масово четене. Въпреки това, SQLite остава де факто стандарт за мобилни приложения благодарение на разпространението си и вградената поддръжка на SQL.
| Операция | ObjectBox | SQLite | Разлика |
|---|---|---|---|
| Вмъкване (1000 записа) | ~5 ms | ~180 ms | x36 по-бързо |
| Четене (1000 записа) | ~3 ms | ~70 ms | x23 по-бързо |
| Актуализиране (1000 записа) | ~6 ms | ~150 ms | x25 по-бързо |
| Търсене по индекс | ~0.1 ms | ~2 ms | x20 по-бързо |
| Размер на базата (1000 обекта) | ~28 KB | ~112 KB | 4 пъти по-малък |
ObjectBox губи от SQLite в сценарии, където са необходими сложни JOIN заявки, агрегатни функции (SUM, COUNT с групиране) или интеграция със съществуваща SQL схема. Ако проектът вече използва SQLite с Room ORM, миграцията към ObjectBox ще изисква пренаписване на цялата логика за достъп до данни. ObjectBox също не поддържа персонализирани SQL заявки — само fluent-API. Въпреки това, за типични CRUD операции и кеширане, ObjectBox дава увеличение на производителността до 100 пъти, което се потвърждава от официални бенчмаркове на Android устройства с различни версии на ОС.
ObjectBox използва анотации за дефиниране на обекти. След компилация се създават Box класове с методи put, get, remove и query. По-долу са показани типични операции за модела Task в приложение за списък със задачи.
Всеки обект се анотира с @Entity. Полето с @Id става първичен ключ, @Index ускорява търсенето по поле. ObjectBox поддържа автоматично генериране на ID при стойност 0.
@Entity
data class Task(
@Id var id: Long = 0,
@Index var title: String = "",
var isCompleted: Boolean = false,
var priority: Int = 0
)
Box е основният клас за работа с обекти. Методът put() запазва или актуализира обекта, get() чете по ID, remove() изтрива. Всички основни операции са синхронни и се изпълняват в извикващата нишка.
val taskBox: Box<Task> = boxStore.boxFor(Task::class.java)
// Създаване
val task = Task(title = "Купуване на продукти", priority = 3)
val newId = taskBox.put(task)
// Четене
val savedTask = taskBox.get(newId)
// Актуализиране
savedTask.isCompleted = true
taskBox.put(savedTask)
// Изтриване
taskBox.remove(newId)
ObjectBox поддържа реактивни заявки чрез .subscribe(). Абонатът получава известия при всяка промяна на данни, които отговарят на условието на заявката. Това е удобно за UI, който автоматично актуализира списъка при добавяне или премахване на елементи.
val query = taskBox.query()
.equal(Task_.isCompleted, false)
.orderDesc(Task_.priority)
.build()
query.subscribe { tasks ->
// tasks — List, обновляется автоматически
updateUi(tasks)
}
ObjectBox поддържа връзки между обекти — To-One, To-Many и Many-to-Many. Връзките се задават чрез анотация @Relation. За разлика от SQLite, ObjectBox не използва външни ключове: връзките са реализирани чрез списъци от ID в плоски файлове, което ускорява навигацията по графа от обекти.
Връзката @Backlink позволява преминаване от дъщерен обект към родителски без отделно поле за препратка. ObjectBox автоматично поддържа обратната препратка, което елиминира дублирането на данни и синхронизацията между две таблици.
ObjectBox Query Builder позволява изграждане на вериги от условия: equal, notEqual, greater, less, in, contains, startsWith. Всички условия се комбинират чрез and/or. Резултатът може да бъде сортиран, ограничен и получен като List или LazyList (за големи набори от данни).
ObjectBox автоматично индексира полето @Id. За персонализирани индекси използвайте анотация @Index на полета, по които често се правят заявки. Индексите ускоряват equal и in заявки, но забавят вмъкването — не индексирайте полета, по които не се търси. ObjectBox поддържа съставни индекси за едновременно филтриране по няколко полета. Комбинираните индекси са особено полезни за филтри в списъци: например, търсенето на незавършени задачи с висок приоритет се изпълнява десетки пъти по-бързо със съставен индекс по полетата isCompleted и priority.
ObjectBox Sync — собствена технология за синхронизация на данни между устройства в реално време. Тя използва протокол, базиран на WebSocket, с разрешаване на конфликти по last-writer-wins. Sync е подходящ за приложения, които се нуждаят от офлайн синхронизация: бележки, списъци със задачи, IoT данни от множество сензори. Въпреки това, за продукция е необходима покупка на лиценз.
// Заявка с няколко условия
val highPriorityIncomplete = taskBox.query()
.greater(Task_.priority, 5)
.equal(Task_.isCompleted, false)
.build()
.find()
// Търсене по подниз
val searchResults = taskBox.query()
.contains(Task_.title, "продукт", StringOrder.CASE_INSENSITIVE)
.build()
.find()
Често задавани въпроси
ObjectBox се разпространява под лиценз Apache 2.0, който позволява комерсиална употреба без ограничения. Функцията ObjectBox Sync (крос-платформена синхронизация) е собствена и изисква закупуване на лиценз за продукция.
BoxStore е нишково безопасен: множество нишки могат едновременно да четат данни. Записът се блокира на ниво Box. За сложни транзакции използвайте boxStore.runInTx(), който гарантира атомарност на група операции.
Да, ObjectBox поддържа Kotlin Multiplatform (KMP) от версия 3.0. Налични са target-и Android, iOS, JVM и Native. За KMP се използва отделен Gradle plugin objectbox-kotlin с поддръжка на expect/actual.
ObjectBox съхранява данни в .mdb файлове в директорията на приложението. За резервно копие копирайте цялата директория ObjectBox чрез BoxStore.copy() или ръчно след извикване на boxStore.close(). Живи файлове не могат да се копират — това ще повреди данните.
Room е ORM върху SQLite, изисква SQL заявки и има допълнителна тежест за картографиране на обекти. ObjectBox е NoSQL без SQL, значително по-бърз, но не поддържа сложни JOIN и не е релационна база данни. Изборът зависи от задачата: за релационни данни — Room, за бързо обектно съхранение — ObjectBox.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също