Voltar aos materiais
TUTORIALCOMUNIDADEVIBE-CODINGSURREALQL

Grafos no SurrealDB: 4 aplicações para produtos brasileiros

Veja como usar relações de grafo em comunidades, educação, marketplaces e atribuição de marketing sem transformar cada conexão em uma pilha de joins.

Por Mauro Mequelussi

8_MIN
Grafos no SurrealDB: 4 aplicações para produtos brasileiros
Em resumo

Veja como usar relações de grafo em comunidades, educação, marketplaces e atribuição de marketing sem transformar cada conexão em uma pilha de joins.

Tabelas guardam coisas. Produtos reais também precisam guardar conexões: quem indicou quem, qual aluno concluiu qual aula, qual profissional atende qual região, quais pessoas pertencem a uma comunidade e como uma compra chegou até uma campanha.

Quando essas conexões respondem perguntas importantes, um grafo deixa de ser uma escolha exótica e vira uma forma direta de representar o negócio. SurrealDB permite combinar registros, documentos e relações no mesmo banco, usando arestas que também carregam dados.

O que é um grafo no banco de dados?

Um grafo é formado por nós e arestas. Nós representam entidades — pessoa, curso, produto, cidade. Arestas representam relações — matriculou-se, indicou, comprou, atende — e podem guardar propriedades como data, papel, origem e status.

No SurrealDB, a relação é criada com RELATE e percorrida com setas:

database/grafo-minimo.surqlsurql
RELATE profile:ana->enrolled_in->course:surrealdb
  SET status = 'active',
      source = 'pix',
      enrolled_at = time::now();

SELECT ->enrolled_in->course.{ title, level }
FROM profile:ana;

O curso e o perfil continuam sendo registros normais. enrolled_in é uma relação com significado e histórico próprios.

Nem toda referência precisa virar aresta.

SituaçãoModelo preferível
pedido pertence a um clientecampo record<cliente>
usuário segue outro usuáriorelação follows
artigo possui um autor principalrecord link
aluno se matricula e a matrícula tem status/datarelação enrolled_in
endereço atual de entregaobjeto ou record link
indicação precisa guardar campanha e recompensarelação referred

Use record link quando a conexão é simples e unilateral. Use relation table quando o vínculo tem propriedades, regras, unicidade, histórico ou precisa ser percorrido em várias direções.

A relação também é dado
Se você precisa responder “quando começou?”, “em qual papel?”, “por qual origem?” ou “com qual resultado?”, provavelmente a conexão merece um registro próprio.

Cenário 1: comunidade e rede de indicações

Uma comunidade brasileira pode recomendar conexões, premiar indicações e mostrar conteúdo de pessoas seguidas. O modelo base inclui perfis e duas relações.

database/community.surqlsurql
DEFINE TABLE profile SCHEMAFULL;
DEFINE FIELD name ON profile TYPE string;
DEFINE FIELD city ON profile TYPE option<string>;
DEFINE FIELD joined_at ON profile TYPE datetime DEFAULT time::now();

DEFINE TABLE follows SCHEMAFULL
  TYPE RELATION IN profile OUT profile;
DEFINE FIELD since ON follows TYPE datetime DEFAULT time::now();
DEFINE INDEX follows_unique ON follows FIELDS in, out UNIQUE;

DEFINE TABLE referred SCHEMAFULL
  TYPE RELATION IN profile OUT profile;
DEFINE FIELD campaign ON referred TYPE option<string>;
DEFINE FIELD converted_at ON referred TYPE option<datetime>;
DEFINE FIELD reward_centavos ON referred TYPE int DEFAULT 0;
DEFINE INDEX referral_unique ON referred FIELDS in, out UNIQUE;

Uma sugestão “pessoas que você talvez conheça” pode percorrer dois saltos: pessoas seguidas por quem Ana segue, excluindo a própria Ana e quem ela já segue.

O tutorial oficial de grafos sociais mostra como seguidores, comentários, clubes e rankings podem coexistir em um modelo desse tipo. A adaptação brasileira não está em traduzir nomes; está em escolher conexões que geram valor local, como indicação, região, turma, parceiro ou revendedor.

[ CONTEÚDO_INTEGRAL_DISPONÍVEL ]

Continuar: grafos para educação, marketplace e marketing

CLIQUE PARA DESBLOQUEAR A LEITURA

Construindo aplicações robustas com arquitetura de alto nível e infraestrutura otimizada na edge do Cloudflare Workers com SurrealDB.

Segurança de dados e conformidade com privacidade desde o primeiro dia de código com tratamento de estados e sessões resilientes.

Métricas de performance para monitorar a experiência do usuário e otimizar custos operacionais em produção com dashboards estruturados.

Continuação liberada

Cenário 2: educação e jornada do aluno

Em uma plataforma de cursos, uma tabela de matrículas resolve o básico. O grafo se torna mais interessante quando o produto precisa conectar pré-requisitos, trilhas, habilidades e progresso.

database/learning-graph.surqlsurql
DEFINE TABLE course SCHEMAFULL;
DEFINE FIELD title ON course TYPE string;
DEFINE FIELD level ON course TYPE string
  ASSERT $value IN ['beginner', 'intermediate', 'advanced'];

DEFINE TABLE skill SCHEMAFULL;
DEFINE FIELD name ON skill TYPE string;

DEFINE TABLE teaches SCHEMAFULL
  TYPE RELATION IN course OUT skill;
DEFINE FIELD weight ON teaches TYPE decimal
  ASSERT $value > 0dec AND $value <= 1dec;

DEFINE TABLE requires SCHEMAFULL
  TYPE RELATION IN course OUT course;
DEFINE FIELD mandatory ON requires TYPE bool DEFAULT true;

DEFINE TABLE enrolled_in SCHEMAFULL
  TYPE RELATION IN profile OUT course;
DEFINE FIELD progress ON enrolled_in TYPE decimal DEFAULT 0dec
  ASSERT $value >= 0dec AND $value <= 1dec;
DEFINE FIELD status ON enrolled_in TYPE string
  ASSERT $value IN ['active', 'completed', 'cancelled'];

Agora o produto pode perguntar: quais habilidades este curso ensina? Quais cursos exigem um curso anterior? Qual é o próximo conteúdo coerente com aquilo que o aluno concluiu?

Recomendação não precisa começar com IA. Uma travessia bem modelada costuma ser mais explicável e barata que enviar todo o catálogo para um modelo.

Cenário 3: marketplace de serviços locais

Um marketplace conecta prestadores, serviços, cidades, avaliações e disponibilidade. A pergunta de busca não é apenas “qual profissional tem esta categoria?”, mas “quem atende minha região, oferece o serviço, está disponível e possui sinais de confiança?”.

Um modelo híbrido funciona bem:

  • provider, service e city como nós;
  • offers para preço inicial, duração e modalidade;
  • serves para raio ou área atendida;
  • reviewed para nota, comentário e pedido verificado;
  • agenda como registros temporais, quando travessia de grafo não acrescentar valor.
database/marketplace.surqlsurql
DEFINE TABLE offers SCHEMAFULL
  TYPE RELATION IN provider OUT service;
DEFINE FIELD price_from_centavos ON offers TYPE int
  ASSERT $value >= 0;
DEFINE FIELD mode ON offers TYPE string
  ASSERT $value IN ['online', 'presencial', 'hibrido'];
DEFINE INDEX offer_unique ON offers FIELDS in, out UNIQUE;

DEFINE TABLE serves SCHEMAFULL
  TYPE RELATION IN provider OUT city;
DEFINE FIELD radius_km ON serves TYPE option<decimal>;

DEFINE TABLE reviewed SCHEMAFULL
  TYPE RELATION IN customer OUT provider;
DEFINE FIELD rating ON reviewed TYPE int
  ASSERT $value >= 1 AND $value <= 5;
DEFINE FIELD comment ON reviewed TYPE option<string>;
DEFINE FIELD verified_order ON reviewed TYPE record<order>;

Não guarde dinheiro em float. Centavos inteiros ou um tipo decimal cuidadosamente tratado são escolhas mais seguras. Também não deixe uma avaliação nascer apenas com IDs enviados pelo navegador: confirme que o pedido pertence ao cliente e foi concluído.

Cenário 4: atribuição de marketing sem perder a jornada

Produtos brasileiros dependem de WhatsApp, indicação, anúncios e conteúdo orgânico. Uma conversão raramente tem um único ponto de contato.

Um grafo pode ligar visitante, sessão, campanha, página, lead e compra. A relação carrega horário, canal, identificador de clique e posição na jornada. Isso permite consultar caminhos sem esmagar tudo num campo utm_source do cadastro final.

O cuidado é proporcional ao valor desses dados. Identificadores de publicidade, telefone e histórico de navegação podem se tornar dados pessoais. Defina retenção, acesso e finalidade; não colete “porque talvez um dia seja útil”.

Unicidade e idempotência pertencem às arestas

Seguir alguém duas vezes, dar dois likes iguais ou criar duas matrículas ativas pode corromper métricas e cobrar duas vezes uma automação. Use índice único nas relações em que apenas um vínculo pode existir.

Quando múltiplas relações são legítimas — várias compras do mesmo produto, por exemplo — use um ID idempotente derivado do evento ou uma chave única do provedor de pagamento. O modelo precisa distinguir repetição acidental de recorrência real.

Grafo não dispensa índice nem limite

Uma travessia elegante ainda pode ser cara. Antes de colocar uma consulta em produção:

  • limite profundidade e quantidade de resultados;
  • filtre cedo por status, tenant ou período;
  • indexe campos usados fora da travessia;
  • teste com volume parecido com o esperado;
  • observe tempo, memória e cardinalidade;
  • evite retornar subgrafos inteiros para o navegador.

Consultas “amigos de amigos de amigos” crescem rapidamente. A pergunta de produto deve determinar até onde percorrer.

Como pedir ajuda à IA para modelar um grafo

Propor grafo a partir de perguntas do produtoAgente de código

Modele em SurrealDB um marketplace brasileiro de serviços locais.

Antes do schema, responda:

  1. quais perguntas do produto realmente exigem travessia de grafo?
  2. quais conexões devem ser record links simples?
  3. quais relações carregam dados próprios?
  4. onde precisamos de unicidade e idempotência?
  5. quais dados pessoais exigem retenção e acesso restrito?

Depois entregue:

  • nós e arestas;
  • schema SCHEMAFULL;
  • três consultas críticas;
  • índices necessários;
  • cinco testes negativos;
  • riscos de performance.

Não use grafo apenas para demonstrar a tecnologia.

Esse último requisito é importante. Um grafo ruim apenas troca joins compreensíveis por setas difíceis de manter.

Perguntas frequentes sobre grafos no SurrealDB

SurrealDB é um banco de grafos?

Ele é multi-modelo e inclui recursos nativos de grafo. Isso permite combinar relações com documentos, consultas estruturadas e vetores no mesmo banco, sem limitar todo dado a uma única representação.

Toda tabela de junção deve virar RELATE?

Não. Use relation table quando o vínculo tem significado próprio ou precisa ser percorrido como parte central do domínio. Uma referência simples pode continuar como campo de record.

Grafo é mais rápido que join?

Não existe resposta universal. Desempenho depende de modelo, cardinalidade, índices, profundidade e padrão de consulta. Faça benchmark com as perguntas reais do produto.

Posso combinar grafo e busca vetorial?

Sim. A busca vetorial encontra candidatos por significado; o grafo pode filtrar ou enriquecer por relações conhecidas. Esse é um dos padrões abordados em RAG e agentes com SurrealDB.

Modele as perguntas, não o diagrama bonito

Liste primeiro as perguntas que movem o produto: quem pode acessar, o que recomendar, como a pessoa chegou, qual caminho falta concluir. Só depois escolha nós e arestas.

Se você ainda está decidindo o banco, veja SurrealDB vs Postgres. Se já escolheu, comece com uma relação que tenha valor claro, dados próprios e um teste de unicidade.

Do vibe ao produto. Com método.

Comece a construir

Quer transformar uma ideia em produto? O kit Sniper Apps reúne base, componentes e método para publicar com mais velocidade.

CONHECER_O_KIT →
Continue explorando
Ver todos os artigos →