Comparação Entre MySQL e MongoDB: Quando Usar Cada um e Exemplos de Aplicações

novembro 19, 2024 | por dbsnoop

Comparação Entre MySQL e MongoDB: Quando Usar Cada um e Exemplos de Aplicações

Na batalha entre MySQL e MongoDB, não há um vencedor universal. Cada um é como um herói com poderes únicos, prontos para salvar o dia dependendo do contexto. Neste artigo, vamos explorar as diferenças, exemplos práticos de aplicações, e responder as perguntas mais importantes para ajudá-lo a escolher a melhor ferramenta.

Para que serve cada um?

  • MySQL: É um banco de dados relacional que utiliza tabelas com linhas e colunas. Ele é ideal para armazenar dados altamente estruturados, como cadastros, transações financeiras ou sistemas ERP.
  • MongoDB: É um banco de dados NoSQL baseado em documentos. Ele é ideal para armazenar dados não estruturados ou semiestruturados, como logs, catálogos de produtos ou conteúdo de redes sociais.

Exemplos:

  • Use MySQL quando precisar de relações rígidas e integridade referencial (ex.: e-commerce com histórico de pedidos e estoques).
  • Use MongoDB quando precisar de flexibilidade para alterar o esquema dinamicamente (ex.: aplicativos que armazenam dados heterogêneos, como perfis de usuários com campos personalizados).

O que armazenar?

Tipo de DadoMySQLMongoDB
Dados tabulares estruturadosSimNão recomendado
Dados flexíveis e variadosDifícil de adaptarSim
Dados relacionais com dependênciasSimNão ideal
Dados sem estrutura fixaNão recomendadoSim

Exemplos de Aplicações

• MySQL:

• Sistemas financeiros.

• CRMs com tabelas rígidas.

• Aplicativos que exigem integridade transacional (ACID).

• MongoDB:

• Aplicativos de IoT armazenando dados de sensores.

• Redes sociais que lidam com postagens de formatos variados.

• Aplicativos de análise de logs.

• Usando Ambos:

• Um e-commerce pode usar MySQL para gerenciar transações e MongoDB para armazenar comentários dos usuários, que têm estrutura menos rígida.

Escalabilidade

• MongoDB: Mais escalável horizontalmente, utilizando sharding para distribuir os dados.

• MySQL: Escalabilidade vertical limitada, embora réplicas e partições ajudem.

Vencedor: MongoDB.

Segurança

• MySQL: Oferece mecanismos robustos de autenticação e controle de acesso, além de criptografia.

• MongoDB: Também possui segurança forte, mas historicamente sofreu com problemas de configurações padrão inseguras.

Vencedor: Empate técnico, mas MySQL leva vantagem por histórico.

Curva de Aprendizado

• MySQL: Mais fácil para quem já conhece SQL e trabalha com bancos relacionais.

• MongoDB: Exige aprender a lidar com JSON-like e conceitos de bancos NoSQL.

Vencedor: MySQL.

Disponibilidade de Mão de Obra

MySQL tem uma base maior de profissionais treinados, mas o mercado de MongoDB está crescendo rapidamente.

Vencedor: MySQL (por enquanto).

Gerenciabilidade

• MySQL: Ferramentas maduras como MySQL Workbench.

• MongoDB: MongoDB Compass e Atlas, excelentes, mas relativamente novos.

Vencedor: MySQL.

Debug e Resolução de Problemas

MySQL: Logs detalhados de erros e ferramentas de depuração ajudam a resolver problemas mais rapidamente.

MongoDB: Flexível, mas pode ser mais difícil de rastrear erros em estruturas dinâmicas.

Vencedor: MySQL.

SLA Médio e MTBF

• MySQL: SLA médio acima de 99.9999% com instâncias bem configuradas. MTBF (tempo médio entre falhas) alto, devido à maturidade.

• MongoDB: Também pode atingir SLA de 99.99%, mas é mais suscetível a problemas se mal configurado.

Consultas Práticas – Vamos para o código que é o que você quer ver, certo ?

Modelo de Dados

• Produtos:

• ID, Nome, Categoria, Preço, Estoque.

No MySQL

-- Criar a tabela
CREATE TABLE produtos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nome VARCHAR(100),
  categoria VARCHAR(50),
  preco DECIMAL(10, 2),
  estoque INT
);
-- Inserir dados
INSERT INTO produtos (nome, categoria, preco, estoque)
VALUES ('Camiseta', 'Roupas', 29.90, 100);
-- Consultas
-- 1. Produtos em estoque
SELECT * FROM produtos WHERE estoque > 0;
-- 2. Produtos por categoria e preço
SELECT * FROM produtos WHERE categoria = 'Roupas' AND preco < 50;

No MongoDB

// Inserir dados
db.produtos.insertOne({
  nome: "Camiseta",
  categoria: "Roupas",
  preco: 29.90,
  estoque: 100
});
// Consultas
// 1. Produtos em estoque
db.produtos.find({ estoque: { $gt: 0 } });
// 2. Produtos por categoria e preço
db.produtos.find({ categoria: "Roupas", preco: { $lt: 50 } });

Consultas Complexas

Cenário: Sistema de Vendas

Vamos usar as tabelas clientes, pedidos e produtos para exemplificar. Queremos responder à seguinte pergunta:

“Quais clientes realizaram pedidos com valor total acima de R$1.000,00 nos últimos 6 meses, listando também os produtos comprados?”

Estrutura das Tabelas:

• clientes: id_cliente, nome.

• pedidos: id_pedido, id_cliente, data_pedido.

• produtos: id_produto, nome_produto, preco.

• pedido_produto (relação): id_pedido, id_produto, quantidade.

Consulta SQL:

SELECT 
    c.nome AS nome_cliente,
    SUM(ped_prod.quantidade * prod.preco) AS valor_total,
    GROUP_CONCAT(prod.nome_produto) AS produtos_comprados
FROM 
    clientes c
LEFT JOIN 
    pedidos p ON c.id_cliente = p.id_cliente
INNER JOIN 
    pedido_produto ped_prod ON p.id_pedido = ped_prod.id_pedido
INNER JOIN 
    produtos prod ON ped_prod.id_produto = prod.id_produto
WHERE 
    p.data_pedido >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY 
    c.id_cliente
HAVING 
    valor_total > 1000
ORDER BY 
    valor_total DESC;

Resultado esperado:

Nome ClienteValor TotalProdutos Comprados
João da Silva1.500,00Notebook, Mouse, Teclado
Maria Oliveira1.200,00Smartphone, Fone Bluetooth

Explicação:

1. LEFT JOIN entre clientes e pedidos: Garante que clientes sem pedidos ainda apareçam (se necessário).

2. INNER JOIN com pedido_produto e produtos: Conecta pedidos aos produtos comprados.

3. WHERE: Filtra pedidos realizados nos últimos 6 meses.

4. GROUP BY: Agrupa os dados por cliente.

5. HAVING: Mostra apenas clientes com valor total de pedidos acima de R$ 1.000,00.

6. GROUP_CONCAT: Combina os nomes dos produtos comprados em um campo único.

No MongoDB

// Clientes:
{
    "_id": ObjectId("1"),
    "nome": "João da Silva"
}
// Pedidos:
{
    "_id": ObjectId("101"),
    "id_cliente": ObjectId("1"),
    "data_pedido": ISODate("2024-06-15"),
    "itens": [
        { "id_produto": ObjectId("1001"), "quantidade": 1 },
        { "id_produto": ObjectId("1002"), "quantidade": 2 }
    ]
}


// Produtos:


{
    "_id": ObjectId("1001"),
    "nome_produto": "Notebook",
    "preco": 1500.00
}

Consulta MongoDB:

db.pedidos.aggregate([
    {
        $match: {
            data_pedido: { $gte: new Date(new Date().setMonth(new Date().getMonth() - 6)) }
        }
    },
    {
        $lookup: {
            from: "clientes",
            localField: "id_cliente",
            foreignField: "_id",
            as: "cliente"
        }
    },
    {
        $unwind: "$cliente"
    },
    {
        $lookup: {
            from: "produtos",
            localField: "itens.id_produto",
            foreignField: "_id",
            as: "produtos"
        }
    },
    {
        $addFields: {
            valor_total: {
                $sum: {
                    $map: {
                        input: "$itens",
                        as: "item",
                        in: {
                            $multiply: [
                                "$$item.quantidade",
                                { $arrayElemAt: ["$produtos.preco", { $indexOfArray: ["$produtos._id", "$$item.id_produto"] }] }
                            ]
                        }
                    }
                }
            }
        }
    },
    {
        $match: {
            valor_total: { $gt: 1000 }
        }
    },
    {
        $project: {
            nome_cliente: "$cliente.nome",
            produtos_comprados: "$produtos.nome_produto",
            valor_total: 1
        }
    }
]);

Explicação:

1. $match: Filtra pedidos realizados nos últimos 6 meses.

2. $lookup: Faz o “join” entre pedidos e clientes, e depois entre pedidos e produtos.

3. $unwind: Separa os arrays resultantes para lidar com cada cliente/produto individualmente.

4. $addFields: Calcula o valor total do pedido multiplicando a quantidade pelo preço do produto.

5. $project: Seleciona apenas os campos desejados no resultado.

Resultado esperado:

[
    {
        "nome_cliente": "João da Silva",
        "valor_total": 1500,
        "produtos_comprados": ["Notebook", "Mouse", "Teclado"]
    },
    {
        "nome_cliente": "Maria Oliveira",
        "valor_total": 1200,
        "produtos_comprados": ["Smartphone", "Fone Bluetooth"]
    }
]

Qual o melhor para Consultas Complexas?

• MySQL: Mais intuitivo para quem já conhece SQL, mas pode se tornar lento em conjuntos massivos.

• MongoDB: Flexível, porém exige mais trabalho para lidar com relacionamentos complexos.

Escolha com base no tipo de aplicação e equipe disponível. Com ambos, você pode construir soluções poderosas e eficientes!

Qual escolher para construir uma nova aplicação?

• Use MySQL se precisa de consistência e estrutura, aprendizado rápido, e boa disponibilidade de mão de obra

• Use MongoDB se precisa de flexibilidade e escalabilidade horizontal.

• Use ambos quando o problema for híbrido.

Seja como Jedi ou Vingador, a escolha do banco de dados certo pode transformar seu sistema em uma verdadeira obra-prima.

Não se esqueça de dar uma olhada no nosso SaaS de monitoramento e observabilidade de banco de dados, o Flightdeck:

Agende uma demonstração aqui

Saiba mais sobre o Flightdeck!

mongodb try dbsnoop Flightdeck
Compartilhar:

Leia mais