SQLite no desenvolvimento mobile: o que é e como funciona

Autor: IT Sectr Publicado: 2026-03-11 Tempo de leitura: 10 min

SQLite é um banco de dados relacional embarcado que funciona sem um processo de servidor separado e armazena todo o banco de dados em um único arquivo no dispositivo. Graças à configuração zero, ao tamanho reduzido da biblioteca e ao suporte completo a SQL, o SQLite tornou-se o padrão para armazenamento local de dados em aplicativos móveis. De acordo com o SQLite Consortium (2025), este SGBD é usado em mais de 4 bilhões de dispositivos, incluindo todos os smartphones com iOS e Android.

Pontos principais

  • SQLite é um SGBD relacional embarcado com configuração zero e armazenamento de dados em um único arquivo.
  • Transações ACID garantem a integridade dos dados mesmo em falhas de energia ou travamentos do aplicativo.
  • Tipagem de dados dinâmica: o SQLite não exige especificação estrita do tipo de coluna ao criar uma tabela.
  • Room é uma biblioteca ORM para Android que simplifica o trabalho com SQLite através de DAOs e anotações.
  • CoreData pode usar SQLite como Persistent Store no iOS, mas adiciona uma camada de gerenciamento de objetos.

O que é SQLite?

SQLite é uma biblioteca em linguagem C que implementa um SGBD relacional sem servidor dedicado. Ela é embarcada diretamente no aplicativo, lendo e escrevendo dados em um arquivo comum no sistema de arquivos do dispositivo. O tamanho da biblioteca é de aproximadamente 600 KB, tornando o SQLite o banco de dados SQL completo mais leve.

O SQLite suporta a maior parte do padrão SQL:1999, incluindo JOIN, subconsultas, triggers, views, índices e funções de janela. As limitações dizem respeito ao ALTER TABLE (suporte limitado) e aos RIGHT/FULL OUTER JOIN completos. No entanto, para aplicativos móveis, a funcionalidade do SQLite é suficiente em 99% dos casos de armazenamento local.

De acordo com a pesquisa de desenvolvedores do Stack Overflow (2025), o SQLite é o banco de dados mais popular para soluções embarcadas e ocupa o terceiro lugar em popularidade entre todos os SGBDs, depois do MySQL e PostgreSQL. No desenvolvimento mobile, o SQLite é usado em todos os aplicativos — diretamente ou através de wrappers.

Características principais do SQLite

Configuração zero — o SQLite não requer instalação, configuração de permissões, criação de usuários ou inicialização de serviço. A biblioteca é vinculada ao projeto e o banco de dados é criado chamando uma única função. Isso simplifica radicalmente a implantação em comparação com SGBDs cliente-servidor, que exigem instalação do servidor, configuração de portas e criação de usuários.

O arquivo de banco de dados SQLite é um arquivo multiplataforma comum que pode ser copiado, analisado, enviado pela rede ou restaurado a partir de um backup. O formato do arquivo é estável no nível da API: arquivos SQLite 3 criados em 2004 são abertos com a versão atual da biblioteca, garantindo compatibilidade de dados a longo prazo.

Como o SQLite funciona: arquitetura e armazenamento

A arquitetura do SQLite consiste em oito máquinas virtuais: Tokenizer, Parser, Code Generator, VM, B-Tree, Pager, OS Interface e Utilities. Uma consulta SQL passa pelo Tokenizer (divisão em tokens), Parser (construção de uma AST), Code Generator (conversão em bytecode) e é executada na máquina virtual, que lê as páginas de dados através de B-Tree e Pager.

O SQLite usa B-Tree para armazenar tabelas e índices. Cada tabela é armazenada como uma B-Tree separada, onde os nós folha contêm as linhas de dados. Os índices também são armazenados como B-Trees, mas com chaves nas folhas. O Pager gerencia o carregamento de páginas (padrão 4096 bytes) do arquivo para a memória, fornecendo transações ACID através de um journal ou WAL.

Modos de registro

WAL (Write-Ahead Logging) é o modo recomendado para aplicativos móveis. As alterações são primeiro gravadas em um arquivo WAL separado e depois transferidas periodicamente para o banco de dados principal. O WAL permite ler (dados antigos) e escrever (através do WAL) simultaneamente no banco de dados, melhorando o desempenho de aplicativos multithread. O journal padrão (rollback journal) bloqueia a leitura durante a gravação.

ParâmetroRollback JournalWAL (Write-Ahead Logging)
Leitura durante gravaçãoBloqueadaPermitida (lê dados antigos)
Desempenho de gravaçãoMédioAlto (gravação sequencial em WAL)
Consumo de discoMenor (apenas journal de reversão)Maior (WAL + banco principal)
Recuperação de falhasReversão ao último ponto de verificaçãoRecuperação do WAL (sem perda de dados)
RecomendaçãoPara cenários single-threadPara aplicativos móveis típicos

A alternância entre modos é feita com uma única consulta SQL: PRAGMA journal_mode=WAL. Para aplicativos móveis com sincronização em segundo plano e uma thread de UI lendo dados simultaneamente, o WAL oferece melhor desempenho e ausência de bloqueios de interface.

SQLite vs outros bancos de dados no desenvolvimento mobile

SQLite não é a única opção para armazenamento local de dados, mas é a mais versátil. O Realm oferece maior velocidade de acesso direto a objetos na memória, mas usa seu próprio formato NoSQL e tem um tamanho de biblioteca maior. O Core Data no iOS é uma camada ORM sobre o SQLite que adiciona gerenciamento de grafo de objetos e desfazer operações.

Para a maioria dos aplicativos, o SQLite continua sendo a escolha ideal devido ao desempenho previsível, ausência de vendor lock-in e estabilidade testada ao longo do tempo. O Realm e o Core Data são justificados em projetos com grafos de objetos complexos, consultas reativas ou requisitos de sincronização entre dispositivos.

CaracterísticaSQLiteRealmCore Data
Tipo de bancoRelacional (SQL)NoSQL (orientado a objetos)ORM (sobre SQLite)
Tamanho da biblioteca~600 KB~4 MBIntegrado ao SDK da Apple
DesempenhoMédioAlto (objetos em memória)Médio (sobrecarga ORM)
PlataformasiOS, Android, Web, DesktopiOS, Android, Node.jsiOS, macOS
Vendor lock-inNenhum (padrão aberto)Médio (formato proprietário)Alto (apenas Apple)

A escolha entre SQLite, Realm e Core Data depende da plataforma, dos requisitos do modelo de objetos e da estratégia de sincronização. Para projetos multiplataforma (KMP, Flutter), o SQLite continua sendo a única escolha universal que funciona em todas as plataformas alvo sem alterações no modelo de dados.

SQLite no Android: Room e SQLiteOpenHelper

Room é uma biblioteca do Android Jetpack que fornece uma camada ORM sobre o SQLite. O Room gera automaticamente consultas SQL a partir de interfaces DAO anotadas, valida a correção das consultas em tempo de compilação e suporta migrações de banco de dados quando o esquema muda. O Room é a maneira recomendada de trabalhar com SQLite no Android.

SQLiteOpenHelper é uma API de baixo nível para gerenciamento direto do SQLite sem ORM. A classe gerencia a criação, abertura e atualização do banco de dados. O SQLiteOpenHelper é adequado para projetos com consultas SQL simples ou quando é necessário controle total sobre a lógica SQL sem a abstração do Room.

Exemplo de entidade e DAO para Room

Uma entidade no Room é anotada com @Entity, e um DAO com @Dao. O Room traduz métodos anotados em consultas SQL: @Insert gera INSERT, @Query gera SELECT com o SQL especificado. As migrações são adicionadas através de Migration com as versões de esquema antiga e nova especificadas. O Room valida o SQL em tempo de compilação, eliminando erros de sintaxe em produção.

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)
}

O Room gera automaticamente a implementação UserDao_Impl, que contém consultas SQLite em tempo de execução através do RoomDatabase interno. Graças às corrotinas (suspend), os métodos DAO são executados de forma assíncrona em uma thread em segundo plano sem bloquear a UI. Os tipos de retorno Flow em @Query atualizam automaticamente o resultado quando a tabela muda.

SQLite no iOS: FMDB e GRDB

FMDB é um wrapper Objective-C sobre a API C do SQLite, historicamente a primeira biblioteca popular para iOS. Ela fornece objetos FMDatabase e FMResultSet para executar consultas e obter resultados. A FMDB é simples e minimalista, mas não suporta construções específicas do Swift — optionals, Codable, async/await.

GRDB é uma biblioteca Swift moderna para trabalhar com SQLite. Ela fornece uma API type-safe, suporte a Codable, Combine Publishers, async/await, migrações e observação de alterações em tempo real. A GRDB é preferida para novos projetos em Swift devido à integração completa com Swift Concurrency e melhor legibilidade do código.

Exemplo de GRDB em Swift

GRDB define tabelas através de classes Record que seguem os protocolos FetchableRecord e TableRecord. As consultas são escritas em Swift com sintaxe type-safe em vez de SQL puro. A GRDB também suporta DatabaseMigrator para versionamento de esquemas e migrações entre versões do aplicativo.

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 usa o modo WAL do SQLite para leitura concorrente. Vários leitores podem acessar o banco de dados simultaneamente enquanto um único escritor atualiza os dados através do WAL. A GRDB gerencia automaticamente as conexões e transações, fornecendo acesso thread-safe ao banco de dados de qualquer thread sem sincronização manual.

Otimização de desempenho do SQLite

Os índices são a maneira mais eficaz de acelerar consultas SQLite. Um índice é criado nas colunas usadas nas cláusulas WHERE, JOIN e ORDER BY. Para uma tabela com 100000 registros, a busca por uma coluna indexada leva milissegundos em vez de segundos. No entanto, os índices diminuem as operações INSERT e UPDATE, portanto, seu número deve ser equilibrado com a frequência de gravação.

A inserção em lote (batch insert) dentro de uma única transação acelera radicalmente o carregamento massivo de dados. Inserir 1000 registros um por um gera uma sobrecarga de ~1 segundo. Os mesmos 1000 registros em uma única transação levam ~5-10 milissegundos. A diferença é explicada pelo fato de cada INSERT individual criar uma nova transação com gravação síncrona em disco.

PRAGMAs de desempenho

PRAGMA são comandos SQLite para configurar o comportamento da biblioteca. Pragmas de otimização principais: PRAGMA synchronous=NORMAL (reduz a frequência de fsync), PRAGMA cache_size=-8000 (aloca 8 MB de cache), PRAGMA temp_store=MEMORY (tabelas temporárias em memória). Para aplicativos móveis com grandes volumes de dados, a combinação desses pragmas acelera as consultas em 2 a 3 vezes.

Outra otimização importante é a pré-compilação de consultas SQL (prepared statements). Se uma consulta é executada repetidamente (por exemplo, inserindo 10000 linhas), compilar o SQL uma vez e reutilizar a instrução reduz a carga da CPU em 30-50%. O Room e a GRDB armazenam em cache automaticamente os prepared statements, mas ao usar a API C do SQLite diretamente, a compilação deve ser feita manualmente.

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)
                }
            }
        }
    }
}

A inserção em lote com withTransaction garante que todas as operações INSERT sejam executadas dentro de uma única transação. A divisão em sublotes (chunked) impede que uma única transação se torne muito grande, o que poderia bloquear outras threads por um longo período. Para sincronização em segundo plano, um tamanho de sublote de 500 registros fornece o equilíbrio ideal entre velocidade e capacidade de resposta da UI.

Perguntas frequentes

O SQLite pode ser usado em múltiplas threads?

Sim, o SQLite suporta acesso multithread no modo WAL. Várias threads podem ler dados simultaneamente, mas apenas uma pode escrever. O Room e a GRDB gerenciam a sincronização automaticamente. No modo rollback journal (padrão), o banco de dados é totalmente bloqueado durante qualquer operação de gravação.

Qual é o tamanho máximo do banco de dados SQLite em um dispositivo móvel?

O limite do SQLite é de 281 TB (máximo teórico). Na prática, o tamanho do banco de dados é limitado pela memória disponível do dispositivo. Para aplicativos móveis, um tamanho confortável é de até 1-2 GB. Bancos de dados com mais de 2 GB diminuem os backups, as atualizações pela App Store e aumentam o consumo de RAM.

Os dados no SQLite são seguros?

O SQLite não criptografa dados por padrão — qualquer processo com acesso ao arquivo pode lê-los. Para criptografia, use SQLCipher (extensão com AES-256), Room com EncryptedDatabase (Android) ou Encrypted Core Data no iOS. A criptografia adiciona 5-15% de sobrecarga nas operações de leitura e gravação de dados.

Qual é a diferença entre SQLite e MySQL?

SQLite é uma biblioteca embarcada que não requer um processo de servidor. MySQL é um SGBD cliente-servidor com um servidor separado, usuários, direitos de acesso e um protocolo de rede. O SQLite armazena o banco de dados em um único arquivo; o MySQL o armazena em vários arquivos gerenciados pelo servidor. O SQLite é mais simples e leve; o MySQL é mais poderoso e escalável.

Como atualizar o esquema do SQLite sem perder dados?

Para migração do SQLite, use ALTER TABLE (adicionar colunas) ou crie uma nova tabela com transferência de dados e exclusão da tabela antiga. O Room automatiza esse processo através das classes Migration: especifique startVersion, endVersion e consultas SQL para alterações de esquema. O GRDB e o FMDB fornecem DatabaseMigrator semelhantes.

Resumo

  • SQLite é um SGBD relacional embarcado com configuração zero, usado em todos os aplicativos móveis no iOS e Android para armazenamento local de dados.
  • Transações ACID e modo WAL garantem a integridade dos dados e acesso concorrente de várias threads do aplicativo.
  • Room (Android) e GRDB (iOS) são wrappers modernos sobre o SQLite que simplificam o trabalho com o banco de dados através de APIs type-safe e migrações automáticas.
  • A arquitetura B-Tree do SQLite garante busca eficiente por índices, enquanto transações em lote e prepared statements fornecem alto desempenho de gravação.
  • SQLite supera o Realm e o Core Data em versatilidade (todas as plataformas), tamanho de biblioteca e ausência de vendor lock-in.
  • A otimização através de índices, modo WAL e configurações PRAGMA acelera as consultas em 2 a 3 vezes em cargas de trabalho móveis típicas.
  • Recomendação — use o SQLite como armazenamento local principal para aplicativos móveis através do Room no Android e do GRDB no iOS.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também