Estrutura e Relacionamentos de Banco de Dados Mobile | [SIS]ANO2C1B2S8A3 | professorcomia.com.br
[SIS]ANO2C1B2S8A3 Unidade 2 · Componente 1 Armazenamento de dados e repositórios Aula 3 · Prática

Tabelas, colunas, tipos de dados e relações entre entidades com Room (Android) e Core Data (iOS) — do modelo conceitual à implementação no dispositivo.

Desenvolvimento de Sistemas Android · iOS Room · Core Data · SQLite Entidades · Relações · Normalização Aula Prática · 45 min

Por que o banco de dados do aluno fica uma bagunça na segunda entidade?

Na primeira aula prática, o estudante cria uma tabela simples — tarefas com título e status — e o CRUD funciona. Na terceira aula, o desafio cresce: o app precisa de categorias. A reação mais comum é adicionar uma coluna categoria do tipo String diretamente na tabela de tarefas, repetindo o nome da categoria em cada registro.

O app funciona. Mas quando o professor pede para renomear a categoria “trabalho” para “profissional”, o estudante percebe que precisaria atualizar dezenas de registros individualmente. O custo do atalho se revela: sem um modelo de dados estruturado com relações entre entidades, qualquer mudança vira uma operação em massa propensa a inconsistências.

Este artigo documenta o caminho correto: modelar duas entidades (Tarefa e Categoria), estabelecer o relacionamento via chave estrangeira, e implementar a estrutura no Room ou no Core Data.

Custo concreto de não estruturar relações: dados duplicados em cada linha da tabela, impossibilidade de renomear categorias em cascata, consultas lentas por ausência de filtros relacionais e impossibilidade de escalar para subcategorias ou filtros compostos sem reescrever todo o banco.

O contexto da aula: estrutura antes da prática

Esta é a terceira aula da Unidade 2. As duas anteriores estabeleceram os tipos de armazenamento e o CRUD básico com uma entidade. Agora o foco se desloca para a arquitetura do banco: como múltiplas tabelas se organizam, como se relacionam e qual o impacto dessa decisão na performance e manutenibilidade do app.

Formato: 45 minutos, em grupo, computador com internet. Entrega de texto-síntese no AVA respondendo às três perguntas do roteiro. Antes de qualquer linha de código, o roteiro orienta o grupo a desenhar o modelo no papel — passo deliberado para forçar o raciocínio estrutural antes da implementação.

≡ definição · estrutura de banco de dados móvel

Conjunto de entidades (tabelas), atributos (colunas com tipos definidos) e relacionamentos (vínculos via chaves estrangeiras) que organizam os dados de uma aplicação de forma eficiente, escalável e livre de redundâncias, implementados localmente via Room ou Core Data.

Quais são os três componentes da estrutura de um banco de dados?

ComponenteConceitoExemplo no app de tarefasPapel no Room
Entidade (Tabela)Representa um objeto ou conjunto de dados homogêneoTarefa, Categoria@Entity(tableName = "tarefas")
Atributo (Coluna)Característica específica de uma entidade, com tipo definidotitulo: String, status: String, id: IntPropriedade da data class
RelacionamentoVínculo lógico entre entidades via chave estrangeiracategoriaId em Tarefa → id em Categoria@ForeignKey ou campo referencial

O diagrama do modelo: Tarefa ↔ Categoria

O app de controle de tarefas requer que cada tarefa esteja associada a uma categoria. A solução correta é criar duas entidades com um relacionamento N:1 — muitas tarefas para uma categoria — mediado pelo campo categoriaId na tabela tarefas.

tarefas
id Int PK
titulo String
descricao String
status String
categoriaId Int FK
categorias
id Int PK
nome String

O campo categoriaId na tabela tarefas armazena o id da categoria associada. Relacionamento N:1 — várias tarefas por categoria.

Por que isso evita duplicação?

Sem a entidade separada, o campo categoria em cada tarefa seria um texto como “Trabalho”. Se houver 50 tarefas com essa categoria e o nome mudar, seriam 50 atualizações. Com a entidade Categoria e a chave estrangeira, basta atualizar um único registro na tabela categorias — a mudança se propaga automaticamente a todas as tarefas associadas.

Como implementar a estrutura com Room (Android)?

{ } método estruturado · banco relacional com room · 5 passos
  1. Configurar ambiente: dependências do Room no build.gradle + plugin kotlin-kapt. Sincronizar antes de criar qualquer classe.
  2. Definir as duas entidades: Tarefa com campos id, titulo, descricao, status e categoriaId; Categoria com id e nome. Ambas anotadas com @Entity.
  3. Criar os DAOs: TarefaDao com inserção, busca por categoria e remoção; CategoriaDao com inserção e listagem. A query de filtro por categoria usa o parâmetro :categoriaId.
  4. Implementar o AppDatabase: declarar ambas as entidades no array entities da anotação @Database e expor os dois DAOs como métodos abstratos.
  5. Testar o relacionamento: inserir categorias primeiro, depois tarefas com categoriaId válido. Verificar a query de filtro por categoria.

Implementação completa: duas entidades relacionadas no Room

Template 1 — Entidades Tarefa e Categoria

Tarefa.kt · Categoria.kt — @Entity com relacionamento ▶ Kotlin
// ── ENTIDADE: Tarefa ── @Entity(tableName = "tarefas") data class Tarefa( @PrimaryKey(autoGenerate = true) val id: Int = 0, val titulo: String, val descricao: String, val status: String, // "pendente" | "completa" val categoriaId: Int // FK → Categoria.id )// ── ENTIDADE: Categoria ── @Entity(tableName = "categorias") data class Categoria( @PrimaryKey(autoGenerate = true) val id: Int = 0, val nome: String // "trabalho", "pessoal", etc. )

Template 2 — TarefaDao e CategoriaDao com query relacional

TarefaDao.kt · CategoriaDao.kt ▶ Kotlin
@Dao interface TarefaDao { @Insert fun inserirTarefa(tarefa: Tarefa)// READ com filtro relacional — retorna tarefas de uma categoria @Query("SELECT * FROM tarefas WHERE categoriaId = :categoriaId") fun obterTarefasPorCategoria(categoriaId: Int): List<Tarefa>@Delete fun removerTarefa(tarefa: Tarefa) }@Dao interface CategoriaDao { @Insert fun inserirCategoria(categoria: Categoria)@Query("SELECT * FROM categorias") fun obterTodasCategorias(): List<Categoria> }

Template 3 — AppDatabase com múltiplas entidades

AppDatabase.kt — duas entidades no @Database ▶ Kotlin
// Declarar as duas entidades no array entities @Database(entities = [Tarefa::class, Categoria::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun tarefaDao(): TarefaDao abstract fun categoriaDao(): CategoriaDao }// Uso: inserir categoria antes das tarefas (FK exige id válido) Thread { val db = Room.databaseBuilder(ctx, AppDatabase::class.java, "app-db").build()// 1. Criar categoria db.categoriaDao().inserirCategoria(Categoria(nome = "Trabalho"))// 2. Buscar id gerado val catId = db.categoriaDao().obterTodasCategorias().first().id// 3. Criar tarefa com FK válida db.tarefaDao().inserirTarefa( Tarefa(titulo = "Revisar relatório", descricao = "Q3 2025", status = "pendente", categoriaId = catId) )// 4. Buscar tarefas da categoria val tarefas = db.tarefaDao().obterTarefasPorCategoria(catId) }.start()

Template 4 — Core Data (iOS): duas entidades com relacionamento

TarefaRepository.swift — iOS · Core Data · relações ▶ Swift
// No Data Model Editor: criar entidade Tarefa e Categoria // Adicionar relacionamento "categoria" em Tarefa → aponta para Categoriaimport CoreDataclass TarefaRepository { private let context: NSManagedObjectContext// Inserir categoria func inserirCategoria(nome: String) -> Categoria { let cat = Categoria(context: context) cat.nome = nome try? context.save() return cat }// Inserir tarefa com relacionamento func inserirTarefa(titulo: String, descricao: String, status: String, categoria: Categoria) { let tarefa = Tarefa(context: context) tarefa.titulo = titulo tarefa.descricao = descricao tarefa.status = status tarefa.categoria = categoria // relacionamento direto try? context.save() }// Buscar tarefas por categoria func tarefasPorCategoria(categoria: Categoria) -> [Tarefa] { let req: NSFetchRequest<Tarefa> = Tarefa.fetchRequest() req.predicate = NSPredicate(format: "categoria == %@", categoria) return (try? context.fetch(req)) ?? [] } }

Caso aplicado: app de controle de tarefas com categorias no laboratório

{ } caso real · ensino médio técnico · SEDUC-SP · grupo de 4 alunos

Contexto da atividade: o grupo foi “contratado” para desenvolver um app de controle de tarefas pessoais com categorias (trabalho, pessoal, etc.). Cada tarefa tem título, descrição e status; cada tarefa pertence a uma categoria específica. O grupo precisa definir as entidades, os tipos de dados de cada coluna e o relacionamento entre elas antes de implementar.

Decisão crítica que o grupo enfrentará: inserir a categoria primeiro ou a tarefa primeiro? O campo categoriaId precisa de um id válido da tabela categorias — se a categoria ainda não existir, a inserção falhará ou gerará um registro órfão. Isso força o grupo a entender a ordem de dependência entre entidades relacionadas.

Perguntas do roteiro para o texto-síntese: importância das relações entre entidades; como entidades separadas melhoram a organização; impacto da estrutura na performance. As respostas devem ser entregues no AVA ao término da aula.

→ expansão estratégica · 4 frentes de aplicação
>_

Projeto Integrador

App de gestão de empréstimos com entidades Aluno, Equipamento e Empréstimo — três tabelas relacionadas, desenvolvido em grupo como projeto de conclusão de semestre.

{ }

Blog / Autoridade

Série: “Modelagem de dados mobile do zero” — do diagrama ER no papel ao Room em Kotlin. Conteúdo de alta demanda entre professores e estudantes de mobile.

Cultura Maker

App de inventário do fab lab com entidades Componente e Categoria — registro de entrada e saída de materiais com filtro por categoria e status.

Formação Docente

Rubrica de avaliação: modelagem correta de entidades e relações como critério técnico — diferencia projetos com estrutura profissional de implementações sem planejamento.

Síntese: a estrutura de um banco de dados móvel depende da correta definição de entidades (tabelas), atributos (colunas com tipos) e relacionamentos (chaves estrangeiras entre tabelas). O Room implementa essa estrutura via @Entity, @Dao e @Database. Separar entidades evita duplicação, facilita manutenção e permite consultas relacionais eficientes — princípio de normalização aplicado ao desenvolvimento mobile.

Perguntas frequentes sobre estrutura e relacionamentos de banco de dados mobile

O que é a estrutura de um banco de dados em aplicações móveis?

A estrutura de um banco de dados móvel compreende entidades (tabelas que representam objetos), atributos (colunas com características e tipos) e relacionamentos (vínculos entre tabelas via chaves estrangeiras). Room e Core Data traduzem essa estrutura em código Kotlin ou Swift executado diretamente no dispositivo.

Qual a importância de definir relações entre entidades em um banco de dados móvel?

Relações organizam os dados logicamente, evitam redundâncias e permitem operações complexas como buscar todas as tarefas de uma categoria específica. Sem relações, dados precisam ser duplicados em cada registro, aumentando o volume e a probabilidade de inconsistências. Com relações, uma mudança na categoria se propaga automaticamente a todas as tarefas associadas.

Como entidades separadas melhoram a organização do banco de dados?

A separação aplica o princípio da normalização: evita duplicação e facilita o gerenciamento. Com Categoria como entidade separada, renomear “trabalho” para “profissional” exige atualizar apenas um registro. Também facilita escalabilidade — adicionar subcategorias ou filtros compostos não exige reestruturação do banco.

O que é chave estrangeira (foreign key) em banco de dados mobile?

Chave estrangeira é um campo que referencia a chave primária de outra tabela, estabelecendo o relacionamento entre elas. No Room, o campo categoriaId na entidade Tarefa é uma foreign key que aponta para o id da tabela Categoria, permitindo consultas como “buscar todas as tarefas da categoria Trabalho”.

Como a estrutura do banco de dados impacta a performance de um app móvel?

Relações claramente definidas tornam consultas filtradas mais rápidas. Sem estrutura, o app processa dados duplicados e realiza mais operações de verificação, aumentando consumo de CPU, memória e bateria. Uma estrutura bem planejada reduz o uso de recursos do dispositivo, essencial para uma boa experiência do usuário em hardware limitado.

>_ Unidade 2 completa — Armazenamento de Dados e Repositórios

Todas as aulas, roteiros de atividade e templates de código disponíveis no blog do Professor Comia.

acessar professorcomia.com.br →

Conclusão: modelar antes de codificar

A principal virada pedagógica desta aula não é técnica — é procedimental. O roteiro instrui o grupo a desenhar o modelo no papel antes de abrir o IDE. Esse passo aparentemente simples impõe o raciocínio estrutural antes da implementação: quais entidades existem, quais são seus campos, como elas se relacionam.

O desenvolvedor que modela antes de codificar comete menos erros de estrutura, refatora menos e escala mais facilmente. Esse hábito — pensar em tabelas, colunas e relações antes de pensar em queries — é a competência central desta aula e uma das mais duráveis do curso técnico de Desenvolvimento de Sistemas.

[SIS]ANO2C1B2S8A3 · Unidade 2 · Componente 1 · Estrutura de banco de dados em aplicações móveis · Aula Prática
professorcomia.com.br · diariodeumpoed.com.br · POED SEDUC-SP

// slides de aula · [SIS]ANO2C1B2S8A3 · aula prática · estrutura e relacionamentos

>_ Estrutura de Banco de Dados em Apps Móveis

abertura · slide_01
frequência · registrar presença agora

Código: [SIS]ANO2C1B2S8A3  ·  Unidade 2 · Componente 1 · Aula 3

Aula 3 — Estrutura de banco de dados em aplicações móveis · Prática em grupo · 45 minutos

? Na aula anterior, criamos uma tabela com CRUD. O que acontece quando o app precisa de duas tabelas que se relacionam? Como garantir que os dados não se repitam desnecessariamente?

[ ] Objetivos da Aula

objetivos · slide_02
  • conceitual Compreender a estrutura básica de um banco de dados: entidades, atributos, tipos e relacionamentos
  • procedimental Criar um banco de dados com duas entidades relacionadas usando Room (Android) ou Core Data (iOS)
  • atitudinal Promover o hábito de modelar a estrutura de dados no papel antes de iniciar a implementação
≡ recursos · computador com internet · lápis e caderno · 1 caneta · IDE configurado

! Problema Gerador

problema_gerador · slide_03

Um app de controle de tarefas pessoais precisa organizar as tarefas por categorias (trabalho, pessoal, etc.). Cada tarefa tem título, descrição e status — e pertence a uma categoria específica.

! problema estrutural

Como armazenar a categoria sem repetir o nome em cada tarefa? Se houver 50 tarefas “Trabalho” e o nome mudar, quantas atualizações serão necessárias?

! problema relacional

Como relacionar a entidade Tarefa com a entidade Categoria de forma que a consulta “tarefas por categoria” seja eficiente e sem dados duplicados?

? Dois objetos distintos (Tarefa e Categoria) exigem duas tabelas. Como se estabelece o vínculo entre elas no banco de dados local?

Componentes da Estrutura de BD

conceito · slide_04
  • Entidade (Tabela) · representa um objeto do domínio da aplicação · Ex: Tarefa, Categoria, Usuário
  • Atributo (Coluna) · característica específica de uma entidade com tipo definido · Ex: titulo: String, id: Int
  • Tipo de Dado · define o formato do valor armazenado · Int, String, Boolean, Float, Long
  • Chave Primária (PK) · identifica unicamente cada registro da tabela · @PrimaryKey(autoGenerate=true)
  • Chave Estrangeira (FK) · campo que referencia a PK de outra tabela, criando o relacionamento

# Entidades Tarefa e Categoria — Relacionamento N:1

conceito · slide_05

O campo categoriaId em Tarefa é a chave estrangeira que referencia o id da tabela Categoria. Várias tarefas → uma categoria (N:1).

tarefas
idIntPK
tituloString
descricaoString
statusString
categoriaIdIntFK
categorias
idIntPK
nomeString

{ } DAO com Query Relacional e AppDatabase

conceito · slide_06

TarefaDao — a query de filtro usa o parâmetro :categoriaId para buscar apenas as tarefas de uma categoria.

TarefaDao.kt · AppDatabase.kt ▶ Kotlin
@Dao interface TarefaDao {
    @Insert   fun inserirTarefa(t: Tarefa)
    @Query("SELECT * FROM tarefas WHERE categoriaId = :categoriaId")
              fun obterPorCategoria(categoriaId: Int): List<Tarefa>
    @Delete   fun removerTarefa(t: Tarefa)
}
@Database(entities = [Tarefa::class, Categoria::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun tarefaDao(): TarefaDao
    abstract fun categoriaDao(): CategoriaDao
}

Caderno — Definições da Aula

caderno · slide_07
  • Entidade · tabela que representa um objeto do domínio da aplicação (Tarefa, Categoria)
  • Atributo · coluna com tipo definido que armazena uma característica da entidade
  • Chave Primária (PK) · campo que identifica unicamente cada registro — autogerado pelo Room
  • Chave Estrangeira (FK) · campo que referencia a PK de outra tabela, criando o relacionamento
  • Relacionamento N:1 · muitas tarefas podem pertencer a uma única categoria
  • Normalização · princípio que evita duplicação de dados ao separar entidades distintas em tabelas próprias
  • Query relacional · consulta SQL que filtra registros usando a chave estrangeira como parâmetro
  • @Database(entities = […]) · declaração de todas as tabelas do banco no Room

{ } Contexto da Atividade Prática

contexto_atividade · slide_08

Título: Estrutura de banco de dados em aplicações móveis

Formato: em grupo · 45 minutos · computador com internet · entrega no AVA

Objetivo: criar a estrutura de banco de dados com duas entidades relacionadas (Tarefa + Categoria) usando Room ou Core Data, executando operações CRUD e respondendo às perguntas do roteiro.

{ } entidade tarefa

id Int · PK autogerada

titulo String · título da tarefa

descricao String · detalhes

status String · pendente/completa

categoriaId Int · FK

{ } entidade categoria

id Int · PK autogerada

nome String · trabalho, pessoal…

Planejamento — Modelar no Papel Primeiro

planejamento · slide_09

Antes de abrir o IDE: desenhar o diagrama de entidades e o relacionamento.

∑ componentes necessários

2 @Entity — Tarefa e Categoria

2 @Dao — TarefaDao e CategoriaDao

1 @Database — AppDatabase com ambas as entidades

! ordem de inserção

Primeiro inserir a Categoria (para obter o id gerado).

Depois inserir a Tarefa com o categoriaId obtido — FK precisa de valor válido.

∑ Decisão do grupo: quais categorias criar para testar? Planejem pelo menos 2 categorias e 3 tarefas distribuídas entre elas.

>_ Fluxo Lógico da Implementação

algoritmo · slide_10
  • 1 Configurar dependências Room + kapt no build.gradle e sincronizar
  • 2 Criar @Entity Tarefa com 5 campos (incluindo categoriaId como FK)
  • 3 Criar @Entity Categoria com id e nome
  • 4 Criar TarefaDao com inserção, busca por categoria e remoção
  • 5 Criar CategoriaDao com inserção e listagem
  • 6 Criar AppDatabase com entities = [Tarefa::class, Categoria::class]
  • 7 Executar: inserir categoria → capturar id → inserir tarefa → filtrar por categoria

Implementação — Orientações de IDE

implementacao · slide_11
◉ android studio

Criar arquivos: Tarefa.kt, Categoria.kt, TarefaDao.kt, CategoriaDao.kt, AppDatabase.kt.

Operações em Thread {} separada — Room proíbe na main thread.

◉ xcode (ios)

No Data Model Editor: criar entidades Tarefa e Categoria. Definir relacionamento categoria em Tarefa com destino Categoria.

  • Passo crítico · o array entities no @Database deve listar as duas classes — omitir uma impede a criação da tabela
  • Build clean · após alterar entidades, fazer Build > Clean Project antes de rebuild para forçar a regeneração do Room

! Casos de Teste — O que Verificar

testes · slide_12
✓ caso normal

Inserir Categoria(“Trabalho”), obter id, inserir Tarefa com categoriaId válido.

Esperado: tarefa recuperada por obterPorCategoria(catId) retorna 1 registro.

! caso filtro

Inserir 2 categorias e 3 tarefas distribuídas. Filtrar por cada categoria.

Esperado: cada filtro retorna apenas as tarefas da categoria consultada.

∅ caso id inválido

Inserir tarefa com categoriaId = 999 (categoria inexistente).

Esperado: registro inserido, mas filtro não retorna essa tarefa em nenhuma categoria.

! Anotar no caderno: o que aconteceu em cada caso e se o resultado foi o esperado — parte do texto-síntese para o AVA.

Entrega no AVA

entrega_ava · slide_13

Envie o texto-síntese com as respostas às três perguntas do roteiro:

⌨ o que incluir

Pergunta 1 — Qual a importância de definir relações entre entidades em um banco de dados móvel?

Pergunta 2 — Como entidades separadas (Tarefa e Categoria) melhoram a organização do banco?

Pergunta 3 — Qual o impacto da estrutura do banco no desempenho do app?

✓ critérios de avaliação

Embasamento técnico nas respostas.

Conexão entre a resposta e a implementação realizada.

Todos os integrantes do grupo identificados na entrega.

⌨ entrega · texto/síntese no AVA até o final da aula · mínimo 15 linhas · todos os nomes do grupo

Então Ficamos Assim…

sintese · slide_14

Estrutura do BD

Banco de dados é ferramenta essencial para armazenar e gerenciar dados — sua estrutura inclui tabelas, colunas, tipos e relações.

#

Relacionamentos

A relação Tarefa ↔ Categoria via chave estrangeira evita duplicação e permite consultas filtradas eficientes — princípio de normalização.

{ }

Room e Core Data

SQLite/Room (Android) e Core Data (iOS) permitem manipular dados de forma rápida e segura diretamente no dispositivo — sem servidor.

← aula anterior

Ferramentas de armazenamento · CRUD básico com uma entidade · TarefaDao e AppDatabase simples

→ próxima aula

Implementação avançada de banco de dados · Consultas complexas, @Relation e integração com a UI do app

📘 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.