Normalização, tipos de dados otimizados, índices para performance e CRUD com Room e Core Data — o fechamento técnico do bloco de armazenamento no ensino técnico de Desenvolvimento de Sistemas.
Quando o código funciona mas o banco de dados é um problema esperando acontecer
Uma aplicação que funciona em testes com dez registros pode se tornar lenta com mil. Uma tabela que parece bem estruturada em um app simples pode gerar inconsistências em uma segunda versão. O código compila, o CRUD executa, o app entrega o resultado esperado — e ainda assim o banco de dados está mal projetado.
Esse é o desafio das boas práticas: elas não aparecem no primeiro teste. Aparecem quando o volume de dados cresce, quando uma coluna precisar ser filtrada frequentemente, quando uma mudança de nomenclatura exige atualizar 400 registros. São princípios de engenharia que separam o app que funciona do app que escala.
Esta última aula do bloco S8 fecha o ciclo com os quatro pilares das boas práticas no armazenamento mobile: normalização, tipos de dados corretos, índices e sincronização.
Custo de ignorar boas práticas: dados duplicados que divergem com o tempo, consultas lentas por ausência de índices, tipos de dados errados que desperdiçam espaço ou perdem precisão decimal, e apps frágeis que corrompem dados em quedas de conexão. Todos são problemas que o desenvolvedor carregará por toda a vida útil do produto.
O contexto da aula: encerramento técnico do bloco
Esta é a quarta e última aula do bloco S8 — Introdução ao Armazenamento de Dados. As aulas anteriores construíram progressivamente: tipos de armazenamento (A1), CRUD básico com uma entidade (A2), estrutura e relacionamentos entre entidades (A3). Agora o foco é a qualidade técnica do que foi construído.
Formato: 40 minutos, em grupo, com computador e internet. A atividade usa um contexto novo — app de registro de atividades físicas — para que o grupo aplique as boas práticas em um domínio diferente das aulas anteriores, consolidando a transferência de conhecimento.
Conjunto de princípios técnicos que garantem desempenho, segurança e integridade em um banco de dados móvel: normalização para eliminar redundâncias, tipos de dados otimizados, índices para acelerar consultas e mecanismos de sincronização para resiliência.
Quais são as quatro boas práticas no armazenamento de dados mobile?
Normalização
Eliminar duplicação ao estruturar as tabelas. Dados relacionados ficam em entidades separadas, vinculadas por chaves estrangeiras.
Tipos de Dados
Usar o tipo correto: Int para inteiros, Float para decimais, String para texto. Evitar armazenar números como String.
Índices
Criar índices em colunas frequentemente pesquisadas (como categoriaId) para acelerar consultas sem varrer a tabela inteira.
Sincronização e Backup
Implementar mecanismos para sincronizar dados locais com o servidor e garantir resiliência em quedas de conexão ou falhas do dispositivo.
Por que tipos de dados importam na prática?
No app de atividades físicas, a duração é armazenada como Int (minutos são números inteiros — não existe “30,5 minutos” como dado de usuário). A distância é armazenada como Float porque 5,3 km é um valor decimalmente válido e relevante. Armazenar a distância como Int truncaria os decimais; como String, impediria comparações e somas numéricas diretas no banco.
A escolha de tipo não é trivial: impacta o espaço em disco, a performance de consultas numéricas e a precisão dos dados — especialmente em apps de saúde ou fitness onde os valores decimais têm significado real.
O que é um índice no banco de dados e como declarar no Room?
Um índice é uma estrutura auxiliar que o banco de dados mantém para localizar registros rapidamente sem varrer toda a tabela. É análogo ao índice de um livro: em vez de ler página por página, você vai diretamente ao número de página do termo buscado. No Room, índices são declarados na anotação @Entity:
Implementação com boas práticas: app de atividades físicas
Template 1 — Entidades com tipos otimizados e índice em categoriaId
// Boa prática: índice em coluna frequentemente pesquisada
@Entity(
tableName = "atividades",
indices = [Index(value = ["categoriaId"])] // acelera filtros por categoria
)
data class Atividade(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val nome: String,
val duracao: Int, // Int: minutos são sempre inteiros
val distancia: Float, // Float: distância em km com precisão decimal
val categoriaId: Int // FK → Categoria.id (indexada acima)
)@Entity(tableName = "categorias")
data class Categoria(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val nome: String // "Aeróbico", "Musculação", "Ciclismo"
)Template 2 — DAOs com CRUD completo para as duas entidades
@Dao
interface AtividadeDao {
@Insert fun inserirAtividade(a: Atividade)// Filtro usa o índice de categoriaId — consulta rápida
@Query("SELECT * FROM atividades WHERE categoriaId = :categoriaId")
fun obterAtividadesPorCategoria(categoriaId: Int): List<Atividade>@Update fun atualizarAtividade(a: Atividade)
@Delete fun removerAtividade(a: Atividade)
}@Dao
interface CategoriaDao {
@Insert fun inserirCategoria(c: Categoria)
@Query("SELECT * FROM categorias")
fun obterTodasCategorias(): List<Categoria>
}@Database(entities = [Atividade::class, Categoria::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun atividadeDao(): AtividadeDao
abstract fun categoriaDao(): CategoriaDao
}Template 3 — Tabela de tipos de dados e quando usar cada um
| Tipo | Uso correto | Exemplo no app | Evitar |
|---|---|---|---|
| Int | Valores inteiros sem casas decimais | duracao: Int (minutos: 30, 45, 60) | Usar Long quando Int é suficiente |
| Float | Valores decimais com precisão simples | distancia: Float (km: 5.3, 10.7) | Usar String para armazenar números decimais |
| String | Texto de comprimento variável | nome: String (“Corrida matinal”) | Usar para armazenar datas ou booleanos |
| Boolean | Valor binário verdadeiro/falso | ativo: Boolean (categoria ativa) | Usar String “true”/”false” em vez de Boolean |
| Long | Timestamps, IDs de alta cardinalidade | dataHora: Long (Unix timestamp) | Usar onde Int é suficiente |
Caso aplicado: app de atividades físicas com boas práticas
Contexto: o grupo foi “contratado” para desenvolver um app de registro de atividades físicas — corridas, treinos, ciclismo. O app registra duração (em minutos), distância (em km) e categoria de cada atividade. A entidade Atividade precisa de duracao: Int e distancia: Float — escolha deliberada de tipos que o grupo precisa justificar no texto-síntese.
Boa prática que o grupo precisa implementar: adicionar o índice em categoriaId via indices = [Index(value = ["categoriaId"])] na anotação @Entity. Essa linha única tem impacto direto na performance de todas as consultas filtradas por categoria — o grupo precisa entender o porquê, não apenas copiar.
Perguntas do roteiro: importância da normalização; como índices melhoram a performance; quais tipos de dados foram usados e por quê. As respostas devem conectar as decisões técnicas implementadas com os princípios das boas práticas.
Síntese do bloco S8: ao criar um banco de dados para app móvel, é fundamental seguir boas práticas para garantir desempenho, segurança e integridade. Room (Android) e Core Data (iOS) implementam CRUD com APIs robustas. Normalização elimina redundâncias, tipos corretos otimizam armazenamento, índices aceleram consultas, e mecanismos de sync garantem resiliência — esses quatro princípios transformam um banco funcional em um banco profissional.
Perguntas frequentes sobre boas práticas no armazenamento mobile
O que são boas práticas no armazenamento de dados em apps móveis?
Boas práticas incluem normalização (eliminar duplicação), uso correto de tipos de dados (Int, Float, String conforme o valor), criação de índices em colunas frequentemente pesquisadas, e implementação de mecanismos de sincronização e backup para garantir integridade e resiliência.
Por que é importante normalizar os dados ao criar um banco de dados móvel?
A normalização elimina duplicação e assegura que informações relacionadas estejam organizadas eficientemente. Em apps móveis, onde armazenamento e performance são recursos limitados, a normalização impacta diretamente a velocidade de consulta e o consumo de bateria.
Como o uso de índices melhora a performance do banco de dados móvel?
Índices em colunas frequentemente pesquisadas, como categoriaId, permitem que o banco localize rapidamente os registros sem varrer a tabela inteira. No Room, são declarados via indices = [Index(value = [“coluna”])] na anotação @Entity. Em apps com muitos registros, a diferença de tempo entre uma consulta com e sem índice pode ser de milissegundos versus segundos.
Quais tipos de dados usar para otimizar o armazenamento em banco de dados mobile?
Use Int para valores inteiros como duração em minutos. Use Float para valores decimais como distância em km. Use String para texto. Evite armazenar números como String — além de ocupar mais espaço, impede cálculos diretos e degrada a performance de consultas numéricas.
Qual a diferença entre RAM, SharedPreferences e SQLite em aplicações móveis?
RAM armazena dados temporários perdidos ao fechar o app. SharedPreferences e UserDefaults armazenam preferências simples do usuário como tema e notificações. SQLite (via Room ou Core Data) é o banco de dados relacional para consultar e manipular grandes volumes de dados estruturados com persistência e suporte a filtros.
>_ Série completa S8 — Introdução ao Armazenamento de Dados
Todas as 4 aulas do bloco, roteiros de atividade prática e templates de código disponíveis no blog do Professor Comia.
acessar professorcomia.com.br →Conclusão: da implementação à engenharia
Implementar um CRUD que funciona é o ponto de partida, não o destino. A distância entre um desenvolvedor que faz o banco de dados funcionar e um desenvolvedor que faz o banco de dados funcionar bem está precisamente nestes quatro princípios: normalização, tipos corretos, índices e resiliência.
O estudante que termina este bloco com esses conceitos internalizados não apenas sabe usar Room ou Core Data — sabe avaliar a qualidade do que implementou e identificar o que pode ser melhorado. Essa capacidade analítica é o que transforma competência técnica em autoridade profissional.
📘 Gostou do que viu aqui no laboratório? No Professor com IA eu mostro, passo a passo, como você também pode criar ferramentas assim — mesmo sem saber programar.