8.4 KiB
Modelo de dados — referência conceitual
1. Aviso
Este documento descreve o modelo lógico desejável para análise.
Ele não afirma que o banco SQLite atual possui essas tabelas ou colunas. O esquema real deve ser inspecionado antes de qualquer consulta.
Não migre o banco original para este modelo sem autorização.
2. Entidades fundamentais
O projeto deve distinguir cinco conceitos:
- fonte: site, portal, corretor ou canal;
- anúncio: publicação identificável em uma fonte;
- observação: estado do anúncio em uma data de coleta;
- imóvel físico: unidade residencial que pode aparecer em vários anúncios;
- execução de coleta: processo técnico que obteve os dados.
Essa separação é essencial para séries históricas e deduplicação.
3. Fonte
Entidade conceitual: source
Campos desejáveis:
source_idnamebase_urlsource_typeactivenotescreated_at
Não usar domínio ou nome de corretor como identificador único sem normalização.
4. Execução de coleta
Entidade conceitual: scrape_run
Campos desejáveis:
run_idsource_idstarted_atfinished_atstatuspages_requestedpages_succeededpages_faileditems_seenitems_inserteditems_updatedhttp_status_summaryscraper_versionconfiguration_hasherror_summary
Serve para identificar:
- períodos sem coleta;
- mudanças de cobertura;
- falhas;
- alterações de código;
- diferenças entre ausência real e ausência causada por erro.
5. Anúncio
Entidade conceitual: listing
Representa a identidade do anúncio, não cada coleta.
Campos desejáveis:
listing_idsource_idsource_listing_idcanonical_urlfirst_seen_atlast_seen_atlast_successful_seen_atstatusseller_typeseller_name_normalizedbroker_registrationproperty_candidate_idcreated_atupdated_at
Chave natural potencial:
(source_id, source_listing_id)
A URL não deve ser a única chave, pois pode mudar.
6. Observação histórica
Entidade conceitual: listing_snapshot
Representa o conteúdo observado em uma execução.
Campos desejáveis:
snapshot_idlisting_idrun_idobserved_attitledescriptionpricecondominium_feeproperty_taxarea_privatearea_usefularea_builtarea_totalbedroomssuitesbathroomsparking_spacesfloorelevatorfurnishedproperty_typeaddress_rawneighborhood_rawlatitudelongitudeimage_countstatus_rawpayload_hashraw_payload_reference
Não sobrescrever o histórico quando um anúncio muda.
Se os dados atuais usam uma única linha mutável por anúncio, documentar essa limitação.
7. Imóvel físico candidato
Entidade conceitual: property_candidate
Representa uma hipótese de que anúncios diferentes descrevem o mesmo imóvel.
Campos desejáveis:
property_candidate_idcanonical_regioncanonical_addresscanonical_unitproperty_typeoriginal_floor_plandedup_confidencededup_methodreview_statuscreated_atupdated_at
Não tratar correspondência probabilística como certeza.
Estados sugeridos:
unreviewedprobableconfirmedrejectedambiguous
8. Endereço e localização
Entidade conceitual: location
Campos desejáveis:
location_idregionadministrative_regionneighborhoodsuperquadraquadrablockqcstreetlotunitpostal_codelatitudelongitudegeocode_precisiongeocode_source
No Distrito Federal, o endereço deve permitir estruturas como:
- SHCES;
- quadra;
- bloco;
- superquadra;
- conjunto;
- lote;
- QC;
- condomínio;
- unidade.
Não forçar todos os endereços a um modelo de rua e número.
9. Mídia
Entidade conceitual: listing_media
Campos desejáveis:
media_idsnapshot_idmedia_urlmedia_typepositioncontent_hashperceptual_hashwidthheightdownload_status
Hashes perceptuais de imagens podem ajudar na deduplicação, mas não devem decidir sozinhos.
10. Histórico de preço
O histórico pode ser derivado de listing_snapshot.
View conceitual:
SELECT
listing_id,
observed_at,
price,
price - LAG(price) OVER (
PARTITION BY listing_id
ORDER BY observed_at
) AS absolute_change
FROM listing_snapshot;
Regras:
- ignorar repetições idênticas;
- registrar aumentos e reduções;
- não interpretar ausência como venda;
- identificar alterações simultâneas de área ou tipologia;
- detectar preços promocionais artificiais;
- separar moeda e unidades.
11. Deduplicação
11.1 Sinais fortes
- mesmo identificador na fonte;
- mesmo endereço e unidade;
- mesmo conjunto de imagens;
- mesmo telefone ou corretor com descrição muito semelhante;
- mesma planta, metragem e características;
- coordenadas muito próximas;
- texto quase idêntico.
11.2 Sinais moderados
- mesma quadra e bloco;
- mesmo preço;
- mesma área;
- mesmos quartos e vagas;
- datas próximas;
- imagens parcialmente coincidentes.
11.3 Sinais fracos
- mesmo bairro;
- título genérico;
- preço arredondado;
- número de quartos isolado.
11.4 Regras
- manter o anúncio original;
- criar relacionamento de duplicidade;
- registrar método e confiança;
- permitir revisão manual;
- não fundir registros de forma irreversível;
- não usar apenas texto normalizado;
- evitar que atualizações do mesmo anúncio sejam contadas como imóveis novos.
12. Normalização
Preço
- armazenar como número inteiro em centavos ou valor monetário consistente;
- preservar valor bruto;
- registrar moeda;
- detectar preço por mês confundido com preço total;
- detectar valores incompletos.
Área
Manter campos separados:
- privativa;
- útil;
- construída;
- total;
- terreno.
Nunca preencher uma área com outra apenas para completar dados.
Quartos
Separar:
- quartos;
- suítes;
- dependência;
- escritório;
- quarto reversível;
- tipologia original;
- tipologia anunciada.
Localização
Preservar:
- texto bruto;
- versão normalizada;
- componentes extraídos;
- confiança da extração.
Datas
Usar ISO 8601 e timezone explícito quando relevante.
13. Qualidade dos dados
Criar métricas por fonte, período e região:
- percentual sem preço;
- percentual sem área;
- percentual sem localização;
- percentual com preço por m² calculável;
- duplicidade estimada;
- taxa de mudança de identificador;
- cobertura diária;
- falhas de coleta;
- distribuições implausíveis;
- inconsistência entre título e campos;
- divergência entre snapshots.
14. Inspeção inicial do SQLite
Consultas somente leitura úteis:
Tabelas e views
SELECT
type,
name,
tbl_name,
sql
FROM sqlite_master
ORDER BY type, name;
Contagem aproximada de tabelas
Gerar consultas após listar os nomes. Não concatenar nomes externos sem validação.
Colunas
PRAGMA table_info('nome_da_tabela');
Chaves estrangeiras
PRAGMA foreign_key_list('nome_da_tabela');
Índices
PRAGMA index_list('nome_da_tabela');
Integridade
PRAGMA quick_check;
quick_check é somente leitura, mas pode ser custoso em bancos grandes. Executar quando apropriado.
15. Camada derivada recomendada
Sem alterar o banco original, criar:
data/derived/
├── listings_clean.parquet
├── snapshots_clean.parquet
├── property_candidates.parquet
├── price_history.parquet
├── locations_normalized.parquet
└── quality_metrics.parquet
Ou um SQLite derivado:
data/derived/analytics.sqlite
Toda derivação deve registrar:
- data;
- versão do código;
- fonte;
- filtros;
- hash ou identificação do banco de origem;
- contagem de entrada e saída.
16. Dicionário do esquema real
Após inspecionar o banco, produzir:
docs/ACTUAL_SCHEMA.md
Esse arquivo deve conter:
- diagrama das tabelas;
- descrição de cada coluna;
- chaves;
- índices;
- cardinalidades;
- exemplos pequenos;
- problemas conhecidos;
- correspondência com este modelo conceitual;
- decisões de interpretação.
Não alterar DATA_MODEL.md para simplesmente espelhar um esquema ruim. Manter separação entre modelo conceitual e implementação real.