Skip to content

Bancos de Dados para .NET Senior

📋 Visão Geral

A escolha do banco de dados é uma decisão arquitetural crítica que impacta diretamente a performance, escalabilidade e manutenibilidade da aplicação. Este guia aborda os principais tipos de bancos de dados e quando usar cada um.

🗄️ Bancos de Dados Relacionais (RDBMS)

SQL Server

O que é: Sistema de gerenciamento de banco de dados relacional da Microsoft.

Características:

  • ACID compliance
  • Transações complexas
  • Stored procedures
  • Triggers
  • Views
  • Índices clustered/non-clustered
  • Partitioning
  • Always On Availability Groups

Benefícios:

  • Integração nativa com .NET
  • Ferramentas robustas (SSMS, Profiler)
  • Suporte a JSON nativo
  • Machine Learning Services
  • PolyBase para big data

Performance:

  • Leitura: Excelente com índices adequados
  • Escrita: Boa para transações OLTP
  • Escalabilidade: Vertical (mais recursos)
  • Concorrência: Row-level locking

Casos de Uso:

  • Aplicações empresariais .NET
  • Sistemas transacionais (OLTP)
  • Data warehousing
  • Business Intelligence
  • Aplicações que precisam de transações complexas
csharp
// Exemplo: Conexão com SQL Server
public class SqlServerRepository
{
    private readonly string _connectionString;
    
    public SqlServerRepository(string connectionString)
    {
        _connectionString = connectionString;
    }
    
    public async Task<List<Order>> GetOrdersAsync()
    {
        using var connection = new SqlConnection(_connectionString);
        await connection.OpenAsync();
        
        var sql = @"
            SELECT o.OrderId, o.CustomerId, o.Total, o.Status, o.CreatedAt,
                   c.Name as CustomerName
            FROM Orders o
            INNER JOIN Customers c ON o.CustomerId = c.CustomerId
            WHERE o.Status = @Status
            ORDER BY o.CreatedAt DESC";
        
        var orders = await connection.QueryAsync<Order>(sql, new { Status = "Active" });
        return orders.ToList();
    }
    
    public async Task<Order> CreateOrderAsync(Order order)
    {
        using var connection = new SqlConnection(_connectionString);
        await connection.OpenAsync();
        
        using var transaction = connection.BeginTransaction();
        
        try
        {
            var orderId = await connection.QuerySingleAsync<Guid>(
                "INSERT INTO Orders (CustomerId, Total, Status, CreatedAt) " +
                "OUTPUT INSERTED.OrderId " +
                "VALUES (@CustomerId, @Total, @Status, @CreatedAt)",
                order, transaction);
            
            foreach (var item in order.Items)
            {
                await connection.ExecuteAsync(
                    "INSERT INTO OrderItems (OrderId, ProductId, Quantity, Price) " +
                    "VALUES (@OrderId, @ProductId, @Quantity, @Price)",
                    new { OrderId = orderId, item.ProductId, item.Quantity, item.Price },
                    transaction);
            }
            
            transaction.Commit();
            order.Id = orderId;
            return order;
        }
        catch
        {
            transaction.Rollback();
            throw;
        }
    }
}

PostgreSQL

O que é: Sistema de banco de dados relacional open-source avançado.

Características:

  • ACID compliance
  • Suporte a JSON nativo
  • Arrays nativos
  • Extensibilidade (extensions)
  • Full-text search
  • Geospatial data (PostGIS)
  • Replicação assíncrona

Benefícios:

  • Gratuito e open-source
  • Muito robusto e confiável
  • Excelente para dados complexos
  • Suporte a múltiplos tipos de dados
  • Comunidade ativa

Performance:

  • Leitura: Excelente com índices adequados
  • Escrita: Muito boa para OLTP
  • Escalabilidade: Horizontal e vertical
  • Concorrência: MVCC (Multi-Version Concurrency Control)

Casos de Uso:

  • Aplicações web modernas
  • Sistemas com dados geográficos
  • Aplicações com dados JSON
  • Data warehousing
  • Sistemas que precisam de flexibilidade
csharp
// Exemplo: Conexão com PostgreSQL
public class PostgreSqlRepository
{
    private readonly string _connectionString;
    
    public PostgreSqlRepository(string connectionString)
    {
        _connectionString = connectionString;
    }
    
    public async Task<List<Order>> GetOrdersWithJsonAsync()
    {
        using var connection = new NpgsqlConnection(_connectionString);
        await connection.OpenAsync();
        
        var sql = @"
            SELECT o.order_id, o.customer_id, o.total, o.status, o.created_at,
                   o.metadata::json as Metadata,
                   c.name as customer_name
            FROM orders o
            INNER JOIN customers c ON o.customer_id = c.customer_id
            WHERE o.status = @Status
            ORDER BY o.created_at DESC";
        
        var orders = await connection.QueryAsync<Order>(sql, new { Status = "Active" });
        return orders.ToList();
    }
    
    public async Task<Order> CreateOrderWithJsonAsync(Order order)
    {
        using var connection = new NpgsqlConnection(_connectionString);
        await connection.OpenAsync();
        
        var sql = @"
            INSERT INTO orders (customer_id, total, status, created_at, metadata)
            VALUES (@CustomerId, @Total, @Status, @CreatedAt, @Metadata::json)
            RETURNING order_id";
        
        var orderId = await connection.QuerySingleAsync<Guid>(sql, new
        {
            order.CustomerId,
            order.Total,
            order.Status,
            CreatedAt = DateTime.UtcNow,
            Metadata = JsonSerializer.Serialize(order.Metadata)
        });
        
        order.Id = orderId;
        return order;
    }
}

MySQL

O que é: Sistema de banco de dados relacional open-source popular.

Características:

  • ACID compliance
  • Múltiplos storage engines (InnoDB, MyISAM)
  • Replicação master-slave
  • Partitioning
  • Full-text search
  • Triggers e stored procedures

Benefícios:

  • Muito popular e bem documentado
  • Fácil de usar e administrar
  • Boa performance para leitura
  • Suporte a múltiplas plataformas
  • Comunidade grande

Performance:

  • Leitura: Excelente (especialmente MyISAM)
  • Escrita: Boa com InnoDB
  • Escalabilidade: Vertical e horizontal
  • Concorrência: Row-level locking (InnoDB)

Casos de Uso:

  • Aplicações web
  • Sistemas de conteúdo
  • E-commerce
  • Aplicações que precisam de alta performance de leitura
  • Sistemas com orçamento limitado
csharp
// Exemplo: Conexão com MySQL
public class MySqlRepository
{
    private readonly string _connectionString;
    
    public MySqlRepository(string connectionString)
    {
        _connectionString = connectionString;
    }
    
    public async Task<List<Order>> GetOrdersAsync()
    {
        using var connection = new MySqlConnection(_connectionString);
        await connection.OpenAsync();
        
        var sql = @"
            SELECT o.order_id, o.customer_id, o.total, o.status, o.created_at,
                   c.name as customer_name
            FROM orders o
            INNER JOIN customers c ON o.customer_id = c.customer_id
            WHERE o.status = @Status
            ORDER BY o.created_at DESC";
        
        var orders = await connection.QueryAsync<Order>(sql, new { Status = "Active" });
        return orders.ToList();
    }
}

Oracle Database

O que é: Sistema de banco de dados relacional enterprise da Oracle.

Características:

  • ACID compliance
  • RAC (Real Application Clusters)
  • Data Guard
  • Partitioning avançado
  • Materialized views
  • PL/SQL
  • Flashback technology

Benefícios:

  • Muito robusto e confiável
  • Excelente para aplicações enterprise
  • Recursos avançados de segurança
  • Suporte 24/7
  • Ferramentas completas

Performance:

  • Leitura: Excelente com otimizações
  • Escrita: Muito boa
  • Escalabilidade: Horizontal e vertical
  • Concorrência: Row-level locking

Casos de Uso:

  • Aplicações enterprise
  • Sistemas financeiros
  • Data warehousing
  • Aplicações que precisam de alta disponibilidade
  • Sistemas com requisitos de compliance rigorosos

📊 Bancos de Dados Não Relacionais (NoSQL)

MongoDB (Document Store)

O que é: Banco de dados de documentos orientado a documentos.

Características:

  • Schema flexível
  • Suporte nativo a JSON
  • Índices em arrays e subdocumentos
  • Aggregation pipeline
  • Sharding horizontal
  • Replicação

Benefícios:

  • Flexibilidade de schema
  • Fácil de usar com JSON
  • Escalabilidade horizontal
  • Performance para leitura
  • Suporte a geospatial queries

Performance:

  • Leitura: Excelente com índices adequados
  • Escrita: Boa
  • Escalabilidade: Horizontal (sharding)
  • Concorrência: Document-level locking

Casos de Uso:

  • Aplicações com dados semi-estruturados
  • Sistemas de conteúdo
  • Logs e analytics
  • Aplicações que precisam de flexibilidade de schema
  • Sistemas com dados JSON complexos
csharp
// Exemplo: Conexão com MongoDB
public class MongoDbRepository
{
    private readonly IMongoCollection<Order> _ordersCollection;
    
    public MongoDbRepository(IMongoDatabase database)
    {
        _ordersCollection = database.GetCollection<Order>("orders");
    }
    
    public async Task<List<Order>> GetOrdersAsync()
    {
        var filter = Builders<Order>.Filter.Eq(o => o.Status, "Active");
        var sort = Builders<Order>.Sort.Descending(o => o.CreatedAt);
        
        return await _ordersCollection
            .Find(filter)
            .Sort(sort)
            .ToListAsync();
    }
    
    public async Task<Order> CreateOrderAsync(Order order)
    {
        order.Id = Guid.NewGuid().ToString();
        order.CreatedAt = DateTime.UtcNow;
        
        await _ordersCollection.InsertOneAsync(order);
        return order;
    }
    
    public async Task<List<Order>> GetOrdersByCustomerAsync(string customerId)
    {
        var filter = Builders<Order>.Filter.Eq(o => o.CustomerId, customerId);
        
        return await _ordersCollection
            .Find(filter)
            .SortByDescending(o => o.CreatedAt)
            .ToListAsync();
    }
    
    public async Task UpdateOrderStatusAsync(string orderId, string status)
    {
        var filter = Builders<Order>.Filter.Eq(o => o.Id, orderId);
        var update = Builders<Order>.Update
            .Set(o => o.Status, status)
            .Set(o => o.UpdatedAt, DateTime.UtcNow);
        
        await _ordersCollection.UpdateOneAsync(filter, update);
    }
}

Redis (Key-Value Store)

O que é: Banco de dados em memória de chave-valor.

Características:

  • Armazenamento em memória
  • Múltiplos tipos de dados
  • Pub/Sub messaging
  • Lua scripting
  • Persistência opcional
  • Cluster mode

Benefícios:

  • Performance extremamente alta
  • Baixa latência
  • Múltiplos tipos de dados
  • Funcionalidades avançadas (pub/sub, Lua)
  • Fácil de usar

Performance:

  • Leitura: Extremamente rápida (memória)
  • Escrita: Muito rápida
  • Escalabilidade: Horizontal (cluster)
  • Concorrência: Single-threaded (por shard)

Casos de Uso:

  • Cache de aplicação
  • Session storage
  • Rate limiting
  • Real-time analytics
  • Message queues
  • Leaderboards
csharp
// Exemplo: Cache com Redis
public class RedisCacheService
{
    private readonly ConnectionMultiplexer _redis;
    private readonly IDatabase _database;
    
    public RedisCacheService(string connectionString)
    {
        _redis = ConnectionMultiplexer.Connect(connectionString);
        _database = _redis.GetDatabase();
    }
    
    public async Task<T> GetAsync<T>(string key)
    {
        var value = await _database.StringGetAsync(key);
        
        if (value.IsNull)
            return default(T);
            
        return JsonSerializer.Deserialize<T>(value);
    }
    
    public async Task SetAsync<T>(string key, T value, TimeSpan? expiry = null)
    {
        var serializedValue = JsonSerializer.Serialize(value);
        await _database.StringSetAsync(key, serializedValue, expiry);
    }
    
    public async Task<bool> DeleteAsync(string key)
    {
        return await _database.KeyDeleteAsync(key);
    }
    
    public async Task IncrementAsync(string key, long value = 1)
    {
        await _database.StringIncrementAsync(key, value);
    }
    
    public async Task AddToSetAsync(string key, string value)
    {
        await _database.SetAddAsync(key, value);
    }
    
    public async Task<List<string>> GetSetMembersAsync(string key)
    {
        var values = await _database.SetMembersAsync(key);
        return values.Select(v => v.ToString()).ToList();
    }
}

Cassandra (Wide Column Store)

O que é: Banco de dados distribuído de colunas largas.

Características:

  • Distribuído por design
  • Linear scalability
  • High availability
  • Tunable consistency
  • CQL (Cassandra Query Language)
  • Materialized views

Benefícios:

  • Escalabilidade linear
  • Alta disponibilidade
  • Performance para escrita
  • Sem single point of failure
  • Flexibilidade de schema

Performance:

  • Leitura: Boa para queries por partition key
  • Escrita: Excelente
  • Escalabilidade: Horizontal (linear)
  • Concorrência: Row-level

Casos de Uso:

  • Time-series data
  • IoT applications
  • Analytics
  • Sistemas que precisam de alta disponibilidade
  • Aplicações com muitas escritas
csharp
// Exemplo: Conexão com Cassandra
public class CassandraRepository
{
    private readonly ISession _session;
    
    public CassandraRepository(ISession session)
    {
        _session = session;
    }
    
    public async Task<List<Order>> GetOrdersByCustomerAsync(string customerId)
    {
        var statement = _session.Prepare(
            "SELECT order_id, customer_id, total, status, created_at " +
            "FROM orders_by_customer " +
            "WHERE customer_id = ? " +
            "ORDER BY created_at DESC");
        
        var boundStatement = statement.Bind(customerId);
        var result = await _session.ExecuteAsync(boundStatement);
        
        return result.Select(row => new Order
        {
            Id = row.GetValue<string>("order_id"),
            CustomerId = row.GetValue<string>("customer_id"),
            Total = row.GetValue<decimal>("total"),
            Status = row.GetValue<string>("status"),
            CreatedAt = row.GetValue<DateTime>("created_at")
        }).ToList();
    }
    
    public async Task CreateOrderAsync(Order order)
    {
        var statement = _session.Prepare(
            "INSERT INTO orders_by_customer (customer_id, created_at, order_id, total, status) " +
            "VALUES (?, ?, ?, ?, ?)");
        
        var boundStatement = statement.Bind(
            order.CustomerId,
            order.CreatedAt,
            order.Id,
            order.Total,
            order.Status);
        
        await _session.ExecuteAsync(boundStatement);
    }
}

Neo4j (Graph Database)

O que é: Banco de dados de grafos nativo.

Características:

  • Modelagem de relacionamentos
  • Cypher query language
  • Graph algorithms
  • ACID compliance
  • Index-free adjacency
  • Traversal otimizado

Benefícios:

  • Excelente para relacionamentos complexos
  • Queries de relacionamento muito rápidas
  • Modelagem natural para redes sociais
  • Cypher é intuitivo
  • Performance para traversals

Performance:

  • Leitura: Excelente para relacionamentos
  • Escrita: Boa
  • Escalabilidade: Vertical
  • Concorrência: Row-level

Casos de Uso:

  • Redes sociais
  • Sistemas de recomendação
  • Fraud detection
  • Knowledge graphs
  • Supply chain management
  • Análise de relacionamentos
csharp
// Exemplo: Conexão com Neo4j
public class Neo4jRepository
{
    private readonly IDriver _driver;
    
    public Neo4jRepository(IDriver driver)
    {
        _driver = driver;
    }
    
    public async Task<List<Customer>> GetCustomerRecommendationsAsync(string customerId)
    {
        using var session = _driver.AsyncSession();
        
        var query = @"
            MATCH (c:Customer {id: $customerId})-[:PURCHASED]->(p:Product)
            MATCH (other:Customer)-[:PURCHASED]->(p)
            WHERE other.id <> $customerId
            WITH other, count(p) as commonProducts
            ORDER BY commonProducts DESC
            LIMIT 10
            RETURN other.id as id, other.name as name, commonProducts";
        
        var result = await session.RunAsync(query, new { customerId });
        var customers = new List<Customer>();
        
        await foreach (var record in result)
        {
            customers.Add(new Customer
            {
                Id = record["id"].As<string>(),
                Name = record["name"].As<string>()
            });
        }
        
        return customers;
    }
    
    public async Task CreateCustomerAsync(Customer customer)
    {
        using var session = _driver.AsyncSession();
        
        var query = "CREATE (c:Customer {id: $id, name: $name, email: $email})";
        
        await session.RunAsync(query, new
        {
            customer.Id,
            customer.Name,
            customer.Email
        });
    }
    
    public async Task CreatePurchaseRelationshipAsync(string customerId, string productId)
    {
        using var session = _driver.AsyncSession();
        
        var query = @"
            MATCH (c:Customer {id: $customerId})
            MATCH (p:Product {id: $productId})
            CREATE (c)-[:PURCHASED {date: datetime()}]->(p)";
        
        await session.RunAsync(query, new { customerId, productId });
    }
}

📈 Comparação de Performance

Banco de DadosTipoLeituraEscritaEscalabilidadeComplexidade
SQL ServerRelacionalExcelenteBoaVerticalMédia
PostgreSQLRelacionalExcelenteMuito BoaHorizontal/VerticalMédia
MySQLRelacionalExcelenteBoaHorizontal/VerticalBaixa
OracleRelacionalExcelenteMuito BoaHorizontal/VerticalAlta
MongoDBDocumentExcelenteBoaHorizontalBaixa
RedisKey-ValueExtremamente RápidaMuito RápidaHorizontalBaixa
CassandraWide ColumnBoaExcelenteHorizontalMédia
Neo4jGraphExcelente (relacionamentos)BoaVerticalMédia

🎯 Critérios de Seleção

Quando usar Relacional:

  • Dados estruturados e consistentes
  • Transações ACID complexas
  • Relacionamentos entre entidades
  • Relatórios e analytics complexos
  • Integridade referencial importante
  • Aplicações enterprise

Quando usar NoSQL:

  • Dados semi-estruturados ou não estruturados
  • Escalabilidade horizontal necessária
  • Flexibilidade de schema
  • Performance de leitura crítica
  • Dados em tempo real
  • Aplicações modernas e ágeis

Quando usar Document Store (MongoDB):

  • Dados JSON complexos
  • Schema flexível
  • Aplicações web modernas
  • Content management
  • Logs e analytics

Quando usar Key-Value (Redis):

  • Cache de aplicação
  • Session storage
  • Rate limiting
  • Real-time features
  • Message queues

Quando usar Wide Column (Cassandra):

  • Time-series data
  • IoT applications
  • Alta disponibilidade necessária
  • Muitas escritas
  • Escalabilidade linear

Quando usar Graph (Neo4j):

  • Relacionamentos complexos
  • Redes sociais
  • Sistemas de recomendação
  • Fraud detection
  • Knowledge graphs

⚠️ Considerações Importantes

Segurança

  • Encryption: Dados em trânsito e em repouso
  • Authentication: Controle de acesso
  • Authorization: Permissões granulares
  • Audit: Logs de acesso e mudanças

Backup e Recovery

  • Backup automático: Configurar backups regulares
  • Point-in-time recovery: Recuperação até momento específico
  • Disaster recovery: Estratégias de DR
  • Testing: Testar restauração regularmente

Monitoramento

  • Performance metrics: Query performance
  • Resource utilization: CPU, memória, disco
  • Connection pooling: Gerenciar conexões
  • Slow queries: Identificar e otimizar

Manutenção

  • Indexing strategy: Índices adequados
  • Query optimization: Otimizar queries
  • Partitioning: Para grandes volumes
  • Archiving: Estratégias de arquivamento

📚 Recursos Adicionais

Ferramentas

  • SQL Server: SSMS, Profiler, Data Tools
  • PostgreSQL: pgAdmin, DBeaver
  • MySQL: MySQL Workbench, phpMyAdmin
  • MongoDB: MongoDB Compass, Studio 3T
  • Redis: RedisInsight, Redis Commander
  • Neo4j: Neo4j Browser, Bloom

ORM e Drivers

  • Entity Framework: Para SQL Server
  • Npgsql: Para PostgreSQL
  • MySqlConnector: Para MySQL
  • MongoDB.Driver: Para MongoDB
  • StackExchange.Redis: Para Redis
  • Neo4j.Driver: Para Neo4j

Livros Recomendados

  • "Designing Data-Intensive Applications"
  • "Database Design for Mere Mortals"
  • "MongoDB: The Definitive Guide"
  • "Redis in Action"
  • "Graph Databases"