Modelagem de Dados¶
Arquitetura de Persistência (Híbrida)¶
O sistema utiliza uma arquitetura híbrida de bancos de dados, onde MongoDB é o banco principal para os dados de negócio, e MySQL é utilizado para dados transacionais críticos.

Por que MongoDB como principal? - Diferentes máquinas possuem especificações variadas - Schema flexível permite cadastro dinâmico de atributos - Dados não-estruturados são mais utilizados no sistema
Schemas MongoDB¶
Visão Geral¶
O banco de dados MongoDB armazena os documentos operacionais do sistema (fábricas, máquinas, produções e peças).
Os documentos operacionais herdam os campos de auditoria createdAt e updatedAt. Algumas coleções (máquina, produção, peça) também suportam atributos dinâmicos via campo atributosExtras.
Coleção: filial¶
Representa as unidades produtivas (galpões, plantas industriais ou unidades) vinculadas a uma empresa.
{
_id: ObjectId,
empresa_id: Number, // Referência à empresa (id do MySQL) - obrigatório
nome: String, // Nome da filial/galpão - obrigatório
tipo: String, // Enum: "GALPAO" | "PLANTA_INDUSTRIAL" | "UNIDADE"
dimensoes: {
largura: Number,
comprimento: Number,
altura: Number
},
endereco: {
logradouro: String,
numero: String,
complemento: String,
bairro: String,
cidade: String,
estado: String,
cep: String,
latitude: Number,
longitude: Number
},
layout: String, // Referência ao Digital Twin
capacidade: Number, // Capacidade de produção
createdAt: Date,
updatedAt: Date
}
Índices
| Nome | Campos | Tipo |
|---|---|---|
| idx_empresa_nome | empresa_id: 1, nome: 1 | Compound |
Coleção: maquina¶
Representa os equipamentos instalados em uma filial.
{
_id: ObjectId,
filial_id: ObjectId, // Referência à filial
nome: String, // Nome/identificação da máquina
tipo: String, // Ex: "prensa", "cnc", "robô"
coordenadas: {
x: Number,
y: Number,
z: Number
},
status: String, // Enum: "ATIVO" | "MANUTENCAO" | "INATIVO"
especificacoes: Object, // Especificações técnicas dinâmicas por tipo
manutencao: {
ultima: Date,
proxima: Date,
historico: [
{
data: Date,
tipo: String,
descricao: String
}
]
},
atributosExtras: Object, // Campos dinâmicos adicionais
createdAt: Date,
updatedAt: Date
}
Índices
| Nome | Campos | Tipo |
|---|---|---|
| idx_filial_status | filial_id: 1, status: 1 | Compound |
| idx_filial_tipo | filial_id: 1, tipo: 1 | Compound |
Coleção: producao¶
Representa as ordens de produção executadas em uma máquina de uma filial.
{
_id: ObjectId,
filial_id: ObjectId, // Referência à filial
maquina_id: ObjectId, // Referência à máquina
ordem: String, // Número da ordem de produção
dataInicio: Date,
dataFim: Date,
quantidade: Number,
status: String, // Enum: "EM_ANDAMENTO" | "CONCLUIDO" | "CANCELADO"
pecas: [
{
tipo: String,
quantidade: Number,
tempoPorUnidade: Number
}
],
atributosExtras: Object, // Campos dinâmicos adicionais
createdAt: Date,
updatedAt: Date
}
Índices
| Nome | Campos | Tipo |
|---|---|---|
| idx_filial_data | filial_id: 1, dataInicio: -1 | Compound |
| idx_maquina_status | maquina_id: 1, status: 1 | Compound |
Coleção: peca¶
Representa as peças produzidas, com rastreamento de etapas.
{
_id: ObjectId,
producao_id: ObjectId, // Referência à produção
codigo: String, // Código de rastreamento único
tipo: String,
etapas: [
{
nome: String,
maquina_id: ObjectId,
inicio: Date,
fim: Date,
status: String
}
],
localizacaoAtual: String,
atributosExtras: Object, // Campos dinâmicos adicionais
createdAt: Date,
updatedAt: Date
}
Índices
| Nome | Campos | Tipo |
|---|---|---|
| idx_codigo | codigo: 1 | Unique |
| idx_producao | producao_id: 1 | Simples |
| idx_etapas_maquina | etapas.maquina_id: 1 | Simples |
Enums Utilizados¶
| Enum | Valores |
|---|---|
| TipoFilial | GALPAO, PLANTA_INDUSTRIAL, UNIDADE |
| StatusMaquina | ATIVO, MANUTENCAO, INATIVO |
| StatusProducao | EM_ANDAMENTO, CONCLUIDO, CANCELADO |
Notas Técnicas
- empresa_id em filial é do tipo Number (referência ao id da tabela empresa no MySQL). Todos os outros relacionamentos entre documentos MongoDB usam ObjectId.
- atributosExtras existe nas coleções máquina, produção e peça como um objeto dinâmico. Ele permite persistir campos não previstos no schema original sem necessidade de migração.
- especificacoes em maquina é um campo dinâmico com semântica de domínio (especificações técnicas da máquina), separado intencionalmente de atributosExtras.
- Os campos createdAt e updatedAt são preenchidos automaticamente pelo mecanismo de auditing do Spring Data MongoDB (@EnableMongoAuditing).
Tabelas MySQL¶
Usuários¶
CREATE TABLE usuario (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
empresa_id BIGINT,
nome VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
senha_hash VARCHAR(255) NOT NULL,
ativo BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (empresa_id) REFERENCES empresa(id)
);
Auditoria/Logs de Sistema¶
CREATE TABLE logs_auditoria (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
usuario_id BIGINT,
acao VARCHAR(100) NOT NULL,
entidade VARCHAR(100) NOT NULL,
entidade_id VARCHAR(24), -- ObjectId MongoDB
detalhes JSON,
ip_address VARCHAR(45),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (usuario_id) REFERENCES usuario(id) ON DELETE SET NULL
);
Empresas¶
CREATE TABLE empresa (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
razao_social VARCHAR(255) NOT NULL,
cnpj VARCHAR(14) NOT NULL,
logradouro VARCHAR(255),
numero VARCHAR(10),
cidade VARCHAR(100),
estado CHAR(2),
cep VARCHAR(8),
email VARCHAR(255),
telefone VARCHAR(20),
configuracoes JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
)
Índices Recomendados (MongoDB)¶
// Filiais
db.filiais.createIndex({ empresa_id: 1 });
db.filiais.createIndex({ empresa_id: 1, nome: 1 });
// Máquinas
db.maquinas.createIndex({ filial_id: 1, status: 1 });
db.maquinas.createIndex({ filial_id: 1, tipo: 1 });
// Produções
db.producoes.createIndex({ filial_id: 1, data_inicio: -1 });
db.producoes.createIndex({ maquina_id: 1, status: 1 });
// Peças
db.pecas.createIndex({ codigo: 1 }, { unique: true });
db.pecas.createIndex({ producao_id: 1 });
db.pecas.createIndex({ "etapas.maquina_id": 1 });
Ações de auditoria¶
┌───────────────┬────────────────────────────────────┐
│ Ação │ Descrição │
├───────────────┼────────────────────────────────────┤
│ CRIACAO │ Novo registro criado │
├───────────────┼────────────────────────────────────┤
│ ATUALIZACAO │ Registro modificado │
├───────────────┼────────────────────────────────────┤
│ EXCLUSAO │ Registro removido │
├───────────────┼────────────────────────────────────┤
│ LOGIN │ Usuário autenticado │
├───────────────┼────────────────────────────────────┤
│ LOGOUT │ Usuário desconectado │
├───────────────┼────────────────────────────────────┤
│ ACESSO_NEGADO │ Tentativa de acesso não autorizado │
├───────────────┼────────────────────────────────────┤
│ IMPORTACAO │ Importação de dados (CSV/Excel) │
└───────────────┴────────────────────────────────────┘