Laboratório: busca de e-commerce com SQLite, D1 e Workers
Modelando o catálogo e o conjunto de dados semente
Schema de produtos, carga de dados de exemplo e critérios de qualidade do corpus de busca.
Nesta aula você vai
- Definir schema relacional de produtos adequado a FTS5
- Carregar um seed de ~15–20 produtos fictícios com diversidade linguística
- Validar o corpus para plurais, acentos e termos compostos
Modelando o catálogo e o conjunto de dados semente
Objetivos
Nesta aula você vai:
- Definir schema relacional de produtos adequado a FTS5
- Carregar um seed de ~15–20 produtos fictícios com diversidade linguística
- Validar o corpus para plurais, acentos e termos compostos
Introdução
Antes de criar a tabela virtual FTS5, o laboratório precisa de uma tabela canônica e de um corpus de teste que exercite os casos reais de busca em e-commerce brasileiro: acentos (furadeira vs furacão), plurais, nomes compostos (chave de fenda) e categorias misturadas (ferramentas, livros, gadgets).
Sem um seed deliberado, você só valida o caminho feliz — e o índice “funciona” sem revelar lacunas de tokenização.
Conteúdo
Schema da tabela products
Preço em centavos evita REAL e arredondamento flutuante. tags fica como texto (lista separada por espaço ou vírgula) para entrar no índice FTS junto com nome e descrição.
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT NOT NULL,
category TEXT NOT NULL,
tags TEXT NOT NULL DEFAULT '',
price_cents INTEGER NOT NULL CHECK (price_cents >= 0)
);
CREATE INDEX IF NOT EXISTS idx_products_category ON products(category);
Campos que entrarão no FTS5 (próxima aula): name, description, category, tags. O preço permanece só na tabela relacional — útil para filtros pós-MATCH, não para tokenização.
Seed: produtos fictícios brasileiros
Nomes e descrições originais para o laboratório (não copie de demos externas). Diversifique categorias e ortografia:
INSERT INTO products (name, description, category, tags, price_cents) VALUES
(
'Furadeira Percussiva Nordkraft 650W',
'Furadeira com percussão para alvenaria e madeira. Inclui maleta e jogo de brocas de 3 a 10 mm.',
'ferramentas',
'furadeira percussao broca obra',
28990
),
(
'Chave de Fenda Isolada VoltSafe 1000V',
'Chave de fenda com cabo isolado para trabalho elétrico até 1000 V. Ponta magnética.',
'ferramentas',
'chave fenda isolada eletrica',
4590
),
(
'Serra Circular Compacta SerraMundi 1400W',
'Serra circular portátil com guia paralela e disco de 7 1/4 polegadas para cortes retos em madeira.',
'ferramentas',
'serra circular madeira corte',
51990
),
(
'Alicate Universal GripMax Pro',
'Alicate universal com cabo emborrachado e corte lateral. Ideal para instalação elétrica residencial.',
'ferramentas',
'alicate universal eletrica',
3290
),
(
'Nível a Laser LinhaCruz LX-2',
'Nível a laser com projeção de cruz em 360 graus. Autonivelamento e suporte magnético.',
'ferramentas',
'nivel laser obra medicao',
18990
),
(
'Livro: Algoritmos na Prática com Grafos',
'Guia intermediário de grafos, caminhos mínimos e aplicações em roteamento. Exemplos em pseudocódigo.',
'livros',
'algoritmos grafos programacao',
8990
),
(
'Livro: SQL Moderno para Relatórios',
'Consultas analíticas, window functions e boas práticas de modelagem para dashboards.',
'livros',
'sql analytics relatorios',
7490
),
(
'Livro: Redes Sem Fio Explicadas',
'Introdução a Wi-Fi, interferência e planejamento de cobertura em ambientes urbanos.',
'livros',
'redes wifi wireless',
6790
),
(
'Livro: Design de APIs REST Estáveis',
'Versionamento, idempotência e contratos JSON para times que evoluem microsserviços.',
'livros',
'api rest design backend',
8190
),
(
'Fone Bluetooth Auricular Névoa SoundPod',
'Fones intra-auriculares com cancelamento passivo e até 28 horas de bateria com case.',
'gadgets',
'fone bluetooth audio',
15990
),
(
'Carregador Portátil PowerFolha 20000mAh',
'Power bank com duas saídas USB-A e uma USB-C PD 18 W. Indicador LED de carga.',
'gadgets',
'carregador powerbank usb-c',
12990
),
(
'Webcam Full HD OrbitCam 1080p',
'Webcam com microfone estéreo, clip universal e correção automática de luz para videochamadas.',
'gadgets',
'webcam video reuniao',
21990
),
(
'Teclado Mecânico Compacto TeclaVento 75%',
'Teclado mecânico 75% com switches táteis, layout ABNT2 e iluminação RGB por tecla.',
'gadgets',
'teclado mecanico abnt2',
34990
),
(
'Mouse Ergonômico Vertical MãoLivre V2',
'Mouse vertical sem fio com sensor óptico de 1600 DPI e receptor USB nano.',
'gadgets',
'mouse ergonomico semfio',
18990
),
(
'Luminária de Mesa LED BrilhoCalmo',
'Luminária com temperatura de cor ajustável e braço articulado para leitura e home office.',
'gadgets',
'luminaria led escritorio',
9990
),
(
'Multímetro Digital PrecisãoAmp 600V',
'Multímetro para tensão, corrente e continuidade. Display backlight e sondas reforçadas.',
'ferramentas',
'multimetro eletrica medicao',
11290
),
(
'Livro: Observabilidade com OpenTelemetry',
'Traces, métricas e logs correlacionados em sistemas distribuídos. Casos em português.',
'livros',
'observabilidade opentelemetry tracing',
9290
),
(
'Hub USB-C MaréDock 7 em 1',
'Hub com HDMI 4K, leitor SD, duas USB-A e PD passthrough para notebooks finos.',
'gadgets',
'hub usb-c hdmi dock',
24990
);
Conte ~18 linhas: suficiente para exercitar consultas e ainda pequeno para inspecionar resultados à mão.
Critérios de qualidade do corpus para FTS
Antes de indexar, verifique:
- Plurais e variantes: há
brocas/broca,fones/fone,chavesimplícitas em descrição vs tag singular. - Acentos e diacríticos:
Névoa,Precisão,MãoLivre— o tokenizerunicode61comremove_diacriticsdeve permitir busca sem acento (nevoa,precisao). - Termos compostos:
chave de fenda,serra circular,power bank(em tags comopowerbank) — teste frase ("chave de fenda") e tokens separados. - Categorias mistas: pelo menos três famílias (ferramentas, livros, gadgets) para filtrar com
JOIN+category = ?depois doMATCH. - Ruído controlado: marcas inventadas (
Nordkraft,SerraMundi) não devem “roubar” relevância de termos genéricos; use-as em testes de prefixo (Nord*). - Tags alinhadas ao texto: tags reforçam sinônimos leves (
percussaosem ç) sem contradizer a descrição.
Validação rápida do seed
SELECT category, COUNT(*) AS n FROM products GROUP BY category;
SELECT id, name
FROM products
WHERE name LIKE '%ção%' OR description LIKE '%ção%' OR name LIKE '%ã%';
SELECT id, name FROM products WHERE description LIKE '% de %';
Espere distribuição razoável por categoria, presença de diacríticos e várias frases compostas. Se tudo for ASCII sem compostos, o lab de FTS5 fica artificialmente fácil.
Exemplos práticos
Checklist mínimo antes da próxima aula:
[ ] products criada com CHECK em price_cents
[ ] 15–20 INSERTs executados sem erro
[ ] ≥3 categorias distintas
[ ] ≥5 produtos com acento ou cedilha
[ ] ≥3 descrições com expressão composta (prep. "de"/"a")
[ ] tags preenchidas (não vazias) na maioria das linhas
Consulta de sanidade:
SELECT COUNT(*) AS total,
SUM(CASE WHEN tags = '' THEN 1 ELSE 0 END) AS sem_tags
FROM products;
Problemas e como resolver
| Problema | Causa | Mitigação |
|---|---|---|
| Seed monolítico | Só uma categoria | Redistribuir nomes e tags |
| Busca sem acento falha depois | Corpus só ASCII | Incluir nomes acentuados de propósito |
| Frase nunca casa | Só palavras soltas | Escrever descrições com compostos reais |
| Preço inconsistente | Misturar reais e centavos | Padronizar price_cents |
Resumo
O laboratório começa com products bem modelada e um seed deliberadamente diverso. Plurais, acentos e compostos não são “dados de enfeite”: são o material que prova se FTS5 e o tokenizer estão configurados corretamente. Na próxima aula, você cria a virtual table FTS5, triggers e consultas MATCH sobre esse catálogo.