SQLite у мобилном развоју: шта је то и како ради

Аутор: IT Sectr Објављено: 2026-03-11 Време читања: 10 мин

SQLite је уграђена релациона база података која ради без одвојеног серверског процеса и чува целу базу у једној датотеци на уређају. Захваљујући нултој конфигурацији, малој величини библиотеке и пуној подршци за SQL, SQLite је постала стандард за локално складиштење података у мобилним апликацијама. Према подацима SQLite Consortium (2025), овај СБПЗ се користи у преко 4 милијарде уређаја, укључујући сваки паметни телефон на iOS и Android-у.

Главно

  • SQLite — уграђена релациона СБПЗ са нултоом конфигурацијом и чувањем података у једној датотеци.
  • ACID транзакције — гарантују интегритет података чак и при нестанку струје или паду апликације.
  • Типизација података — динамичка: SQLite не захтева строго навођење типа колоне при креирању табеле.
  • Room — ORM библиотека за Android која поједностављуће рад са SQLite кроз DAO и анотације.
  • CoreData може да користи SQLite као Persistent Store на iOS-у, али додаје слој за управљање објектима.

Шта је SQLite?

SQLite је библиотека у језику C која имплементира релациони СБПЗ без издвојеног сервера. Уграђује се директно у апликацију, чита и пише податке у обичној датотеци на фајл систему уређаја. Величина библиотеке је око 600 KB, што чини SQLite најлакшом потпуно функционалном SQL базом података.

SQLite подржава већи део стандарда SQL:1999, укључујући JOIN, подупите, окидаче, погледе, индексе и прозорске функције. Ограничења се односе на ALTER TABLE (ограничена подршка) и пуне RIGHT/FULL OUTER JOIN. Ипак, за мобилне апликације функционалност SQLite је довољна у 99% случајева локалног складиштења.

Према анкети програмера са Stack Overflow (2025), SQLite је најпопуларнија база података за уграђена решења и заузима треће место по популарности међу свим СБПЗ после MySQL и PostgreSQL. У мобилном развоју, SQLite се користи у свакој апликацији — директно или кроз омотаче.

Кључне карактеристике SQLite

Zero-configuration — SQLite не захтева инсталацију, подешавање дозвола, креирање корисника или покретање сервиса. Библиотека се повезује са пројектом, а база података се креира позивањем једне функције. То коренито поједностављуће постављање у поређењу са клијент-сервер СБПЗ, које захтевају инсталацију сервера, конфигурацију портова и конфигурацију корисника.

Датотека базе података SQLite је обична вишеплатформна датотека која се може копирати, анализирати, послати путем мреже или вратити из резервне копије. Формат датотеке је стабилан на нивоу API-ја: датотеке SQLite 3 креиране 2004. године отварају се тренутном верзијом библиотеке, што гарантује дугорочну компатибилност података.

Како је SQLite структуриран: архитектура и складиште

Архитектура 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 JournalWAL (Write-Ahead Logging)
Читање током писањаБлокира сеДозвољено (чита старе податке)
Перформанса писањаСредњаВисока (секвенцијални упис у WAL)
Потрошња дискаМања (само дневник повлачења)Већа (WAL + главна база)
Опоравак након квараПовлачење на последњу контролну тачкуОпоравак из WAL-а (подаци се не губе)
ПрепорукаЗа једнонитне сценаријеЗа типичне мобилне апликације

Пребацивање између режима врши се једним SQL упитом: PRAGMA journal_mode=WAL. За мобилне апликације са позадинском синхронизацијом и UI нити која истовремено чита податке, WAL пружа бољу перформансу и одсуство блокирања интерфејса.

SQLite напрам другим базама података у мобилном развоју

SQLite није једина опција за локално складиште података, али је најуниверзалнија. Realm нуди већу брзину директног приступа објектима у меморији, али користи сопствени NoSQL формат и има већу величину библиотеке. Core Data на iOS-у је ORM слој изнад SQLite-а који додаје управљање графом објеката и поништавање операција.

За већину апликација, SQLite остаје оптималан избор захваљујући предвидивој перформанси, нултом зависношчу од произвођача и временски тестираном стабилношчу. Realm и Core Data су оправдани у пројектима са сложеним графовима објеката, реактивним упитима или захтевима за синхронизацију између уређаја.

КарактеристикаSQLiteRealmCore Data
Тип базеРелациона (SQL)NoSQL (објектна)ORM (изнад SQLite)
Величина библиотеке~600 KB~4 MBУграђена у Apple SDK
ПерформансаСредњаВисока (објекти у меморији)Средња (надометак ORM)
ПлатформеiOS, Android, Web, DesktopiOS, Android, Node.jsiOS, macOS
Зависност од произвођачаНема (отворен стандард)Средња (сопствени формат)Велика (само Apple)

Избор између SQLite, Realm и Core Data зависи од платформе, захтева за моделом објеката и стратегије синхронизације. За вишеплатформне пројекте (KMP, Flutter) SQLite остаје једини универзалан избор који ради на свим циљаним платформама без промена у моделу података.

SQLite на Android-у: Room и SQLiteOpenHelper

Room — библиотека из Android Jetpack која пружа ORM слој изнад SQLite-а. Room аутоматски генерише SQL упите из анотираних DAO интерфејса, проверава исправност упита у фази компилације и подржава миграције базе података при промени шеме. Room је препоручени начин рада са SQLite на Android-у.

SQLiteOpenHelper — нисконивоаски API за директно управљање SQLite-ом без ORM-а. Класа управља креирањем, отварањем и ажурирањем базе података. SQLiteOpenHelper је погодан за пројекте са једноставним SQL упитима или када је потребна пуна контрола над SQL логиком без апстракције Room-а.

Примјер ентитета и DAO за Room

Ентитет у Room-у је анотиран са @Entity, а DAO са @Dao. Room претвара анотиране методе у SQL упите: @Insert генерише INSERT, @Query — SELECT са наведеним SQL. Миграције се додају кроз Migration са навођењем старе и нове верзије шеме. Room проверава SQL у фази компилације, што елиминише синтаксне грешке у производњи.

kotlin
@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 аутоматски ажурирају резултат при промени табеле.

SQLite на iOS-у: FMDB и GRDB

FMDB — Objective-C омотач изнад SQLite C API-ја, историјски прва популарна библиотека за iOS. Пружа објекте FMDatabase и FMResultSet за извршавање упита и добијање резултата. FMDB је једноставна и минималистична, али не подржава Swift-специфичне конструкције — опционале, Codable, async/await.

GRDB — савремена Swift библиотека за рад са SQLite-ом. Пружа type-safe API, подршку за Codable, Combine Publishers, async/await, миграције и праћење промена у реалном времену. GRDB је пожељна за нове пројекте у Swift-у због пуне интеграције са Swift Concurrency и боље читљивости кода.

Примјер GRDB у Swift-у

GRDB дефинише табеле кроз Record класе који испуњавају протоколе FetchableRecord и TableRecord. Упити се пишу у Swift-у са type-safe синтаксом, а не сировим SQL-ом. GRDB такође подржава DatabaseMigrator за верзионирање шеме и миграције између верзија апликације.

swift
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

Индекси — најефикаснији начин убрзавања SQLite упита. Индекс се креира на колонама које учествују у WHERE, JOIN и ORDER BY. За табелу са 100 000 записа, претрага по индексираној колони траје милисекунде уместо секунди. Међутим, индекси успоравају INSERT и UPDATE, па њихов број треба да буде уравнотежен са учесталошћу писања.

Шаржно уметање (batch insert) у оквиру једне транзакције коренито убрзава масовно учитавање података. Уметање 1000 записа један по један даје додатни трошак око 1 секунде. Истих 1000 записа у једној транзакцији — око 5–10 милисекунди. Разлика се објашњава чињеницом да сваки појединачни INSERT ствара нову транзакцију са синхроним уписом на диск.

Прагме перформансе

PRAGMA — SQLite команде за подешавање понашања библиотеке. Кључне оптимизационе прагме: PRAGMA synchronous=NORMAL (смањује учесталост fsync), PRAGMA cache_size=-8000 (издваја 8 MB кеша), PRAGMA temp_store=MEMORY (привремене табеле у меморији). За мобилне апликације са великим количинама података, комбинација ових прагми убрзава упите 2–3 пута.

Још једна важна оптимизација је претходна компилација SQL упита (prepared statements). Ако се упит вишеструко извршава (нпр. уметање 10 000 редова), компилација SQL-а једном и затим коришћење statement-а смањује оптерећење CPU-а за 30–50%. Room и GRDB аутоматски кеширају prepared statements, али при директном коришћењу SQLite C API-ја, компилацију треба извршити ручно.

kotlin
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 користити на више нити?

Да, SQLite подржава вишенитни приступ у WAL режиму. Више нити могу истовремено да читају податке, али само једна може да пише. Room и GRDB аутоматски управљају синхронизацијом. У rollback journal режиму (подразумевано), база је потпуно блокирана при сваком запису.

Која је максимална величина SQLite базе на мобилном уређају?

Ограничење SQLite-а — 281 TB (теоретски максимум). У пракси, величина базе је ограничена доступном меморијом уређаја. За мобилне апликације, комфортна величина је до 1–2 GB. Базе веће од 2 GB успоравају резервно копирање, ажурирање кроз App Store и повећавају потрошњу RAM-а.

Да ли су подаци у SQLite-у безбедни?

SQLite не шифрује податке подразумевано — сваки процес са приступом датотеци може да их чита. За шифрирање користите SQLCipher (проширење са AES-256), Room са EncryptedDatabase (Android) или Encrypted Core Data на iOS-у. Шифрирање додаје 5–15% додатног оптерећења при читању и писању података.

По чему се SQLite разликује од MySQL-а?

SQLite је уграђена (embedded) библиотека која не захтева серверски процес. MySQL је клијент-сервер СБПЗ са одвојеним сервером, корисницима, правима приступа и мрежним протоколом. SQLite чува базу у једној датотеци, MySQL у више датотека којима управља сервер. SQLite је једноставнија и лакша, MySQL јача и може да се скалира.

Како ажурирати шему SQLite-а без губитка података?

За миграцију користите ALTER TABLE (додавање колона) или креирање нове табеле са преносом података и брисањем старе. Room аутоматизује овај процес кроз Migration класе: наведите startVersion, endVersion и SQL упите за измену шеме. GRDB и FMDB пружају сличне DatabaseMigrator.

Закључак

  • SQLite — уграђена релациона СБПЗ са нултоом конфигурацијом, која се користи у свакој мобилној апликацији на iOS и Android-у за локално складиште података.
  • ACID транзакције и WAL режим обезбеђују интегритет података и конкурентни приступ из више нити апликације.
  • Room (Android) и GRDB (iOS) — савремени омотачи за SQLite који поједностављућу рад са базом кроз type-safe API и аутоматске миграције.
  • B-Tree архитектура SQLite-а омогућава ефикасно претраживање путем индекса, а шаржне транзакције и prepared statements високу перформансу писања.
  • SQLite надмашује Realm и Core Data по универзалности (све платформе), величини библиотеке и непостојању зависности од произвођача.
  • Оптимизација кроз индексе, WAL режим и PRAGMA подешавања убрзава упите 2–3 пута при типичним мобилним оптерећењима.
  • Препорука — користите SQLite као примарно складиште за локалне податке мобилне апликације путем Room-а на Android-у и GRDB-а на iOS-у.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође