Skip to main content
Esta seção detalha a estrutura técnica do banco de dados PostgreSQL 18 do Synapside, incluindo tabelas principais, campos, tipos de dados e índices de performance.

Tabela Principal: events

A tabela events é o coração do sistema de rastreamento do Synapside. Cada evento coletado é armazenado como uma linha nesta tabela.

Estrutura da Tabela

CREATE TABLE events (
  event_uuid UUID PRIMARY KEY,
  user_uuid UUID NOT NULL,
  event_type VARCHAR(50) NOT NULL,
  event_ts TIMESTAMP WITH TIME ZONE NOT NULL,
  recorded_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  data JSONB,
  session_uuid UUID,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Campos Principais

CampoTipoDescrição
event_uuidUUIDIdentificador único do evento (chave primária)
user_uuidUUIDIdentificador único do usuário que gerou o evento
event_typeVARCHAR(50)Tipo do evento (pageview, click, form_submit, session_start, ou customizado)
event_tsTIMESTAMP WITH TIME ZONEData e hora em que o evento ocorreu (com timezone)
recorded_atTIMESTAMP WITH TIME ZONEData e hora em que o evento foi registrado no banco
dataJSONBCampo flexível contendo dados específicos do evento (estrutura varia por tipo)
session_uuidUUIDIdentificador da sessão do usuário
created_atTIMESTAMP WITH TIME ZONETimestamp de criação do registro

Tipos de Dados

  • UUID: Identificador único universal de 128 bits, ideal para distribuição e evitar colisões
  • VARCHAR(50): String de tamanho variável para tipos de eventos
  • TIMESTAMP WITH TIME ZONE: Permite armazenar timestamps com informação de timezone, essencial para análises globais
  • JSONB: Formato JSON binário do PostgreSQL, permite armazenamento flexível e consultas eficientes

Tabela: user_identities

A tabela user_identities mapeia identidades conhecidas (email, ID de cliente, etc) ao user_uuid centralizado.

Estrutura da Tabela

CREATE TABLE user_identities (
  identity_uuid UUID PRIMARY KEY,
  user_uuid UUID NOT NULL REFERENCES events(user_uuid),
  identity_type VARCHAR(50) NOT NULL,
  identity_value VARCHAR(255) NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Campos

CampoTipoDescrição
identity_uuidUUIDIdentificador único da identidade
user_uuidUUIDReferência ao usuário (chave estrangeira)
identity_typeVARCHAR(50)Tipo de identidade (email, customer_id, phone, etc)
identity_valueVARCHAR(255)O valor da identidade
created_atTIMESTAMP WITH TIME ZONEQuando foi criado
updated_atTIMESTAMP WITH TIME ZONEQuando foi atualizado

Campo JSONB: Estrutura de Dados Dinâmicos

O campo data em cada evento é um JSONB que permite estrutura flexível. Diferentes tipos de eventos têm diferentes estruturas.

Pageview Events

{
  "path": "/produtos",
  "referer": "https://google.com",
  "utm_source": "google",
  "utm_medium": "organic",
  "utm_campaign": "busca-natural",
  "title": "Página de Produtos",
  "screen_resolution": "1920x1080"
}

Session Start Events

{
  "device": "mobile",
  "device_type": "iphone",
  "os": "ios",
  "browser": "Safari",
  "referer": "https://google.com",
  "utm_source": "google",
  "session_uuid": "550e8400-e29b-41d4-a716-446655440000"
}

Click Events

{
  "target": "button",
  "text": "Comprar Agora",
  "class": "btn-primary cta-button",
  "id": "checkout-btn",
  "path": "/produtos/123"
}

Form Submit Events

{
  "form_id": "contact-form",
  "form_name": "Formulário de Contato",
  "fields": {
    "name": "true",
    "email": "true",
    "message": "true",
    "phone": "false"
  },
  "path": "/contato"
}

Índices e Performance

Para otimizar consultas frequentes, a tabela events possui os seguintes índices:
-- Índice na user_uuid para consultas por usuário
CREATE INDEX idx_events_user_uuid ON events(user_uuid);

-- Índice em event_ts para consultas por intervalo de tempo
CREATE INDEX idx_events_event_ts ON events(event_ts DESC);

-- Índice combinado para consultas de série temporal por usuário
CREATE INDEX idx_events_user_ts ON events(user_uuid, event_ts DESC);

-- Índice em event_type para filtros de tipo
CREATE INDEX idx_events_event_type ON events(event_type);

-- Índice em session_uuid para análises de sessão
CREATE INDEX idx_events_session_uuid ON events(session_uuid);

-- Índice GIN para queries eficientes no JSONB
CREATE INDEX idx_events_data_gin ON events USING GIN(data);

Estratégia de Índices

  • B-tree: Usado para colunas UUID e event_type (buscas iguais/intervalo)
  • BRIN: Para timestamp (bloco de índice comprimido, eficiente para dados ordenados)
  • GIN: Para JSONB (queries complexas no field dinâmico)

Particionamento (Recomendação para Escala)

Para enormes volumes de dados, considere particionar events por período temporal:
CREATE TABLE events_2026_q1 PARTITION OF events
  FOR VALUES FROM ('2026-01-01') TO ('2026-04-01');

CREATE TABLE events_2026_q2 PARTITION OF events
  FOR VALUES FROM ('2026-04-01') TO ('2026-07-01');
Isso melhora:
  • Performance de queries com filtro de data
  • Facilita arquivamento de dados antigos
  • Reduz tempo de VACUUM e ANALYZE

Segurança e Privacidade

Dados Sensíveis

O campo data pode conter informações sensíveis (emails em form_submit, etc). Recomendações:
  • Não logarear senhas ou tokens
  • Implementar mascaramento de dados sensíveis (PII)
  • Aplicar políticas de retenção

Exemplos de Consultas Úteis

Contar eventos por tipo (últimos 30 dias)

SELECT
  event_type,
  COUNT(*) as total
FROM events
WHERE event_ts >= NOW() - INTERVAL '30 days'
GROUP BY event_type
ORDER BY total DESC;

Usuários únicos por dia

SELECT
  DATE(event_ts) as data,
  COUNT(DISTINCT user_uuid) as usuarios_unicos
FROM events
WHERE event_ts >= NOW() - INTERVAL '7 days'
GROUP BY DATE(event_ts)
ORDER BY data DESC;

Identificar usuários por email

SELECT DISTINCT
  e.user_uuid,
  ui.identity_value as email,
  COUNT(e.event_uuid) as total_eventos
FROM events e
JOIN user_identities ui ON e.user_uuid = ui.user_uuid
WHERE ui.identity_type = 'email'
  AND ui.identity_value LIKE '%@example.com'
GROUP BY e.user_uuid, ui.identity_value
ORDER BY total_eventos DESC;