Pular para o conteúdo principal

Banco de dados

Todos os sistemas Rails usam PostgreSQL. As bases do Syens e do Salus são grandes (milhares de migrations), então cuidados com performance e integridade não são opcionais.

Migrations

  • Toda mudança de schema entra por migration reversível (change com operações reversíveis, ou up/down).
  • Adicione constraints no banco: chaves estrangeiras, null: false e índices únicos, além das validações de modelo.
  • Crie índices para colunas usadas em WHERE, ORDER BY ou JOIN.
  • Em tabelas grandes, avalie o impacto da migration antes de rodar em produção (bloqueios e tempo de execução).
class AddIndexesToAttendances < ActiveRecord::Migration
def change
add_index :attendances, [:classroom_id, :date]
add_foreign_key :attendances, :classrooms
change_column_null :attendances, :classroom_id, false
end
end

O schema.rb é a fonte de verdade do schema e é versionado.

Performance (não-negociável)

Estas regras valem para todo código que toca o banco:

  • Prefira operações no banco a iterar em Ruby para dados em massa: update_all, delete_all, pluck.
  • Não carregue grandes conjuntos na memória — use find_each / find_in_batches.
  • Use counter_cache para contagens frequentes de associações.
  • Mova operações pesadas (relatórios, exportações, e-mails em massa) para o Sidekiq.
# Em vez de carregar tudo e iterar
Student.where(school_id: school.id).find_each do |student|
# processa em lotes, sem estourar a memória
end

# Apenas uma coluna? use pluck
ids = Enrollment.where(school_year_id: year.id).pluck(:student_id)

Prevenção de N+1

Sempre use includes, preload ou eager_load quando for acessar associações em um loop (inclusive dentro de views e serializers).

# Ruim: 1 query para turmas + N queries para a escola de cada uma
classrooms.each { |c| puts c.school.name }

# Bom: pré-carrega a associação
Classroom.includes(:school).each { |c| puts c.school.name }

Regra prática: depois de escrever uma query que renderiza uma coleção, percorra mentalmente a view/serializer e confira se alguma associação é acessada por registro.